aboutsummaryrefslogtreecommitdiff
path: root/flakes/private/mail-relay
diff options
context:
space:
mode:
Diffstat (limited to 'flakes/private/mail-relay')
-rwxr-xr-xflakes/private/mail-relay/filter-rewrite-from.py68
-rw-r--r--flakes/private/mail-relay/flake.lock36
-rw-r--r--flakes/private/mail-relay/flake.nix58
3 files changed, 162 insertions, 0 deletions
diff --git a/flakes/private/mail-relay/filter-rewrite-from.py b/flakes/private/mail-relay/filter-rewrite-from.py
new file mode 100755
index 0000000..aad9c69
--- /dev/null
+++ b/flakes/private/mail-relay/filter-rewrite-from.py
@@ -0,0 +1,68 @@
1#! /usr/bin/env python3
2import sys
3
4sys.stdin.reconfigure(encoding='utf-8')
5sys.stdout.reconfigure(encoding='utf-8')
6stdin = sys.stdin
7stdout = sys.stdout
8
9mailaddr = sys.argv[1]
10inheader = {}
11
12# Change to actual file for logging
13logfile = open("/dev/null", "a")
14
15def log(l, i):
16 logfile.write("{} {}\n".format(i, l))
17 logfile.flush()
18
19def send(l):
20 log(l, ">")
21 stdout.write("{}\n".format(l))
22 stdout.flush()
23
24def token_and_sid(version, sid, token):
25 if version < "0.5":
26 return "{}|{}".format(token, sid)
27 else:
28 return "{}|{}".format(sid, token)
29
30log("started", "l")
31while True:
32 line = stdin.readline().strip()
33 log(line, "<")
34 if not line:
35 log("finished", "l")
36 break
37 splitted = line.split("|")
38 if line == "config|ready":
39 log("in config ready", "l")
40 send("register|filter|smtp-in|mail-from")
41 send("register|filter|smtp-in|data-line")
42 send("register|ready")
43 if splitted[0] != "filter":
44 continue
45 if len(splitted) < 7:
46 send("invalid filter command: expected >6 fields!")
47 sys.exit(1)
48 version = splitted[1]
49 action = splitted[4]
50 sid = splitted[5]
51 token = splitted[6]
52 token_sid = token_and_sid(version, sid, token)
53 rest = "|".join(splitted[7:])
54 if action == "mail-from":
55 inheader[sid] = True
56 send("filter-result|{}|rewrite|<{}>".format(token_sid, mailaddr))
57 continue
58 if action == "data-line":
59 if rest == "" and inheader.get(sid, False):
60 inheader[sid] = False
61 if rest == "." and not inheader.get(sid):
62 del(inheader[sid])
63 if inheader.get(sid, False) and rest.upper().startswith("FROM:"):
64 send("filter-dataline|{}|From: {}".format(token_sid, mailaddr))
65 else:
66 send("filter-dataline|{}|{}".format(token_sid, rest))
67 continue
68 send("filter-result|{}|proceed".format(token_sid))
diff --git a/flakes/private/mail-relay/flake.lock b/flakes/private/mail-relay/flake.lock
new file mode 100644
index 0000000..bbb2011
--- /dev/null
+++ b/flakes/private/mail-relay/flake.lock
@@ -0,0 +1,36 @@
1{
2 "nodes": {
3 "environment": {
4 "locked": {
5 "lastModified": 1,
6 "narHash": "sha256-rMKbM7fHqWQbI7y59BsPG8KwoDj2jyrvN2niPWB24uE=",
7 "path": "../environment",
8 "type": "path"
9 },
10 "original": {
11 "path": "../environment",
12 "type": "path"
13 }
14 },
15 "root": {
16 "inputs": {
17 "environment": "environment",
18 "secrets": "secrets"
19 }
20 },
21 "secrets": {
22 "locked": {
23 "lastModified": 1,
24 "narHash": "sha256-5AakznhrJFmwCD7lr4JEh55MtdAJL6WA/YuBks6ISSE=",
25 "path": "../../secrets",
26 "type": "path"
27 },
28 "original": {
29 "path": "../../secrets",
30 "type": "path"
31 }
32 }
33 },
34 "root": "root",
35 "version": 7
36}
diff --git a/flakes/private/mail-relay/flake.nix b/flakes/private/mail-relay/flake.nix
new file mode 100644
index 0000000..639bd06
--- /dev/null
+++ b/flakes/private/mail-relay/flake.nix
@@ -0,0 +1,58 @@
1{
2 inputs.environment.url = "path:../environment";
3 inputs.secrets.url = "path:../../secrets";
4
5 outputs = { self, environment, secrets }: {
6 nixosModule = self.nixosModules.mail-relay;
7 nixosModules.mail-relay = { lib, pkgs, config, name, ... }:
8 {
9 imports = [
10 environment.nixosModule
11 secrets.nixosModule
12 ];
13 options.myServices.mailRelay.enable = lib.mkEnableOption "enable Mail relay services";
14 config = lib.mkIf config.myServices.mailRelay.enable {
15 secrets.keys."opensmtpd/creds" = {
16 user = "smtpd";
17 group = "smtpd";
18 permissions = "0400";
19 text = ''
20 eldiron ${name}:${config.hostEnv.ldap.password}
21 '';
22 };
23 users.users.smtpd.extraGroups = [ "keys" ];
24 services.opensmtpd = {
25 enable = true;
26 serverConfiguration = let
27 filter-rewrite-from = pkgs.runCommand "filter-rewrite-from.py" {
28 buildInputs = [ pkgs.python38 ];
29 } ''
30 cp ${./filter-rewrite-from.py} $out
31 patchShebangs $out
32 '';
33 in ''
34 table creds \
35 "${config.secrets.fullPaths."opensmtpd/creds"}"
36 # FIXME: filtering requires 6.6, uncomment following lines when
37 # upgrading
38 # filter "fixfrom" \
39 # proc-exec "${filter-rewrite-from} ${name}@immae.eu"
40 # listen on socket filter "fixfrom"
41 action "relay-rewrite-from" relay \
42 helo ${config.hostEnv.fqdn} \
43 host smtp+tls://eldiron@eldiron.immae.eu:587 \
44 auth <creds> \
45 mail-from ${name}@immae.eu
46 action "relay" relay \
47 helo ${config.hostEnv.fqdn} \
48 host smtp+tls://eldiron@eldiron.immae.eu:587 \
49 auth <creds>
50 match for any !mail-from "@immae.eu" action "relay-rewrite-from"
51 match for any mail-from "@immae.eu" action "relay"
52 '';
53 };
54 environment.systemPackages = [ config.services.opensmtpd.package ];
55 };
56 };
57 };
58}