Move to NixOS-managed email

This commit is contained in:
Charlotte Van Petegem 2022-03-06 00:09:59 +01:00
parent 7f1769329f
commit d76b03ed7f
No known key found for this signature in database
GPG key ID: 019E764B7184435A
19 changed files with 254 additions and 103 deletions

56
flake.lock generated
View file

@ -40,6 +40,22 @@
"type": "github" "type": "github"
} }
}, },
"blobs": {
"flake": false,
"locked": {
"lastModified": 1604995301,
"narHash": "sha256-wcLzgLec6SGJA8fx1OEN1yV/Py5b+U5iyYpksUY/yLw=",
"owner": "simple-nixos-mailserver",
"repo": "blobs",
"rev": "2cccdf1ca48316f2cfd1c9a0017e8de5a7156265",
"type": "gitlab"
},
"original": {
"owner": "simple-nixos-mailserver",
"repo": "blobs",
"type": "gitlab"
}
},
"emacs-overlay": { "emacs-overlay": {
"locked": { "locked": {
"lastModified": 1646499853, "lastModified": 1646499853,
@ -90,6 +106,28 @@
"type": "github" "type": "github"
} }
}, },
"nixos-mailserver": {
"inputs": {
"blobs": "blobs",
"nixpkgs": [
"nixpkgs"
],
"utils": "utils"
},
"locked": {
"lastModified": 1645895212,
"narHash": "sha256-SbR7HtHg7/UopLYLmMwwFZGF0BTmg0tLwIU/rQtRLfk=",
"owner": "simple-nixos-mailserver",
"repo": "nixos-mailserver",
"rev": "7de138037f62679e2fefa0549af543412dab0d1a",
"type": "gitlab"
},
"original": {
"owner": "simple-nixos-mailserver",
"repo": "nixos-mailserver",
"type": "gitlab"
}
},
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1646254136, "lastModified": 1646254136,
@ -127,10 +165,11 @@
"agenix": "agenix", "agenix": "agenix",
"emacs-overlay": "emacs-overlay", "emacs-overlay": "emacs-overlay",
"home-manager": "home-manager", "home-manager": "home-manager",
"nixos-mailserver": "nixos-mailserver",
"nixpkgs": "nixpkgs", "nixpkgs": "nixpkgs",
"nur": "nur", "nur": "nur",
"tetris": "tetris", "tetris": "tetris",
"utils": "utils" "utils": "utils_2"
} }
}, },
"tetris": { "tetris": {
@ -154,6 +193,21 @@
} }
}, },
"utils": { "utils": {
"locked": {
"lastModified": 1605370193,
"narHash": "sha256-YyMTf3URDL/otKdKgtoMChu4vfVL3vCMkRqpGifhUn0=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "5021eac20303a61fafe17224c087f5519baed54d",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"utils_2": {
"inputs": { "inputs": {
"flake-utils": "flake-utils" "flake-utils": "flake-utils"
}, },

View file

@ -15,6 +15,10 @@
url = "github:nix-community/home-manager"; url = "github:nix-community/home-manager";
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs";
}; };
nixos-mailserver = {
url = "gitlab:simple-nixos-mailserver/nixos-mailserver";
inputs.nixpkgs.follows = "nixpkgs";
};
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
nur.url = "github:nix-community/NUR"; nur.url = "github:nix-community/NUR";
tetris = { tetris = {
@ -24,7 +28,7 @@
utils.url = "github:gytis-ivaskevicius/flake-utils-plus"; utils.url = "github:gytis-ivaskevicius/flake-utils-plus";
}; };
outputs = inputs@{ self, nixpkgs, accentor, agenix, emacs-overlay, home-manager, nur, tetris, utils }: outputs = inputs@{ self, nixpkgs, accentor, agenix, emacs-overlay, home-manager, nixos-mailserver, nur, tetris, utils }:
let let
customPackages = callPackage: { customPackages = callPackage: {
jdtls = callPackage ./packages/jdtls { }; jdtls = callPackage ./packages/jdtls { };
@ -61,7 +65,8 @@
}) })
accentor.nixosModule accentor.nixosModule
agenix.nixosModules.age agenix.nixosModules.age
home-manager.nixosModules.home-manager home-manager.nixosModule
nixos-mailserver.nixosModule
./modules ./modules
]; ];
}; };

View file

@ -5,10 +5,7 @@
time.timeZone = "Europe/Berlin"; time.timeZone = "Europe/Berlin";
networking = { networking.hostId = "b352adfe";
hostId = "b352adfe";
firewall.allowedTCPPorts = [ 25 143 465 587 993 4190 ];
};
# Machine-specific module settings # Machine-specific module settings
chvp = { chvp = {
@ -35,6 +32,12 @@
fast = true; fast = true;
location = "192.168.0.1"; location = "192.168.0.1";
} }
{
path = "zdata/big-apps/mail";
remotePath = "zdata/recv/lasting-integrity/big-apps/mail";
fast = true;
location = "192.168.0.1";
}
{ {
path = "zdata/big-apps/nextcloud"; path = "zdata/big-apps/nextcloud";
remotePath = "zdata/recv/lasting-integrity/big-apps/nextcloud"; remotePath = "zdata/recv/lasting-integrity/big-apps/nextcloud";
@ -45,69 +48,47 @@
rootDataset = "zroot/local/root"; rootDataset = "zroot/local/root";
}; };
}; };
development = {
docker.enable = true;
git.enable = true;
};
games = { games = {
particles.server = true; particles.server = true;
tetris.server = true; tetris.server = true;
}; };
services = { services = {
mail.enable = true;
matrix.enable = true; matrix.enable = true;
nginx = { nginx.hosts = [
extraPostACMEScripts = [ {
'' fqdn = "vanpetegem.me";
cp fullchain.pem /data/root/mailcow/data/assets/ssl/cert.pem options = {
cp key.pem /data/root/mailcow/data/assets/ssl/key.pem locations = let matrixRedirect = {
pushd /data/root/mailcow proxyPass = "http://127.0.0.1:8448";
${pkgs.bash}/bin/bash -c "source mailcow.conf && ${pkgs.docker-compose}/bin/docker-compose restart" extraConfig = ''
popd proxy_read_timeout 600;
'' client_max_body_size 10M;
]; proxy_set_header X-Forwarded-Ssl on;
hosts = [ '';
{ }; in
fqdn = "vanpetegem.me"; {
options = { "/_matrix" = matrixRedirect;
locations = let matrixRedirect = { "/.well-known/matrix" = matrixRedirect;
proxyPass = "http://127.0.0.1:8448"; "/".return = "307 https://www.vanpetegem.me$request_uri";
extraConfig = '' };
proxy_read_timeout 600; };
client_max_body_size 10M; }
proxy_set_header X-Forwarded-Ssl on; { fqdn = "www.vanpetegem.me"; }
''; {
}; in fqdn = "cvpetegem.be";
{ options.locations."/".return = "307 https://www.cvpetegem.be$request_uri";
"/_matrix" = matrixRedirect; }
"/.well-known/matrix" = matrixRedirect; { fqdn = "www.cvpetegem.be"; }
"/".return = "307 https://www.vanpetegem.me$request_uri"; {
}; fqdn = "chvp.be";
}; options.locations."/".return = "307 https://www.chvp.be$request_uri";
} }
{ fqdn = "www.vanpetegem.me"; } { fqdn = "www.chvp.be"; }
{ ];
fqdn = "cvpetegem.be";
options = {
locations."/".return = "307 https://www.cvpetegem.be$request_uri";
};
}
{ fqdn = "www.cvpetegem.be"; }
{
fqdn = "chvp.be";
options = {
locations."/".return = "307 https://www.chvp.be$request_uri";
};
}
{ fqdn = "www.chvp.be"; }
{
fqdn = "mail.vanpetegem.me";
basicProxy = "http://127.0.0.1:8080";
}
];
};
nextcloud.enable = true; nextcloud.enable = true;
syncthing.enable = true; syncthing.enable = true;
tunnel.enable = true;
}; };
}; };
services.ssmtp.enable = false;
} }

View file

@ -42,6 +42,10 @@
fsType = "zfs"; fsType = "zfs";
neededForBoot = true; neededForBoot = true;
}; };
"/data/var/vmail" = {
device = "zdata/big-apps/mail";
fsType = "zfs";
};
"/data/var/lib/nextcloud" = { "/data/var/lib/nextcloud" = {
device = "zdata/big-apps/nextcloud"; device = "zdata/big-apps/nextcloud";
fsType = "zfs"; fsType = "zfs";

View file

@ -2,7 +2,7 @@
{ {
services.ssmtp = { services.ssmtp = {
enable = true; enable = lib.mkDefault true;
authUser = "webmaster@vanpetegem.me"; authUser = "webmaster@vanpetegem.me";
authPassFile = config.age.secrets."passwords/services/ssmtp-pass".path; authPassFile = config.age.secrets."passwords/services/ssmtp-pass".path;
domain = "${config.networking.hostName}.vanpetegem.me"; domain = "${config.networking.hostName}.vanpetegem.me";

View file

@ -12,7 +12,7 @@
]; ];
}; };
age.secrets."authorized_keys/root"= { age.secrets."authorized_keys/root" = {
file = ../../../secrets/authorized_keys/root.age; file = ../../../secrets/authorized_keys/root.age;
path = "/root/.ssh/authorized_keys"; path = "/root/.ssh/authorized_keys";
symlink = false; symlink = false;

View file

@ -6,10 +6,10 @@
./containers ./containers
./data-access ./data-access
./deluge ./deluge
./mail
./matrix ./matrix
./nextcloud ./nextcloud
./nginx ./nginx
./syncthing ./syncthing
./tunnel
]; ];
} }

View file

@ -0,0 +1,88 @@
{ config, lib, pkgs, ... }:
let
keyFile = "${config.security.acme.certs."vanpetegem.me".directory}/key.pem";
certFile = "${config.security.acme.certs."vanpetegem.me".directory}/fullchain.pem";
in
{
options.chvp.services.mail.enable = lib.mkEnableOption "mail";
config = lib.mkIf config.chvp.services.mail.enable {
mailserver = {
enable = true;
fqdn = "mail.vanpetegem.me";
domains = [ "vanpetegem.me" "cvpetegem.be" "chvp.be" "accentor.tech" "toekomstlabo.be" ];
loginAccounts = {
"charlotte@vanpetegem.me" = {
hashedPasswordFile = config.age.secrets."passwords/services/mail/charlotte@vanpetegem.me".path;
aliases = [ "@chvp.be" "@cvpetegem.be" ];
};
"expenses-noreply@vanpetegem.me" = {
hashedPasswordFile = config.age.secrets."passwords/services/mail/expenses-noreply@vanpetegem.me".path;
sendOnly = true;
};
"huis@vanpetegem.me".hashedPasswordFile = config.age.secrets."passwords/services/mail/huis@vanpetegem.me".path;
"peter@vanpetegem.me".hashedPasswordFile = config.age.secrets."passwords/services/mail/peter@vanpetegem.me".path;
"postbot@vanpetegem.me" = {
hashedPasswordFile = config.age.secrets."passwords/services/mail/postbot@vanpetegem.me".path;
aliases = [ "@vanpetegem.me" ];
};
"robbe@vanpetegem.me".hashedPasswordFile = config.age.secrets."passwords/services/mail/robbe@vanpetegem.me".path;
"ugent@cvpetegem.be" = {
hashedPasswordFile = config.age.secrets."passwords/services/mail/ugent@cvpetegem.be".path;
aliases = [ "charlotte.vanpetegem@ugent.be" ];
};
"webmaster@vanpetegem.me".hashedPasswordFile = config.age.secrets."passwords/services/mail/webmaster@vanpetegem.me".path;
};
indexDir = "${config.chvp.cachePrefix}/var/lib/dovecot/indices";
fullTextSearch = {
enable = true;
memoryLimit = 4000;
};
lmtpSaveToDetailMailbox = "no";
extraVirtualAliases = {
"team@accentor.tech" = [ "charlotte@vanpetegem.me" "robbe@vanpetegem.me" ];
};
forwards = {
"info@toekomstlabo.be" = "robbe+toekomstlabo@robbevanpetegem.be";
};
mailDirectory = "${config.chvp.dataPrefix}/var/vmail";
useFsLayout = false;
certificateScheme = 1;
certificateFile = certFile;
keyFile = keyFile;
dkimKeyDirectory = "${config.chvp.dataPrefix}/var/dkim";
};
services.postfix = {
config.sender_dependent_default_transport_maps = [ "hash:/etc/postfix/sender_map" ];
mapFiles.sender_map = pkgs.writeText "postfix-sender-map" ''
charlotte.vanpetegem@ugent.be smtp:[127.0.0.1]:9797
'';
};
systemd.services.tunnel = {
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
script = "${pkgs.openssh}/bin/ssh -i ${config.age.secrets."files/services/tunnel/key".path} -o ServerAliveInterval=60 -o ExitOnForwardFailure=yes -o ControlPath=none -NT -p $SSH_PORT -L 0.0.0.0:9797:$CONN_HOST:$CONN_PORT $USER@$SSH_HOST";
serviceConfig = {
RestartSec = "5s";
Restart = "on-failure";
EnvironmentFile = config.age.secrets."files/services/tunnel/env".path;
};
};
age.secrets = {
"files/services/tunnel/key".file = ../../../secrets/files/services/tunnel/key.age;
"files/services/tunnel/env".file = ../../../secrets/files/services/tunnel/env.age;
"passwords/services/mail/charlotte@vanpetegem.me".file = ../../../secrets/passwords/services/mail/charlotte_at_vanpetegem.me.age;
"passwords/services/mail/expenses-noreply@vanpetegem.me".file = ../../../secrets/passwords/services/mail/expenses-noreply_at_vanpetegem.me.age;
"passwords/services/mail/huis@vanpetegem.me".file = ../../../secrets/passwords/services/mail/huis_at_vanpetegem.me.age;
"passwords/services/mail/peter@vanpetegem.me".file = ../../../secrets/passwords/services/mail/peter_at_vanpetegem.me.age;
"passwords/services/mail/postbot@vanpetegem.me".file = ../../../secrets/passwords/services/mail/postbot_at_vanpetegem.me.age;
"passwords/services/mail/robbe@vanpetegem.me".file = ../../../secrets/passwords/services/mail/robbe_at_vanpetegem.me.age;
"passwords/services/mail/ugent@cvpetegem.be".file = ../../../secrets/passwords/services/mail/ugent_at_cvpetegem.be.age;
"passwords/services/mail/webmaster@vanpetegem.me".file = ../../../secrets/passwords/services/mail/webmaster_at_vanpetegem.me.age;
};
};
}

View file

@ -27,18 +27,6 @@
} }
]; ];
}; };
extraPostACMEScripts = lib.mkOption {
default = [ ];
example = [
''
cp fullchain.pem /data/home/charlotte/synapse/slack/cert.crt
cp privkey.pem /data/home/charlotte/synapse/slack/key.pem
pushd /data/home/charlotte/synapse
''${pkgs.docker-compose}/bin/docker-compose restart slack
popd
''
];
};
}; };
config = lib.mkIf config.chvp.services.nginx.enable { config = lib.mkIf config.chvp.services.nginx.enable {
@ -54,7 +42,6 @@
"chvp.be" "chvp.be"
"*.chvp.be" "*.chvp.be"
]; ];
postRun = lib.concatStrings config.chvp.services.nginx.extraPostACMEScripts;
}; };
defaults.email = "webmaster@vanpetegem.me"; defaults.email = "webmaster@vanpetegem.me";
acceptTerms = true; acceptTerms = true;

View file

@ -1,25 +0,0 @@
{ config, pkgs, lib, ... }:
{
options.chvp.services.tunnel.enable = lib.mkOption {
default = false;
example = true;
};
config = lib.mkIf config.chvp.services.tunnel.enable {
networking.firewall.trustedInterfaces = [ "br-mailcow" ];
systemd.services.tunnel = {
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
script = "${pkgs.openssh}/bin/ssh -i ${config.age.secrets."files/services/tunnel/key".path} -o ServerAliveInterval=60 -o ExitOnForwardFailure=yes -o ControlPath=none -NT -p $SSH_PORT -L 0.0.0.0:9797:$CONN_HOST:$CONN_PORT $USER@$SSH_HOST";
serviceConfig = {
RestartSec = "5s";
Restart = "on-failure";
EnvironmentFile = config.age.secrets."files/services/tunnel/env".path;
};
};
age.secrets."files/services/tunnel/key".file = ../../../secrets/files/services/tunnel/key.age;
age.secrets."files/services/tunnel/env".file = ../../../secrets/files/services/tunnel/env.age;
};
}

View file

@ -40,6 +40,14 @@ in
"secrets/passwords/services/accentor.age".publicKeys = [ urithiru ] ++ users; "secrets/passwords/services/accentor.age".publicKeys = [ urithiru ] ++ users;
"secrets/passwords/services/mail/charlotte_at_vanpetegem.me.age".publicKeys = [ lasting-integrity ] ++ users;
"secrets/passwords/services/mail/expenses-noreply_at_vanpetegem.me.age".publicKeys = [ lasting-integrity ] ++ users;
"secrets/passwords/services/mail/huis_at_vanpetegem.me.age".publicKeys = [ lasting-integrity ] ++ users;
"secrets/passwords/services/mail/peter_at_vanpetegem.me.age".publicKeys = [ lasting-integrity ] ++ users;
"secrets/passwords/services/mail/postbot_at_vanpetegem.me.age".publicKeys = [ lasting-integrity ] ++ users;
"secrets/passwords/services/mail/robbe_at_vanpetegem.me.age".publicKeys = [ lasting-integrity ] ++ users;
"secrets/passwords/services/mail/ugent_at_cvpetegem.be.age".publicKeys = [ lasting-integrity ] ++ users;
"secrets/passwords/services/mail/webmaster_at_vanpetegem.me.age".publicKeys = [ lasting-integrity ] ++ users;
"secrets/passwords/services/ssmtp-pass.age".publicKeys = hosts ++ users; "secrets/passwords/services/ssmtp-pass.age".publicKeys = hosts ++ users;
"secrets/passwords/services/acme.age".publicKeys = servers ++ users; "secrets/passwords/services/acme.age".publicKeys = servers ++ users;

View file

@ -0,0 +1,11 @@
age-encryption.org/v1
-> ssh-ed25519 hKAFvQ ahBZiWAQJ8gDr9iXra/ss3Z0Av9D1ie9JSKLF4c/Okw
yFgKlZZTQpJEgk3fcSGNYH5pSzp/Hk0UgE9IqyTHa4s
-> ssh-ed25519 s9rb8g c18VGG0c1TUodSAJ9yse6NnTxU55vD3/GxFT6AKDMxE
D/eY7Yy8aEQI+G7NnLv7wYuj4wKgss5LtC+hziJ82GE
-> ssh-ed25519 yad4VQ uFPIuBUVcB4uNWT2n0zG47B0lS3xJNc9eYC2UYjOXik
HASW6oo49CCCqDhVxBQWV8ospBSFZQj2US1NFbenItE
-> xB*-grease Y/qK/}Qi \1]9X~
eFWnjgXubs1JoPMhz13W6fU
--- HMRxW/o6WnGKX1VBIhVoibAA3LgI8IFY71I7sbmj08I
¨;ÐáNÛû Nÿfå¾`´.×í ”‚?H°8‰p¤åâfPL<50>1î°ˆ=dŽê昚üàä<5_øN+h¹*kO²ÖÕKûÀW:úòCæ*GË¢¤ö†²""ó·˜<|“mPIºFÙŽ­B

View file

@ -0,0 +1,13 @@
age-encryption.org/v1
-> ssh-ed25519 hKAFvQ K0/OGHgNGGOXqUcbDgCIrzW4t73SPSeUd+gG5jnm00c
KGhXDqs6PEG4aMVujmHC6m5srF3f8AA7Qwoero2HEYA
-> ssh-ed25519 s9rb8g JTk9eebQUBH+iblr1D4l1/GEuw44dSL+6+z3bCvewQA
kQX7BhNb06o+MvTaZJAjeXzxzMgG97yBSi7i8wQilXI
-> ssh-ed25519 yad4VQ aVsBmsu8EUJGSdZSkMMRoqCMSSnerZ1ZQSSQdL74pHA
TBoBMYpaaSW4JxnSNjFmMQZWuG980eO3eUx+sBJ6Sx4
-> D0j-grease /Vnw;b}W !Qi wxsjo,Ns 3SP
gICLXBnxzhuWZYcEAjHqTUXthxk3OXXOKcqaqZ4TPgJNlP+w2tQPI9mKkKvBsyxC
kPRmsQrMeaKkbSBd7E9ukHmjFFrUr976dbYEYBVr
--- ct4WJvTs7bBnsMIYGgKpqDqQP6lD6HKy0M9YZr6nMtE
ß@(ç%J}$„¯øä`Qî'Î
<EFBFBD>;»)U¶GQm3%jç™F7ÖˆpI¸<41>óžÉœ<C389>uÁÝd bsiWn™5<E284A2>­5™lØ*½wÉçtBãÕ¨Z4>1Ù¼vC/äù]

View file

@ -0,0 +1,13 @@
age-encryption.org/v1
-> ssh-ed25519 hKAFvQ ipuOfR53i4N9K7WU3n42Z8T4Yx4stuFR+ZbwZ//qOhA
u+B/ghnsEtRkdhfMhzq0mXqITnIN/fBZWL1Qr4AJqMQ
-> ssh-ed25519 s9rb8g Z8bMCuAsDgYPFqkHbrjmApusx/eGzht/hlRMf+SMVxc
Ll7OIxlh3MhlDNZuP+AOY7uumdoRkhdFzX0Wnk3u36E
-> ssh-ed25519 yad4VQ x8zMlh1ik/u/H6w1Pz/EqHbkjf9YfGSAyGJNu1sJyU0
hw4aZDrMN7TSR9pdstgb/mtcGekFlFP32IfcWHQHhqk
-> =-grease
akxvkvEU2dQoOjC23uvAhwVdbbEu6UgholfEeMJmXPPxg52ajnGvQl8TCHsMZB+v
DoiJ6IPsByE
--- Qu6IXI4VY6a66SOQDxH7iwcbu2+HfKb8yoQ8MU9Jf1Y
h_<Á3VÂèop
5xä_!U¯ÙÕ<C399>Qb>”1U¨! ò库3‡dðËHßÐÅŒ¨ÙœB]å* p`*ž”™L$œ­•Jܳù‡0Lë²pÞø¡¹øå¬mܵÈCbP{

View file

@ -0,0 +1,12 @@
age-encryption.org/v1
-> ssh-ed25519 hKAFvQ JHjuI9rQDBEZvK8NN3KmDOL4tZsGZMec1EFXrMSY1nw
n0uoSU5wTkQYf9xBOEiWWfMjjATk7T0orntiSjTKdtE
-> ssh-ed25519 s9rb8g E1lkFCR7hM5LXWBZ51y5hZvUN4+pHIudkXmpU8wkLCY
eEvc/SXb2d8vqRTroayijnVB99ZO4RPgK03fCR37O94
-> ssh-ed25519 yad4VQ x6B/1ZQOMgbjbs32U7j4Rr4/MmBLyCg+cIPDynFJuXA
6loeFyyP9g2R3/p//6iUCn3YfMl2otRcIvl2srWBpd0
-> PH~?+-grease
GX64yaOgkxrMz9cfX6BfbXuefE8PPeYyIke4bGCxbsRSibDHaHfcd8OiIKxAHkP7
IwNDaBN+FSoIvKc
--- 8Vd7zRm8JAo0kYXwuP5+AlAIyEWzahj7NKv2VZOsdWo
<EFBFBD>¸ƒéàœÔ%RM·ð¯iÈ JRMäF~ÒqÆÊNôCª—šŒPlͣͫéåæ²bF4Èj¹à3WøÏbÃÜì, ÍךޔAÌgI¬Ü`òyâ¡Œ•`@eH²k³amLOáX€ã