diff options
Diffstat (limited to 'hosts')
-rw-r--r-- | hosts/surtr/email/default.nix | 58 | ||||
-rw-r--r-- | hosts/surtr/ruleset.nft | 31 |
2 files changed, 82 insertions, 7 deletions
diff --git a/hosts/surtr/email/default.nix b/hosts/surtr/email/default.nix index 057e29f3..23ac8aa1 100644 --- a/hosts/surtr/email/default.nix +++ b/hosts/surtr/email/default.nix | |||
@@ -32,9 +32,47 @@ let | |||
32 | }); | 32 | }); |
33 | }; | 33 | }; |
34 | 34 | ||
35 | nftables-nologin-script = pkgs.writeScript "nftables-mail-nologin" '' | ||
36 | #!${pkgs.zsh}/bin/zsh | ||
37 | |||
38 | set -e | ||
39 | export PATH="${lib.makeBinPath (with pkgs; [inetutils nftables])}:$PATH" | ||
40 | |||
41 | typeset -a as_sets route route6 | ||
42 | as_sets=(${lib.escapeShellArgs config.services.email.nologinASSets}) | ||
43 | |||
44 | for as_set in $as_sets; do | ||
45 | while IFS=$'\n' read line; do | ||
46 | if [[ "''${line}" =~ "^route:\s+(.+)$" ]]; then | ||
47 | route+=($match[1]) | ||
48 | elif [[ "''${line}" =~ "^route6:\s+(.+)$" ]]; then | ||
49 | route6+=($match[1]) | ||
50 | fi | ||
51 | done < <(whois -h whois.radb.net "!i''${as_set},1" | egrep -o 'AS[0-9]+' | xargs -- whois -h whois.radb.net -- -i origin) | ||
52 | done | ||
53 | |||
54 | printf -v elements4 '%s,' "''${route[@]}" | ||
55 | elements4=''${elements4%,} | ||
56 | printf -v elements6 '%s,' "''${route6[@]}" | ||
57 | elements6=''${elements6%,} | ||
58 | nft -f - <<EOF | ||
59 | flush set inet filter mail_nologin4 | ||
60 | flush set inet filter mail_nologin6 | ||
61 | add element inet filter mail_nologin4 {''${elements4}} | ||
62 | add element inet filter mail_nologin6 {''${elements6}} | ||
63 | EOF | ||
64 | ''; | ||
65 | |||
35 | spmDomains = ["bouncy.email"]; | 66 | spmDomains = ["bouncy.email"]; |
36 | emailDomains = spmDomains ++ ["kleen.consulting"]; | 67 | emailDomains = spmDomains ++ ["kleen.consulting"]; |
37 | in { | 68 | in { |
69 | options = { | ||
70 | services.email.nologinASSets = mkOption { | ||
71 | type = types.listOf types.str; | ||
72 | default = []; | ||
73 | }; | ||
74 | }; | ||
75 | |||
38 | config = { | 76 | config = { |
39 | nixpkgs.overlays = [ | 77 | nixpkgs.overlays = [ |
40 | (final: prev: { | 78 | (final: prev: { |
@@ -918,5 +956,25 @@ in { | |||
918 | id=REJECT_RL; action=450 4.7.1 Exceeding maximum of $$HIT_RATELIMIT_LIMIT recipients per $$HIT_RATELIMIT_INTERVAL seconds [$$HIT_RATECOUNT] | 956 | id=REJECT_RL; action=450 4.7.1 Exceeding maximum of $$HIT_RATELIMIT_LIMIT recipients per $$HIT_RATELIMIT_INTERVAL seconds [$$HIT_RATECOUNT] |
919 | ''; | 957 | ''; |
920 | }; | 958 | }; |
959 | |||
960 | services.email.nologinASSets = ["AS-MICROSOFT"]; | ||
961 | systemd.services.nftables.serviceConfig = { | ||
962 | ExecStart = lib.mkAfter [ nftables-nologin-script ]; | ||
963 | ExecReload = lib.mkAfter [ nftables-nologin-script ]; | ||
964 | }; | ||
965 | systemd.services."nftables-mail-nologin" = { | ||
966 | serviceConfig = { | ||
967 | Type = "oneshot"; | ||
968 | ExecStart = nftables-nologin-script; | ||
969 | }; | ||
970 | }; | ||
971 | systemd.timers."nftables-mail-nologin" = { | ||
972 | wantedBy = [ "nftables.service" ]; | ||
973 | |||
974 | timerConfig = { | ||
975 | OnActiveSec = "20h"; | ||
976 | RandomizedDelaySec = "8h"; | ||
977 | }; | ||
978 | }; | ||
921 | }; | 979 | }; |
922 | } | 980 | } |
diff --git a/hosts/surtr/ruleset.nft b/hosts/surtr/ruleset.nft index 14fc9b79..5c2bba7c 100644 --- a/hosts/surtr/ruleset.nft +++ b/hosts/surtr/ruleset.nft | |||
@@ -86,6 +86,7 @@ table inet filter { | |||
86 | 86 | ||
87 | counter established-rx {} | 87 | counter established-rx {} |
88 | 88 | ||
89 | counter reject-mail-nologin {} | ||
89 | counter reject-ratelimit-rx {} | 90 | counter reject-ratelimit-rx {} |
90 | counter reject-rx {} | 91 | counter reject-rx {} |
91 | counter reject-tcp-rx {} | 92 | counter reject-tcp-rx {} |
@@ -114,6 +115,17 @@ table inet filter { | |||
114 | 115 | ||
115 | counter tx {} | 116 | counter tx {} |
116 | 117 | ||
118 | set mail_nologin4 { | ||
119 | type ipv4_addr | ||
120 | flags interval | ||
121 | auto-merge | ||
122 | } | ||
123 | set mail_nologin6 { | ||
124 | type ipv6_addr | ||
125 | flags interval | ||
126 | auto-merge | ||
127 | } | ||
128 | |||
117 | chain forward { | 129 | chain forward { |
118 | type filter hook forward priority filter | 130 | type filter hook forward priority filter |
119 | policy drop | 131 | policy drop |
@@ -145,6 +157,14 @@ table inet filter { | |||
145 | counter name drop-fw | 157 | counter name drop-fw |
146 | } | 158 | } |
147 | 159 | ||
160 | chain reject_input { | ||
161 | limit name lim_reject log level debug prefix "drop input: " counter name reject-ratelimit-rx drop | ||
162 | log level debug prefix "reject input: " counter name reject-rx | ||
163 | meta l4proto tcp ct state new counter name reject-tcp-rx reject with tcp reset | ||
164 | ct state new counter name reject-icmp-rx reject | ||
165 | |||
166 | counter name drop-rx | ||
167 | } | ||
148 | chain input { | 168 | chain input { |
149 | type filter hook input priority filter | 169 | type filter hook input priority filter |
150 | policy drop | 170 | policy drop |
@@ -177,6 +197,9 @@ table inet filter { | |||
177 | udp dport {3478, 5349} counter name stun-rx accept | 197 | udp dport {3478, 5349} counter name stun-rx accept |
178 | udp dport 49000-50000 counter name turn-rx accept | 198 | udp dport 49000-50000 counter name turn-rx accept |
179 | 199 | ||
200 | tcp dport {465,466,993,4190} ip saddr @mail_nologin4 log prefix "mail nologin: " counter name reject-mail-nologin jump reject_input | ||
201 | tcp dport {465,466,993,4190} ip6 saddr @mail_nologin6 log prefix "mail nologin: " counter name reject-mail-nologin jump reject_input | ||
202 | |||
180 | tcp dport 25 counter name smtp-rx accept | 203 | tcp dport 25 counter name smtp-rx accept |
181 | tcp dport {465, 466} counter name submissions-rx accept | 204 | tcp dport {465, 466} counter name submissions-rx accept |
182 | tcp dport 993 counter name imaps-rx accept | 205 | tcp dport 993 counter name imaps-rx accept |
@@ -186,13 +209,7 @@ table inet filter { | |||
186 | ct state {established, related} counter name established-rx accept | 209 | ct state {established, related} counter name established-rx accept |
187 | 210 | ||
188 | 211 | ||
189 | limit name lim_reject log level debug prefix "drop input: " counter name reject-ratelimit-rx drop | 212 | jump reject_input |
190 | log level debug prefix "reject input: " counter name reject-rx | ||
191 | meta l4proto tcp ct state new counter name reject-tcp-rx reject with tcp reset | ||
192 | ct state new counter name reject-icmp-rx reject | ||
193 | |||
194 | |||
195 | counter name drop-rx | ||
196 | } | 213 | } |
197 | 214 | ||
198 | chain output { | 215 | chain output { |