infra/nix/os/containers/mailserver.nix
Stefan Junker 1533077234 sj-srv1,containers: debug and streamline networking config; update and track forgejo here
after an update to nixpkgs on sj-srv1 the networking for the `webserver`
container wasn't working. this caused me to debug the situation and
changing lots of things around. the culprit was most likely some impure
state file on the server that caused the `ve-webserver` interface not to
persist its IP. after renaming the webserver container the problem went
away.

i reverted all the IP changes and am keeping the other changes as opporunistic
improvements
2024-07-26 18:02:52 +02:00

231 lines
6.3 KiB
Nix

{
specialArgs,
hostAddress,
localAddress,
imapsPort ? 993,
sievePort ? 4190,
autoStart ? false,
}: {
inherit specialArgs;
config = {
pkgs,
config,
lib,
repoFlake,
...
}: {
system.stateVersion = "22.05"; # Did you read the comment?
imports = [
../profiles/containers/configuration.nix
repoFlake.inputs.sops-nix.nixosModules.sops
../profiles/common/user.nix
];
networking.firewall.allowedTCPPorts = [
imapsPort
sievePort
];
# FIXME: find out how to use the `defaultSopsFile` so i don't have to specify each secret separately
# sops.defaultSopsFile = ./mailserver_secrets.yaml;
sops.age.sshKeyPaths = ["/etc/ssh/ssh_host_ed25519_key"];
sops.secrets.email_mailStefanjunkerDe = {
sopsFile = ./mailserver_secrets.yaml;
owner = config.users.users.steveej.name;
};
sops.secrets.email_mailStefanjunkerDeHetzner = {
sopsFile = ./mailserver_secrets.yaml;
owner = config.users.users.steveej.name;
};
sops.secrets.email_schtifATwebDe = {
sopsFile = ./mailserver_secrets.yaml;
owner = config.users.users.steveej.name;
};
sops.secrets.email_dovecot_steveej = {
sopsFile = ./mailserver_secrets.yaml;
owner = config.users.users.dovecot2.name;
};
# TODO: switch to something other than ddclient as it's no longer maintained
# TODO: switch to a let's encrypt certificate
sops.secrets.dovecotSslServerCert = {
sopsFile = ./mailserver_secrets.yaml;
owner = config.users.users.dovecot2.name;
};
sops.secrets.dovecotSslServerKey = {
sopsFile = ./mailserver_secrets.yaml;
owner = config.users.users.dovecot2.name;
};
services.dovecot2 = {
enable = true;
modules = [pkgs.dovecot_pigeonhole];
protocols = ["sieve"];
enableImap = true;
enableLmtp = true;
enablePAM = true;
showPAMFailure = true;
mailLocation = "maildir:~/.maildir";
sslServerCert = config.sops.secrets.dovecotSslServerCert.path;
sslServerKey = config.sops.secrets.dovecotSslServerKey.path;
#configFile = "/etc/dovecot/dovecot2_manual.conf";
extraConfig = ''
auth_mechanisms = cram-md5 digest-md5
auth_verbose = yes
passdb {
driver = passwd-file
args = scheme=CRYPT username_format=%u /etc/dovecot/users
}
protocol lda {
postmaster_address = "mail@stefanjunker.de"
mail_plugins = $mail_plugins sieve
}
protocol imap {
mail_max_userip_connections = 64
}
'';
};
environment.etc."dovecot/users".source = config.sops.secrets.email_dovecot_steveej.path;
systemd.services.steveej-getmail-stefanjunker = {
enable = true;
wantedBy = ["multi-user.target"];
serviceConfig.User = "steveej";
serviceConfig.Group = "dovecot2";
serviceConfig.RestartSec = 600;
serviceConfig.Restart = "always";
description = "Getmail service";
path = [pkgs.getmail6];
script = let
rc = pkgs.writeText "mailATstefanjunker.de.getmail.rc" ''
[options]
verbose = 1
read_all = 0
delete_after = 30
[retriever]
type = SimpleIMAPSSLRetriever
server = ssl0.ovh.net
port = 993
username = mail@stefanjunker.de
password_command = ("${pkgs.coreutils}/bin/cat", "${config.sops.secrets.email_mailStefanjunkerDe.path}")
mailboxes = ('INBOX',)
[destination]
type = MDA_external
path = ${pkgs.dovecot}/libexec/dovecot/dovecot-lda
'';
in ''
getmail --idle=INBOX --rcfile=${rc}
'';
};
systemd.services.steveej-getmail-stefanjunker-hetzner = {
enable = true;
wantedBy = ["multi-user.target"];
serviceConfig.User = "steveej";
serviceConfig.Group = "dovecot2";
serviceConfig.RestartSec = 60;
serviceConfig.Restart = "always";
description = "Getmail service";
path = [pkgs.getmail6];
script = let
rc = pkgs.writeText "mailATstefanjunker.de.getmail.rc" ''
[options]
verbose = 2
read_all = 0
delete_after = 30
[retriever]
type = SimpleIMAPSSLRetriever
server = mail.your-server.de
port = 993
username = mail@stefanjunker.de
password_command = ("${pkgs.coreutils}/bin/cat", "${config.sops.secrets.email_mailStefanjunkerDeHetzner.path}")
mailboxes = ('INBOX',)
[destination]
type = MDA_external
path = ${pkgs.dovecot}/libexec/dovecot/dovecot-lda
'';
in ''
getmail --rcfile=${rc} --idle=INBOX
'';
};
systemd.services.steveej-getmail-webde = {
enable = true;
wantedBy = ["multi-user.target"];
serviceConfig.User = "steveej";
serviceConfig.Group = "dovecot2";
description = "Getmail service";
path = [pkgs.getmail6];
serviceConfig.RestartSec = 1000;
serviceConfig.Restart = "always";
script = let
rc = pkgs.writeText "schtifATweb.de.getmail.rc" ''
[options]
verbose = 1
read_all = 0
delete_after = 30
[retriever]
type = SimpleIMAPSSLRetriever
server = imap.web.de
port = 993
username = schtif
password_command = ("${pkgs.coreutils}/bin/cat", "${config.sops.secrets.email_schtifATwebDe.path}")
mailboxes = ('INBOX',)
[destination]
type = Maildir
path = ~/.maildir/
'';
in ''
getmail --rcfile=${rc} --idle=INBOX
'';
};
};
inherit autoStart;
bindMounts = {
# FIXME/REMINDER: this is used so that the container can decrypt the secrets that are deployed to the host
"/etc/ssh/ssh_host_ed25519_key".isReadOnly = true;
"/etc/ssh/ssh_host_ed25519_key.pub".isReadOnly = true;
"/home" = {
hostPath = "/var/lib/container-volumes/mailserver/home";
isReadOnly = false;
};
};
privateNetwork = true;
forwardPorts = [
{
# imaps
containerPort = 993;
hostPort = imapsPort;
protocol = "tcp";
}
{
# sieve
containerPort = 4190;
hostPort = sievePort;
protocol = "tcp";
}
];
inherit hostAddress localAddress;
}