nyarlathotep: cleanup after deployment #55
|
@ -75,6 +75,18 @@
|
|||
group = "stalwart-mail";
|
||||
mode = "0440";
|
||||
};
|
||||
"dkim_rsa" = {
|
||||
sopsFile = ./dkim.keys.yaml;
|
||||
Gonne marked this conversation as resolved
Outdated
|
||||
owner = "stalwart-mail";
|
||||
group = "stalwart-mail";
|
||||
mode = "0440";
|
||||
};
|
||||
"dkim_ed25519" = {
|
||||
sopsFile = ./dkim.keys.yaml;
|
||||
Gonne marked this conversation as resolved
Outdated
nerf
commented
see below see below
|
||||
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.secrets.yaml;
|
||||
|
|
40
nixos/machines/nyarlathotep/dkim.keys.yaml
Normal file
|
@ -0,0 +1,40 @@
|
|||
dkim_rsa: ENC[AES256_GCM,data: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,iv:QbZVXp5FQhmYZvXxXNxWKrNm5GqM+2P3a5pPk499mlc=,tag:F+KNoPRnoLLhOpEj6Czj6Q==,type:str]
|
||||
Gonne marked this conversation as resolved
Outdated
nerf
commented
can this file be called can this file be called `<something>.secrets.yaml`?
|
||||
dkim_ed25519: ENC[AES256_GCM,data:cZHm7bVpQ/VhYLt2CnNk9364k+J5ybgSLrR7Vm1GsCU6JcAvHl8Y5R7mqwgS+gTnHX7K02GuIGXa8909/aEotE0ZMY5irKJ25SGJqTaqQafbiMOz65CRQh5trtcMBF4s4wRYOkDGgz09KkELbkDHyQZFcrGqvgM=,iv:p9ROj/epqR3xtrimXF1onJJHH9JUqNG9z1MxKVu9uPg=,tag:m53rXkcu+ernS5JX+k8YcA==,type:str]
|
||||
sops:
|
||||
kms: []
|
||||
gcp_kms: []
|
||||
azure_kv: []
|
||||
hc_vault: []
|
||||
age:
|
||||
- recipient: age1rasjnr2tlv9y70sj0z0hwpgpxdc974wzg5umtx2pnc6z0p05u3js6r8sln
|
||||
enc: |
|
||||
-----BEGIN AGE ENCRYPTED FILE-----
|
||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB6VnhvWHdsZWNHemlueFo4
|
||||
L0xCTGp4NlRuU3YwRWJiSHFBbmtURTNMQkVRCnlSbFc0Q2xINjRvU2tQeStQc1U5
|
||||
VElxcTVuNm9MUm01RkpGYytrYWg0czgKLS0tIHZqUWhkMGRNNjJvUTQrOHBpZXVS
|
||||
NlpjeDQxbVZIRHFCcmNtT1JSVHp1K2sKSNcC0fcOar/KKzs1twaozB8wfdFT9OdB
|
||||
4quV/ycNpJpfs6+2r0RTLBxYFyusybu1swosAni+PJsRXS82+PTXHQ==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
- recipient: age1epz92k2rkp43hkrg3u0jgkzhnkwx8y43kag7rvfzwl9wcddelvusyetxl7
|
||||
enc: |
|
||||
-----BEGIN AGE ENCRYPTED FILE-----
|
||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBsUTUzYzZuMkYvcTlrUmRK
|
||||
aStnak5IWitFUSt0eVBQOHIzcTlrMFRFTjA4CmlYUTdobXFUK2tYMWtFekNqNnhp
|
||||
R2RRRFdHc1p6bFVjYU9lbTRBeEM3Y2sKLS0tIHdsRW1wR25pVkZIYU1yMm9sQXpr
|
||||
NFhiN0pyaHVWT1h5eVFXMWZDb0sxUGMKIVkYYheD8F9aaAyCA+m9ZGlV8vKbAW4r
|
||||
H6FUe+ats30abxoYfHZfMJv17BxJtpodksSxWjnPYm0dfRf/EF/vSQ==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
- recipient: age1ktwclxa640l89le6yecm8v2z6hmwr4lusd6x9gyzamhv57887szqtqp59a
|
||||
enc: |
|
||||
-----BEGIN AGE ENCRYPTED FILE-----
|
||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBvU3NzY0Uxc0NhY2xJZyti
|
||||
TCtTS1crV3hzMXZNV3k4cm0zUFNuY2tBL0dNCnNpYytoaUI1eERhdG1PUlZ2eE5C
|
||||
R2UrVlBwcXR2L1VNR3RJL1lEQmlTSDgKLS0tIFJyLzhZeG5zejFmL2VkYy8xVEM1
|
||||
U3QwOXlRdU8yd3ozL2hUVzRXNGE0bDQKT7SLAqICsbFmRUF+3s2avpBt0dLUbHLX
|
||||
AgQzx5v6GpMMNwCkCrOnpFX6al7zkRSYHe7hbn03BBORz9mPHek5ew==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
lastmodified: "2025-03-02T07:58:00Z"
|
||||
mac: ENC[AES256_GCM,data:OvERjDFfHTJbTfwq9BmXBQy6pjeyIhao6zP4we0KeYL3skbw4+aaMixjUFzjauby0C7nJjEPBSk6pwK3lN+rScS5g7J8tTNtmhfEDQbfsS5zNDKzIQjYxbUbDr2cTPWwCA73gRGMwLbyNvdfuEp46jNV8OJ8km/y2nyG9lDcBb4=,iv:0RSU2MdZWiYEapwXGzevP9/vc/Sk1MS6a0MnCRQyIs8=,tag:vvngXS2IRzH999yzo4JyFQ==,type:str]
|
||||
pgp: []
|
||||
unencrypted_suffix: _unencrypted
|
||||
version: 3.9.4
|
|
@ -108,6 +108,15 @@ in {
|
|||
iprev.verify = "relaxed";
|
||||
spf.verify.ehlo = "relaxed";
|
||||
spf.verify.mail-from = "relaxed";
|
||||
|
||||
# Sign *our* outgoing mails with the configured signatures.
|
||||
dkim.sign = [
|
||||
{
|
||||
"if" = "is_local_domain('', sender_domain) || sender_domain == 'lists.mathebau.de'";
|
||||
"then" = "['rsa-' + sender_domain, 'ed25519-' + sender_domain]";
|
||||
}
|
||||
{"else" = false;}
|
||||
];
|
||||
};
|
||||
|
||||
# Forward outgoing mail to HRZ or mail VMs.
|
||||
|
@ -202,12 +211,53 @@ in {
|
|||
sieve.trusted.from-addr = "sender"; # set the from-address to the original sender as specified in the MAIL FROM.
|
||||
sieve.trusted.from-name = "sender";
|
||||
sieve.trusted.return-path = "sender";
|
||||
# If we are the sender, we sign the message with DKIM. Else we leave it alone.
|
||||
sieve.trusted.sign = [
|
||||
{
|
||||
Gonne marked this conversation as resolved
Outdated
nerf
commented
maybe we should move this file from maybe we should move this file from `/tmp` into the `/run` directory as this usually has proper
file access rights set up.
Gonne
commented
There is also Reading https://lwn.net/Articles/436012/ I have no idea whether There is also `JoinsNamespaceOf` for `PrivateTmp` of systemd service units (https://www.man7.org/linux/man-pages/man5/systemd.exec.5.html) but I didn't succeed setting it.
Reading https://lwn.net/Articles/436012/ I have no idea whether `/run` is a better place.
nerf
commented
We don't care about the early boot discussion. So the question is, is it runtime date or temporary data, wherever the boundary between these two is. Putting things in If we already follow Lennart's advice then we also should use So after reading all of this maybe the cleanest option is to get the We don't care about the early boot discussion. So the question is, is it runtime date or temporary data, wherever the boundary between these two is. Putting things in `/tmp` is often a buggy mess as this directory is usually somewhat of a global dumpster fire, where there are no guarantees that this file does not already exist with some important information for some other process (though unlikely). `PrivateTmp` would save us here, but even the documentation says that one should not rely on this (and we would need to get it to work).
If we already follow Lennart's advice then we also should use `mkstemp` to generate files in `/tmp` which will
be very painful in a nix setting (as paths and filenames will only be available at runtime). Lennart also seems to think that `/run` is primarily for communication primitives (is this one?).
See [his blogpost](https://0pointer.net/blog/projects/tmp.html).
So after reading all of this maybe the cleanest option is to get the `JoinNamespaceOf` option to work?
Gonne
commented
I got the private I got the private `/tmp` with `JoinsNamespaceOf` working.
|
||||
"if" = "is_local_domain('', sender_domain) || sender_domain == 'lists.mathebau.de'";
|
||||
Gonne marked this conversation as resolved
Outdated
nerf
commented
the the `trusted` part is to much, also see the comment at `from-name` below
|
||||
"then" = "['rsa-' + sender_domain, 'ed25519-' + sender_domain]";
|
||||
Gonne marked this conversation as resolved
Outdated
nerf
commented
I couldn't figure out what I couldn't figure out what `from-name` or `from-addr` actually do. Reading the documentation I believe combined they
set the default value for the `From:` header of a generated mail. But I couldn't verify this in tests.
Maybe it does something different that has to do with the `MAIL FROM:` see comment below
nerf marked this conversation as resolved
nerf
commented
where did the where did the `/tmp` folder discussion disappeared to?
nerf
commented
ahh it got marked outdated ahh it got marked outdated
|
||||
}
|
||||
Gonne marked this conversation as resolved
Outdated
nerf
commented
This seems to do what we want, even though the documentation reads like it sets the This seems to do what we want, even though the documentation reads like it sets the `Return-Path:` header. But it seems to set the reverse path (which is the argument to the `MAIL FROM:` smtp command). Maybe it does both?
nerf
commented
This parameter seems to control the This parameter seems to control the `MAIL FROM:` and with this all the headers we want to set.
The documentation reads to me as if it sets the `Return-Path:` header. I'm unsure if it actually does it.
|
||||
{"else" = false;}
|
||||
];
|
||||
sieve.trusted.limits = {
|
||||
redirects = 50;
|
||||
out-messages = 50;
|
||||
};
|
||||
session.data.script = "'redirects'";
|
||||
|
||||
# See https://stalw.art/docs/smtp/authentication/dkim/sign
|
||||
# We need two blocks per domain because the domain setting in the blocks does not accept variables like `sender_domain`.
|
||||
signature = let
|
||||
signatureTemplate = domain: {
|
||||
"rsa-${domain}" = {
|
||||
private-key = "%{file:/run/secrets/dkim_rsa}%";
|
||||
domain = "${domain}";
|
||||
selector = "rsa-default";
|
||||
headers = ["From" "To" "Cc" "Date" "Subject" "Message-ID" "Organization" "MIME-Version" "Content-Type" "In-Reply-To" "References" "List-Id" "User-Agent" "Thread-Topic" "Thread-Index"];
|
||||
algorithm = "rsa-sha256";
|
||||
canonicalization = "relaxed/relaxed";
|
||||
};
|
||||
"ed25519-${domain}" = {
|
||||
Gonne marked this conversation as resolved
nerf
commented
I will just trust you on the header selection I will just trust you on the header selection
|
||||
private-key = "%{file:/run/secrets/dkim_ed25519}%";
|
||||
domain = "${domain}";
|
||||
selector = "ed-default";
|
||||
headers = ["From" "To" "Cc" "Date" "Subject" "Message-ID" "Organization" "MIME-Version" "Content-Type" "In-Reply-To" "References" "List-Id" "User-Agent" "Thread-Topic" "Thread-Index"];
|
||||
algorithm = "ed25519-sha256";
|
||||
canonicalization = "relaxed/relaxed";
|
||||
};
|
||||
};
|
||||
in
|
||||
map signatureTemplate (["lists.mathebau.de"] ++ (map ({domain, ...}: domain) cfg.domains));
|
||||
|
||||
# Sign *our* outgoing mails with the configured signatures.
|
||||
auth.dkim.sign = [
|
||||
{
|
||||
"if" = "is_local_domain('', sender_domain) || sender_domain == 'lists.mathebau.de'";
|
||||
"then" = "['rsa-' + sender_domain, 'ed25519-' + sender_domain]";
|
||||
}
|
||||
{"else" = false;}
|
||||
];
|
||||
|
||||
authentication.fallback-admin = {
|
||||
user = "admin";
|
||||
# see passwd on azathoth for plaintext or machine secret in encoded format for HTTP Basic AUTH
|
||||
|
|
see below