Compare commits

...

4 commits

10 changed files with 523 additions and 6 deletions

View file

@ -1,4 +1,8 @@
{inputs, ...}: {
{
inputs,
lib,
...
}: {
# debug = true;
# We only define machines config in this flake yet, so we only include
# the module that builds these. This file might get fuller, if we need to
@ -53,6 +57,42 @@
_module.args.pkgs = import inputs.nixpkgs {
inherit system;
config.permittedInsecurePackages = ["jitsi-meet-1.0.8043"];
overlays = [
(_: prev: {
alias-to-sieve = inputs.alias-to-sieve.packages.x86_64-linux.default; # add custom package to convert alias files to sieve scripts on the stalwart machine
stalwart-mail = assert lib.assertMsg (prev.stalwart-mail.version == "0.11.6-unstable-2025-02-04") ''
1. If the bug https://github.com/stalwartlabs/sieve/issues/11 is resolved to our satisfaction, try to remove this overlay.
2. Check whether sieve-rs recieved new updates that our patch needs to be rebased upon.
3. Check whether the sieve-rs patch below that exchanges the dependency needs updates.
4. Then update the version comparison in this assert statement.
5. Update the `cargoHash` by setting it to `lib.fakeHash` and then inserting the result.
6. Check if we can get rid of alias-to-sieve when stalwart-mail has a builtin alias feature.
'';
prev.stalwart-mail.override (
let
rp = pkgs.rustPlatform;
in {
rustPlatform =
rp
// {
buildRustPackage = args:
rp.buildRustPackage (
args
// rec {
cargoPatches = [
# Let stalwart-mail depend on our own version of the sieve crate that does not have some “loop prevention” that disables redirects to the original sender.
# We want to redirect to sender if we simulate alias files and not doing so barely prevents loops in my opinion.
./patches/sieve-rs.patch
];
cargoHash = "sha256-gb2oFlVA/vE6DoWWW8SCFA3l7rtV2RuosPUY+6IcKNM=";
}
);
};
}
);
})
];
};
};

View file

@ -0,0 +1,52 @@
allowlistPass:
matheball: ENC[AES256_GCM,data:4y83ZJ4=,iv:+B1hTSGs5cskmUA9gLpRHPjhxzvwOrplB+lIbNUKtz4=,tag:ZsKA2A4ltbI3px1Z16EgvA==,type:str]
mathebau: ENC[AES256_GCM,data:ZlIv0MrCVtsyF3t9Gr/zcg==,iv:ZdBlnx4/zQZjT75ssB0osfDlWVerUe6yvwbMxlXpHZs=,tag:ytlNq7zP2WtPafcSQFZ6RQ==,type:str]
mathechor: ENC[AES256_GCM,data:d5KyoD/P8/j+poJSGF1nDA==,iv:ayKtvj4EEqUtMLi/7njbxuUql1A58WNi729svHtZju4=,tag:JqWoxxMN5mVN+gaQTmBv1Q==,type:str]
koma: ENC[AES256_GCM,data:bB7px1n5q1+++sctsmIMJg==,iv:DIJGpC9+JyFv3SU9dBVLdnEkRlZzY7DBRAL4zXSbpec=,tag:WaZUGvYtm+5ys2RsBNILog==,type:str]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
age:
- recipient: age1rasjnr2tlv9y70sj0z0hwpgpxdc974wzg5umtx2pnc6z0p05u3js6r8sln
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBpWW9FZHEwejRaRER1MHJQ
VXgyaE1GQmhhNFh1dEtBNjRnZXVqWm5hV25vCjliank4KzFobEZtbitzaXBhT1F6
cCtqeVorS1BLMmMzZkVVOEN6NERFdDAKLS0tIGkzUUt1NnBUWUJWTy9Pd2FIeTF0
cDVaUHowSEpoRjR3Zm81Z1p5NlYzV1kKMRvC7+3TS5EKjWg/NPnbwvVIikxf+Bpa
zNo9jhw3GREMScBXOiarm+xgMZ1e2SRrLrUwfR4DiXI4uvg1Jk/tPg==
-----END AGE ENCRYPTED FILE-----
- recipient: age1epz92k2rkp43hkrg3u0jgkzhnkwx8y43kag7rvfzwl9wcddelvusyetxl7
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBRYk1LQTVDNGhHWXJZSmsy
NEZ0WTNlek4yVnRwL3BKNXYrcm84SzIvNlRZCjlDdXU1a2NRNUVHZmkyK2ltZ3pE
bmtmVE5TR1hBcVNhaTBGK2F6VWZ1d2MKLS0tIDVKcXhDbjBncFlsR3FzanRhWWQv
Um1jcExjN2RWbHhzY2ZpcWVTWE1IbHMKfRSAmfbk+JDWdhSTSg9GZ+lws5DOHv9T
ZO9nQV37X9zFD6sXDWaspG3sf4kJZUCbWjCTKyQL/xmh4+E8+CAXYw==
-----END AGE ENCRYPTED FILE-----
- recipient: age1dhzugelagj6vge5jjxwwn0522ngf7fhxn04sxy2tm8557rtme5tstprwnj
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBzOXBwTUF3ZXJCTFJOQjVC
bGplRDRCQVhtUEJPcnhENEF3UVVnbmVKNnprCjFOZW94ajI2d21RamZKT0xFMmtZ
ZzZFYjg3WDBmOVhlaFZyOW83M1NYVXcKLS0tIGltWUJGczNJS0pWTmxaZHU5Wi9t
TDRCdStocXRvLzBPUTd2blZFV0IyblkKjufZg39n/TI6BhGhIFNz4jplUx6u3/bo
NMbr9uJy/I1sdlfGNaheG/TIGOgFG1KqGkGdwpisU3gUD9uMUo1dvw==
-----END AGE ENCRYPTED FILE-----
- recipient: age1ktwclxa640l89le6yecm8v2z6hmwr4lusd6x9gyzamhv57887szqtqp59a
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBzdDdsdW44ZlQyMzdJNmsv
aTIzVWRoSDhzamlqTDFOemZlc1JQMFdZbFJNCmVZbDVVaDBSVi8yTkdOQ1UySy9X
MlhXTzRvNWtqUzQxTlNqQ2RlN2J1OXMKLS0tIC9aZEZMVkFybnRTQmhpM1dzc1lt
bDdvdHc3Y1NmeE5WUzl3cXVRc3pmOUkK+9WueS1wDQDJlenec4jJCfynbPnuOFYR
HFsWmvEZJ+XhH6N9Q0phCHQgZGiR67FH6CHkCblmb6ZfZcWSEe1oTg==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2025-01-05T13:49:19Z"
mac: ENC[AES256_GCM,data:i7t/Hb5aW0lIvPLk84geQ792uUGP25vX8FC7kK/3H19tz5i4zsIcvl1d+oB5gJ004gP5pRogcuKL1xHUUl+A0UXXNzRpxc0BBVZaxnIhjfPunORbmZeJQRP298tQpvYYqI/pGhjrlit37U9jecGf1l12Cgv97sGW42d2F+S2Soc=,iv:My21fMF3SEr6mg2+eh8KA6B8tzmQVEDy2BG3hfkafrU=,tag:xdU6j8ti8Z68rbiRxkj7Pw==,type:str]
pgp: []
unencrypted_suffix: _unencrypted
version: 3.9.2

View file

@ -10,15 +10,76 @@
# System configuration here
services.mathebau-mail = {
enable = true;
stalwartAdmin = config.sops.secrets.stalwartAdmin.path;
# see passwd on azathoth for plaintext or machine secret in encoded format for HTTP Basic AUTH
stalwartAdminHash = "$argon2i$v=19$m=4096,t=3,p=1$d0hYOTkzclpzSmFTZUplWnhVeWE$I7q9uB19RWL0oZKaPlMPSlGfFp6FQ/vrx80FFKCsalg";
domains = [
# lists.mathebau.de is forwarded to another VM and does not need to be listed here.
{
domain = "matheball.de";
allowlistPass = config.sops.secrets."allowlistPass/matheball".path;
}
{
domain = "mathebau.de";
allowlistPass = config.sops.secrets."allowlistPass/mathebau".path;
virt_aliases = config.sops.secrets."mathebau.aliases".path;
}
{
domain = "mathechor.de";
allowlistPass = config.sops.secrets."allowlistPass/mathechor".path;
virt_aliases = config.sops.secrets."mathechor.aliases".path;
}
{
domain = "koma89.tu-darmstadt.de";
allowlistPass = config.sops.secrets."allowlistPass/koma".path;
virt_aliases = config.sops.secrets."koma.aliases".path;
}
];
};
networking.hostName = "kaalut";
vmNetwork.ipv4 = "192.168.0.17";
system.stateVersion = "24.05";
sops.secrets = {
sops.secrets = let
allowlistSops = {
sopsFile = ./allowlistPass.yaml;
owner = "stalwart-mail";
group = "stalwart-mail";
mode = "0400";
};
in {
# Password for the HRZ API that gets a list of mailaddresses that we serve
"allowlistPass/matheball" = allowlistSops;
"allowlistPass/mathebau" = allowlistSops;
"allowlistPass/mathechor" = allowlistSops;
"allowlistPass/koma" = allowlistSops;
# Virtual alias file
"mathebau.aliases" = {
sopsFile = ./mathebau.aliases.yaml;
owner = "stalwart-mail";
group = "stalwart-mail";
mode = "0440";
};
"mathechor.aliases" = {
sopsFile = ./mathechor.aliases.yaml;
owner = "stalwart-mail";
group = "stalwart-mail";
mode = "0440";
};
"koma.aliases" = {
sopsFile = ./koma.aliases.yaml;
owner = "stalwart-mail";
group = "stalwart-mail";
mode = "0440";
};
# password for https://stalw.art/docs/auth/authorization/administrator/#fallback-administrator encoded to be supplied in the basic auth header
stalwartAdmin = {
sopsFile = ./stalwartAdmin.yaml;
owner = "stalwart-mail";
group = "stalwart-mail";
mode = "0400";
};
backupKey = {
sopsFile = ./backupKey.yaml;
owner = "root";

View file

@ -0,0 +1,48 @@
koma.aliases: ENC[AES256_GCM,data:r9dJzjUrv9BBr6emtHuIm71OamwTQdxdAbWuh62ZPG/tbvg8YimMvUno1WXn6EXn+0q2Gf+r4UiB6RJLD62D+JU+lEAKg9LKfX+578M4eCIbwRqkHWQYAtT/V3nB8L7/dqcvdatF90+50w==,iv:SL13OY8XUNdVBkZlKBfqwzT5LTtZcykyGIK+nHHOa10=,tag:Yyu2/ZqLotmFD+cMwtXYlA==,type:str]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
age:
- recipient: age1rasjnr2tlv9y70sj0z0hwpgpxdc974wzg5umtx2pnc6z0p05u3js6r8sln
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBBS283ZTdKVTVLaDRDV1N5
SGhJQjJWdXJzc1l5OWtCWVdueTJMdjZpUjJzCmtUZFRYR0JXTW15Z0NyMktEbW5w
dkk1TjF0dVQ3MlFhNUFTbU0vMFdySWcKLS0tIDZPQmxSVGYzT2dDM244ek95dk9n
SnhtQWJic3B2YTM1ZlE3SHVRSjl1YVkKgUXW7JW3WSM5EusBoxQMsBRGwIqqi7Lo
DgWLq/P1rruuqRAS8hl4cht3jz6PlCJgVh2xpaM/kfkFS8ZuhVFw4g==
-----END AGE ENCRYPTED FILE-----
- recipient: age1epz92k2rkp43hkrg3u0jgkzhnkwx8y43kag7rvfzwl9wcddelvusyetxl7
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBKdmcyM3hSUFdlM25UUndu
RUhzdEhsakdEdytBUGRyRTFXRzdYK2RBR0dnCmJqOTlvYkZkeld3eDYvRmRmUU5u
aHArR0FkZWRtT0hoNTZpS1JmaTRHencKLS0tIGVVSWN0NWQyQWdrcXdQUnQxUjdu
MWFZWVQ3RmZZS3FnRkJPdDRrOTZrWG8KVgFqfeBLw5gTBKugfnC4a5OLwOhosSgy
3hXbGMrJiBDwOS+70H3L+IwiNSoJ6mL+ufShCTq8wER2L9GTteI8gg==
-----END AGE ENCRYPTED FILE-----
- recipient: age1dhzugelagj6vge5jjxwwn0522ngf7fhxn04sxy2tm8557rtme5tstprwnj
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAzamM5TDVQM0hnZklsbncx
SlBMM0NpcnBBai94czV5WE1Md21EeE1kVXpFClpDVTRqYm5rWFhjVjRPQm1IVWxW
WTNlZFo4Y3VVNjZhckZ0RFVlQlV0OEEKLS0tIGJOR3k0OUorYTNXL01KQWJBUzVD
V0xidWR0SnBDM01hRlkrTlY4eEIrc1EK1Hye/jrQebkEDQ8muJpgHqBLefjnEJPF
GxdANetJLuZeeiOUjaUcbP6tecqZpiWN8fFEXrjNL4vnrHvJ+bR1aA==
-----END AGE ENCRYPTED FILE-----
- recipient: age1ktwclxa640l89le6yecm8v2z6hmwr4lusd6x9gyzamhv57887szqtqp59a
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBqQURCeGJBYytCdlhrWjF5
c1ZrbEFENDF5bTNMaE52SE5CS1dVdWJCNlFzClZtK1QxOWY0dEVRRWY4MEtlZ1N1
eGlaYXVLMUJiUi9FckdNcllBRCt4cmMKLS0tIEZuOTZQTm9vWHQ4Y3Z6RVloT0VL
OW5ZQWIvU2x1OEN6OW84K0dqRmhGNUUKOA3ugnG/ZD7m1DKrFjpZ8opPnjPtLaQx
t8qgGuQIoX6KeUb+YybRAOAPPzl51/m9GSUB43Eanm/tVJpdaew7/g==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2025-02-25T17:41:29Z"
mac: ENC[AES256_GCM,data:lZ9AXtJzVuc8Jg9L0aGhS18cs8pTjOG/xNP2tG25/7/PEdEV1SNwbxubGQOFAHrNbiDbmJMKJq96mhV8e3tHszlrzQnU1uyu9MrWiAYwV3CjmwSqC4J9ezSm/AY9e9+OWKn6sb4RVsz9A7aDGUhhoZMycnPNRKlpTuzdTIJK98o=,iv:LxSsZoHkJ2HFXBLWkw+SUb/LYW2ciE1DtzpoV4YLOwQ=,tag:QeYmreRGZk4PqlLWJLLD8g==,type:str]
pgp: []
unencrypted_suffix: _unencrypted
version: 3.9.4

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,48 @@
mathechor.aliases: ENC[AES256_GCM,data:VKEGY6KVtgKApnV7N2e2cqy9erDWQ2fb88Gwcpp5th/t0VGp16KGDtGiuQXhY80j6dDIcQMd9bLHzqAzc4+i/WhmEPhiXUkGiEKuarMfvqNl1LBlXFCoIrUXMMSIqab9q+fE3ignVQapE/YZt9aniyvg1prcmBcwIy9rDoHkiTY006ux5CM+vX0F60ADX8Nf6Qmn/JncPxXgq2jYsBxjXPj7BwJaair/+nxrbVf0,iv:Elj1NDeR1fdIIjIbjvkV3BmcVAKjwdMfknuNxMXJsa4=,tag:AkXWQ8sTMLsd7a+MfRcF/w==,type:str]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
age:
- recipient: age1rasjnr2tlv9y70sj0z0hwpgpxdc974wzg5umtx2pnc6z0p05u3js6r8sln
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBjMlRsWnkrREVaQitsWHMy
WHZFVG1qN25QbWFHcUxNS1Z0SFRDd1oxeG5RCi8wNUhkeWh2VjI4ZGowM1ExaExh
SE1yVGFTUHZadUdDL3pxaGdKTHQ0VTgKLS0tIHVNM2xlOFNNS3dFalJqZUtPODRn
b2NOTHpXSUVyaFRJNG5ONCt0TTVjOEkKYld7KN995QxdrGBVRYgCxO7kGwsiq+cp
iQJTjMdoFygIrTkgE5Rj89/GCiVe0+yAWJuQF7PEnC3cyq0M1g+fzw==
-----END AGE ENCRYPTED FILE-----
- recipient: age1epz92k2rkp43hkrg3u0jgkzhnkwx8y43kag7rvfzwl9wcddelvusyetxl7
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBPRFJCeXhwQVFSWmgzNHBu
SHlTTGtiRkI5bmhKa1B0QTZMY3FERmlUd0FBCk1vOUpydEFZUExpR2hpWm9mRHpE
dk9MQ042K0FpSVJ3dUlQcktGT2k1VjAKLS0tIHpGRmwzNE01YkV1TW94RkNmMjN4
YnNXZUlta3NMVW9Cc3V2T0t4R01RSlkKNTW3gnF49BuPwF3jwciOYThJe+gJa0a6
WKYt+aJuHi0a4y5rS/wfttij+hS5vYVNOrgfJ5bGinkNuAygA2hMOg==
-----END AGE ENCRYPTED FILE-----
- recipient: age1dhzugelagj6vge5jjxwwn0522ngf7fhxn04sxy2tm8557rtme5tstprwnj
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB6MjZOR1dwb3RjZnlNNW4v
SzJnT1BRVktWNDI5S2Z2NnhQQzdNeS9ralI0CnN0SU9ESEV3ZCtRQmpZK3VZOGYx
Y3FVUy9zY3RZcGxyVmttVzFJL1haYWsKLS0tIENGRW1KZkpUdldOZWgzSXVoenpX
dTVpNUpWallSTzJ3cEZJTXk3c2t1czgKzJCwhMspzAsjzwSRdSPUoseEAsKp8HFy
cL9if92ar68HMHTdoy0Zvy+5AbxKUxgXZ2t8cDgkL8bNG5Ri2xYaUA==
-----END AGE ENCRYPTED FILE-----
- recipient: age1ktwclxa640l89le6yecm8v2z6hmwr4lusd6x9gyzamhv57887szqtqp59a
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBtNm5xUGkrK1dYd2ZtamFW
NXpNMEtvNTl3U3MzeVNSbVJOdGdlWGsxRHlZCllQVmNtYzBJNDc2Y0dmUlNsbTF5
RHB4QWZ1VGNFVkx1Q0hNK3FDTTRrUlkKLS0tIG9hbldDeHk0YmVZV2IwMXNpYStU
Q29uVHBCb2pTeWVJVmVXbWpycnFneWMKnDmu5917dddV8vjO0L8OP3wXMjDi46Ro
b9eOY8l74jm4sTxyKNvnkEjD6iHn1t7f8J7HAbWrpZY+J0i77nrzQw==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2024-11-23T09:05:51Z"
mac: ENC[AES256_GCM,data:Xnulo0681LtgH9SZt9DL3nd9bSDH+TCQDvbKdggVBJ66rxBiKmlbu5MAblAWqxbdZ6EelldaVeX9OaL2rYJoYbTWxzw2iuPieldp3Ah3PsTI2C8W+UD9KVHcB+3AMOmVmJZzFlZvTwyfPfZRNNb0HAijkN97P3fP0r1Iqf3YjiI=,iv:vhu38HM4e+PyyChXvI87LWSGtKQQiXUr4MKrI7kotzk=,tag:eNuQD74kUO+duqEXNbLJBw==,type:str]
pgp: []
unencrypted_suffix: _unencrypted
version: 3.9.1

View file

@ -0,0 +1,48 @@
stalwartAdmin: ENC[AES256_GCM,data:4vpvxtFa2KiF3ojl+cw3ic/MI7UM9JQCQn76bidYvbW31zgF,iv:DtLAi68oQRf3U69uFK0Cz4qHMkxM6NnB3lVYft/DtqQ=,tag:HYm2mdpTuXNHdQIv2Rkwig==,type:str]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
age:
- recipient: age1rasjnr2tlv9y70sj0z0hwpgpxdc974wzg5umtx2pnc6z0p05u3js6r8sln
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAxcTRqZXRoNTJCdFhQUG9o
Qmx2cVl0TWdaQzZZUThTOEpQdjIxVFh3eHhzCjlHWHhSYmM1ajYrdjl3Nm90TkRh
YWE3c0hJYzdFWXpZUGI0cHBQdThSWWsKLS0tIFh5M20wV2ZZbzllS1BNOGtaRUVF
MFN3bENrZ0tDMllJM1E5MWkyZ2thZEkKfZlUzE5t8K0oHZYOSVItvRJZP2MJlA7N
SLozGlpwCoZKWP6qAqP5jisTG/npQRhcqwkd7P39EytO2HXU9m8sJA==
-----END AGE ENCRYPTED FILE-----
- recipient: age1epz92k2rkp43hkrg3u0jgkzhnkwx8y43kag7rvfzwl9wcddelvusyetxl7
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBkVldRVmtPUzFxV0ltK0d2
SHRqbXZCTW5wZUtZM0ZkL3lXOEJmVXdjMXdZCjE5MUUrSEhnWHRSOVhtWWQxdndv
ckUzTFl4ZXM5VHBTRlY3SzVsZWpxNUEKLS0tIEtpbTBhaWR1c3RhSW5nclZvMTdO
eTBYL1Q5cXNvTGkvQzJMWHZHaEZseVUK5w2MPZMquT0luq+tl2owLrrSBx9KPskS
FupcAZTcCo+YsemKLjJ6GlHch5x8Mw98NHS5h1AKxwZYtcfwg3lfbQ==
-----END AGE ENCRYPTED FILE-----
- recipient: age1dhzugelagj6vge5jjxwwn0522ngf7fhxn04sxy2tm8557rtme5tstprwnj
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBpUitNeHNWOTVjWkF4YWhB
MnEwWDFnT0wyNUx3VmlQMmZTRmZRbXBGOVFvCmpoOHZZSXRweUtZaHZ6azF2Q3dK
NFBwa242U3JSVjhtOUlRTUZuakhkcXcKLS0tIEN5TGhMRFphdEpvcU5zTmVlTTJN
d2JRc2p4YmpuUHAycUoxc1FuZmxhemcKOgGyieFVS57tsvUtVooahqswYZH0Fi6+
jxM6Ga/tIM/bZ/qSwYrNlNiz0XHm8/XFH2s8sxypDZ+NHGLs3zGjsw==
-----END AGE ENCRYPTED FILE-----
- recipient: age1ktwclxa640l89le6yecm8v2z6hmwr4lusd6x9gyzamhv57887szqtqp59a
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBERTdvSTZ3eEVNbEZpUnQ2
ZC85blRQVzgrckljcnZPeVhZWUxGd01tankwCjBCZHdWRnpoZkdRQWdoK0VmOFVy
VmpiOFkvNisrWmp2NE1kalB4dUhzdWsKLS0tIEJ6T1FsTFlIMUVWd3FwbEtldmlC
UjFHWHNZci8zRlFXNVpNNk5oSUNvaTQKW9T88GflSysJwqMnBrc/jZVwL/fRdg2a
5XysXb/dCo4uNxLQit/KNSpINj7rAkf4Pk819DO6SKiIiuIJDXw9cA==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2024-11-23T11:43:23Z"
mac: ENC[AES256_GCM,data:GZ1Q67n43WU3fDQd6SGsD2EZgoaq1mzh5biy42cx6FQWlveK5lhb0F2HUuWWv5zSHKpslEPD6odvkQmMNCRY8NsvT3+KBAnHHU0aHzM9AEV27cDL4x6oBvO52EMxsNCMm+fXPD1CubQxfbfvx/aIuqb1sovgKGgwf4u6yqIrHJ0=,iv:ExX+ySMXhF/c1w2IP7y8mdlcy8W9Zxiy6X67b2f4AeY=,tag:shxQJdaW3HsG6sNY+zDNCA==,type:str]
pgp: []
unencrypted_suffix: _unencrypted
version: 3.9.1

View file

@ -1,4 +1,10 @@
/*
* Building: We patch our version of stalwart and thus need to built it locally.
* Be aware that this needs some hours, about 12Gb RAM and a few Gb free space in /tmp.
* If you only want to deploy configuration changes and no software updates, consider building on the target VM.
* It has stalwart in its nix store and does not need to rebuild it.
* Forwarding mails: Update the Sops-secrets in the machine directory, rebuild on the VM and deploy.
* Everything else should happen automatically but new redirects might take up to two hours due HRZ infrastructure.
* Using the web admin interface: Set your SSH to do portforwarding of some local port to port 80 of the VM and
* and use your personal admin account or create one using the fallback admin password.
* Create users with mail boxes: Go to the admin interface and create them.
@ -9,6 +15,7 @@
{
config,
lib,
pkgs,
...
}: let
inherit
@ -22,10 +29,33 @@
in {
options.services.mathebau-mail = {
enable = mkEnableOption "mathebau mail service";
stalwartAdmin = mkOption {
type = path;
description = "Path to a file that contains the stalwart fallback admin password encoded for HTTP Basic Auth";
};
stalwartAdminHash = mkOption {
type = str;
description = "String containing the hashed fallback admin password";
};
domains = mkOption {
type = listOf (lib.types.submodule {
options = {
domain = mkOption {
description = "Domain name that we serve. We also push its addresses to HRZ.";
type = strMatching "^([a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,}$"; #Regex from https://www.oreilly.com/library/view/regular-expressions-cookbook/9781449327453/ch08s15.html
};
allowlistPass = mkOption {
description = "Password file for the HRZ API that gets a list of mailaddresses that we serve";
type = path;
};
virt_aliases = mkOption {
description = "File path to a virtual alias file applicable for this domain";
type = path;
default = "/dev/null"; # there might not be an alias file and reading an empty one works with our implementation
};
};
});
};
};
config = mkIf cfg.enable {
@ -127,6 +157,32 @@ in {
];
};
# Stalwart gets its configuration from two places: A TOML configuration file that we control in this module
# and from a database that can be configured from web management interface or via Rest API.
# We here define what comes from the TOML-file and especially add "sieve.trusted.scripts.*" to the default ones
# because only TOML-based keys may use macros to load files from disk.
# We want this to be able to load our sieve-script for mail forwarding.
config.local-keys =
[
"store.*"
"directory.*"
"tracer.*"
"server.*"
"!server.blocked-ip.*"
"authentication.fallback-admin.*"
"cluster.node-id"
"storage.data"
"storage.blob"
"storage.lookup"
"storage.fts"
"storage.directory"
"lookup.default.hostname"
"certificate.*"
] # the default ones
++ ["sieve.trusted.scripts.*"]; #for macros to be able to include our redirection script
sieve.trusted.scripts.redirects.contents = "%{file:/tmp/virt_aliases}%"; # generated redirect script
session.data.script = "'redirects'";
authentication.fallback-admin = {
user = "admin";
# see passwd on azathoth for plaintext or machine secret in encoded format for HTTP Basic AUTH
@ -149,6 +205,95 @@ in {
files = ["/root/.ssh/known_hosts"]; # for the backup server bragi
};
systemd = {
timers."mailAllowlist" = {
wantedBy = ["timers.target"];
timerConfig = {
OnBootSec = "1h"; # Run every hour
OnUnitActiveSec = "1h";
RandomizedDelaySec = "10m"; # prevent overload on regular intervals
Unit = "mailAllowlist.service";
};
};
services = {
"mailAllowlist" = {
description = "Allowlist update: Post the mail addresses to the HRZ allowllist";
script = let
scriptTemplate = {
domain,
allowlistPass,
...
}: ''
echo "process ${domain}"
# This line gets the available mailboxes from stalwart's Rest API, searches for their addresses and collects them to a file for submission.
${pkgs.curl}/bin/curl -s --header "authorization: Basic $(<${cfg.stalwartAdmin})" http://localhost/api/principal | ${pkgs.gnugrep}/bin/grep -o -e "[A-Za-z0-9.!#\$%&'*+-/=?^_{|}~]*@${domain}" | tee /tmp/addresses
# This line searches for available redirects and adds them to the submission file.
${pkgs.gnugrep}/bin/grep -o -e "[A-Za-z0-9.!#\$%&'*+-/=?^_{|}~]*@${domain}" /tmp/virt_aliases >> /tmp/addresses # This doesn't catch all RFC conform local parts. Improve if you need.
# Post local-parts to HRZ, see https://www-cgi.hrz.tu-darmstadt.de/mail/index.php?bereich=whitelist_upload
${pkgs.curl}/bin/curl -s https://www-cgi.hrz.tu-darmstadt.de/mail/whitelist-update.php -F emaildomain=${domain} -F password=$(cat ${allowlistPass}) -F emailliste=@/tmp/addresses -F meldungen=voll
# Cleanup submission file
rm /tmp/addresses
'';
in
lib.strings.concatStringsSep "" (map scriptTemplate cfg.domains);
serviceConfig = {
Type = "oneshot";
User = "stalwart-mail";
NoNewPrivileges = true;
# See https://www.man7.org/linux/man-pages/man5/systemd.exec.5.html
PrivateTmp = false; # allow access to sieve script
ProtectHome = true;
ReadOnlyPaths = "/";
ReadWritePaths = "/tmp";
InaccessiblePaths = "-/lost+found";
PrivateDevices = true;
PrivateUsers = true;
ProtectHostname = true;
ProtectClock = true;
ProtectKernelTunables = true;
ProtectKernelModules = true;
ProtectKernelLogs = true;
ProtectControlGroups = true;
LockPersonality = true;
MemoryDenyWriteExecute = true;
RestrictRealtime = true;
RestrictSUIDSGID = true;
};
};
"stalwart-mail" = {
restartTriggers = lib.attrsets.mapAttrsToList (_: aliaslist: aliaslist.sopsFile) config.sops.secrets; # restart if secrets, especially alias files, have changed.
serviceConfig.PrivateTmp = lib.mkForce false; # enable access to generated Sieve script
};
"virt-aliases-generator" = {
description = "Virtual Aliases Generator: Generate a sieve script from the virtual alias file";
script = lib.strings.concatStringsSep "" (["${pkgs.alias-to-sieve}/bin/alias_to_sieve "] ++ map (x: "${x.virt_aliases} ${x.domain} ") cfg.domains ++ ["> /tmp/virt_aliases"]);
wantedBy = ["stalwart-mail.service"]; # Rerun on stalwart restart because forwardings may have changed.
serviceConfig = {
Type = "oneshot";
User = "stalwart-mail";
NoNewPrivileges = true;
# See https://www.man7.org/linux/man-pages/man5/systemd.exec.5.html
PrivateTmp = false;
ProtectHome = true;
ReadOnlyPaths = "/";
ReadWritePaths = "/tmp";
InaccessiblePaths = "-/lost+found";
PrivateDevices = true;
PrivateUsers = true;
ProtectHostname = true;
ProtectClock = true;
ProtectKernelTunables = true;
ProtectKernelModules = true;
ProtectKernelLogs = true;
ProtectControlGroups = true;
LockPersonality = true;
MemoryDenyWriteExecute = true;
RestrictRealtime = true;
RestrictSUIDSGID = true;
};
};
};
};
# Backups
services.borgbackup.jobs.mail = {
paths = [

View file

@ -35,7 +35,7 @@ in {
proxy_interfaces = "130.83.2.184";
smtputf8_enable = "no"; # HRZ does not know SMTPUTF8
};
relayHost = "192.168.0.24"; # Relay to eihort which relays to HRZ (see https://www.hrz.tu-darmstadt.de/services/it_services/email_infrastruktur/index.de.jsp)
relayHost = "mathebau.de"; # Relay to mail vm which relays to HRZ (see https://www.hrz.tu-darmstadt.de/services/it_services/email_infrastruktur/index.de.jsp)
};
mailman = {
enable = true;
@ -64,9 +64,9 @@ in {
systemd.timers."mailAllowlist" = {
wantedBy = ["timers.target"];
timerConfig = {
OnBootSec = "5m"; # Run every 5 minutes
OnUnitActiveSec = "5m";
RandomizedDelaySec = "2m"; # prevent overload on regular intervals
OnBootSec = "1h"; # Run every hour
OnUnitActiveSec = "1h";
RandomizedDelaySec = "10m"; # prevent overload on regular intervals
Unit = "mailAllowlist.service";
};
};

27
patches/sieve-rs.patch Normal file
View file

@ -0,0 +1,27 @@
diff --git a/Cargo.lock b/Cargo.lock
index be36759b..b4316639 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -6404,8 +6404,7 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
[[package]]
name = "sieve-rs"
version = "0.6.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "15ac54053752c25a0e545dd1953de716abcc80b12cfe0b6c2f2c1c73759d4f45"
+source = "git+https://gitea.mathebau.de/fachschaft/sieve-rs.git#71324550504c0f84fe3e814d05cbe22f90a3b228"
dependencies = [
"ahash 0.8.11",
"bincode",
diff --git a/Cargo.toml b/Cargo.toml
index f055474f..2b64c9ac 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -63,3 +63,7 @@ incremental = false
debug-assertions = false
overflow-checks = false
rpath = false
+
+
+[patch.crates-io]
+sieve-rs = { git = 'https://gitea.mathebau.de/fachschaft/sieve-rs.git' }