nixos-config/lib/fudo/mail-container.nix
2021-11-05 07:06:08 -07:00

222 lines
5.9 KiB
Nix

{ pkgs, lib, config, ... }:
with lib;
let
hostname = config.instance.hostname;
cfg = config.fudo.mail-server;
container-maildir = "/var/lib/mail";
container-statedir = "/var/lib/mail-state";
# Don't bother with group-id, nixos doesn't seem to use it anyway
container-mail-user = "mailer";
container-mail-user-id = 542;
container-mail-group = "mailer";
build-timestamp = config.instance.build-timestamp;
build-seed = config.instance.build-seed;
site = config.instance.local-site;
domain = cfg.domain;
local-networks = config.instance.local-networks;
in rec {
config = mkIf (cfg.enableContainer) {
# Disable postfix on this host--it'll be run in the container instead
services.postfix.enable = false;
services.nginx = mkIf cfg.monitoring {
enable = true;
virtualHosts = let
proxy-headers = ''
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
'';
trusted-network-string =
optionalString ((length local-networks) > 0)
(concatStringsSep "\n"
(map (network: "allow ${network};")
local-networks)) + ''
deny all;'';
in {
"${cfg.mail-hostname}" = {
enableACME = true;
forceSSL = true;
locations."/metrics/postfix" = {
proxyPass = "http://127.0.0.1:9154/metrics";
extraConfig = ''
${proxy-headers}
${trusted-network-string}
'';
};
locations."/metrics/dovecot" = {
proxyPass = "http://127.0.0.1:9166/metrics";
extraConfig = ''
${proxy-headers}
${trusted-network-string}
'';
};
locations."/metrics/rspamd" = {
proxyPass = "http://127.0.0.1:7980/metrics";
extraConfig = ''
${proxy-headers}
${trusted-network-string}
'';
};
};
};
};
containers.mail-server = {
autoStart = true;
bindMounts = {
"${container-maildir}" = {
hostPath = cfg.mail-directory;
isReadOnly = false;
};
"${container-statedir}" = {
hostPath = cfg.state-directory;
isReadOnly = false;
};
"/run/mail/certs/postfix/cert.pem" = {
hostPath = cfg.ssl.certificate;
isReadOnly = true;
};
"/run/mail/certs/postfix/key.pem" = {
hostPath = cfg.ssl.private-key;
isReadOnly = true;
};
"/run/mail/certs/dovecot/cert.pem" = {
hostPath = cfg.ssl.certificate;
isReadOnly = true;
};
"/run/mail/certs/dovecot/key.pem" = {
hostPath = cfg.ssl.private-key;
isReadOnly = true;
};
"/run/mail/passwords/dovecot/ldap-reader.passwd" = {
hostPath = cfg.dovecot.ldap.reader-password-file;
isReadOnly = true;
};
};
config = { config, pkgs, ... }: {
imports = let
initialize-host = import ../../initialize.nix;
profile = "container";
in [
./mail.nix
(initialize-host {
inherit
lib
pkgs
build-timestamp
site
domain
profile;
hostname = "mail-container";
})
];
instance.build-seed = build-seed;
environment.etc = {
"mail-server/postfix/cert.pem" = {
source = "/run/mail/certs/postfix/cert.pem";
user = config.services.postfix.user;
mode = "0444";
};
"mail-server/postfix/key.pem" = {
source = "/run/mail/certs/postfix/key.pem";
user = config.services.postfix.user;
mode = "0400";
};
"mail-server/dovecot/cert.pem" = {
source = "/run/mail/certs/dovecot/cert.pem";
user = config.services.dovecot2.user;
mode = "0444";
};
"mail-server/dovecot/key.pem" = {
source = "/run/mail/certs/dovecot/key.pem";
user = config.services.dovecot2.user;
mode = "0400";
};
## The pre-script runs as root anyway...
# "mail-server/dovecot/ldap-reader.passwd" = {
# source = "/run/mail/passwords/dovecot/ldap-reader.passwd";
# user = config.services.dovecot2.user;
# mode = "0400";
# };
};
fudo = {
mail-server = {
enable = true;
mail-hostname = cfg.mail-hostname;
domain = cfg.domain;
debug = cfg.debug;
monitoring = cfg.monitoring;
state-directory = container-statedir;
mail-directory = container-maildir;
postfix = {
ssl-certificate = "/etc/mail-server/postfix/cert.pem";
ssl-private-key = "/etc/mail-server/postfix/key.pem";
};
dovecot = {
ssl-certificate = "/etc/mail-server/dovecot/cert.pem";
ssl-private-key = "/etc/mail-server/dovecot/key.pem";
ldap = {
server-urls = cfg.dovecot.ldap.server-urls;
reader-dn = cfg.dovecot.ldap.reader-dn;
reader-password-file = "/run/mail/passwords/dovecot/ldap-reader.passwd";
};
};
local-domains = cfg.local-domains;
alias-users = cfg.alias-users;
user-aliases = cfg.user-aliases;
sender-blacklist = cfg.sender-blacklist;
recipient-blacklist = cfg.recipient-blacklist;
trusted-networks = cfg.trusted-networks;
mail-user = container-mail-user;
mail-user-id = container-mail-user-id;
mail-group = container-mail-group;
clamav.enable = cfg.clamav.enable;
dkim.signing = cfg.dkim.signing;
};
};
};
};
};
}