From 4f650b2091257af54f890b1f5f05bed7df1eef6e Mon Sep 17 00:00:00 2001 From: chayleaf Date: Sun, 13 Aug 2023 16:40:21 +0700 Subject: [PATCH] router: small port 25 changes technically this is relevant for security since it blocks requests to port 25 over ipv6 from clients other than the server, but it doesn't matter on my network because i don't have ipv6 --- system/hosts/router/default.nix | 37 ++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/system/hosts/router/default.nix b/system/hosts/router/default.nix index bd19787..04fc665 100644 --- a/system/hosts/router/default.nix +++ b/system/hosts/router/default.nix @@ -58,6 +58,15 @@ let else if rule.target4.address or null == netAddresses.lan4 || rule.target6.address or null == netAddresses.lan6 then "rule" else "mark"; + dnatRuleProtos = rule: + let + inherit (notnft.inetProtos) tcp udp; + in + if rule.tcp && rule.udp then notnft.dsl.set [ tcp udp ] + else if rule.tcp then tcp + else if rule.udp then udp + else throw "Invalid rule: either tcp or udp must be set"; + # nftables rules generator # selfIp4/selfIp6 = block packets from these addresses # extraInetEntries = stuff to add to inet table @@ -463,8 +472,7 @@ in { inetDnatRules = builtins.concatLists (map (rule: let - inherit (notnft.inetProtos) tcp udp; - protocols = if rule.tcp && rule.udp then notnft.dsl.set [ tcp udp ] else if rule.tcp then tcp else udp; + protocols = dnatRuleProtos rule; rule4 = rule.target4; rule6 = rule.target6; in with notnft.dsl; with payload; lib.optionals (rule4 != null) [ @@ -521,22 +529,20 @@ in { [(is.eq ip6.daddr "@force_unvpn6") (mangle meta.mark wan_table)] [(is.eq ip.saddr "@force_unvpn4") (mangle meta.mark wan_table)] [(is.eq ip6.saddr "@force_unvpn6") (mangle meta.mark wan_table)] - # block requests to port 25 from hosts other than the server so they can't send mail pretending to originate from my domain - # only do this for br0 since other adapters aren't forwarded from - [(is.eq meta.iifname "br0") (is.ne ether.saddr cfg.serverMac) (is.eq ip.protocol (f: f.tcp)) (is.eq tcp.dport 25) (log "smtp ") drop] - # don't vpn smtp requests so spf works fine (and in case the vpn blocks requests over port 25, which it usually does) - [(is.eq ip.protocol (f: f.tcp)) (is.eq tcp.dport 25) (mangle meta.mark wan_table)] - [(is.eq ip6.nexthdr (f: f.tcp)) (is.eq tcp.dport 25) (mangle meta.mark wan_table)] - # finally, force vpn to/from force_vpn4/force_vpn6 even if we previously decided to unvpn this connection + # force vpn to/from force_vpn4/force_vpn6 even if we previously decided to unvpn this connection [(is.eq ip.daddr "@force_vpn4") (mangle meta.mark vpn_table)] [(is.eq ip6.daddr "@force_vpn6") (mangle meta.mark vpn_table)] [(is.eq ip.saddr "@force_vpn4") (mangle meta.mark vpn_table)] [(is.eq ip6.saddr "@force_vpn6") (mangle meta.mark vpn_table)] + # block requests to port 25 from hosts other than the server so they can't send mail pretending to originate from my domain + # only do this for br0 since traffic from other interfaces isn't forwarded to wan + [(is.eq meta.iifname "br0") (is.ne ether.saddr cfg.serverMac) (is.eq meta.l4proto (f: f.tcp)) (is.eq tcp.dport 25) (log "smtp ") drop] + # don't vpn smtp requests so spf works fine (and in case the vpn blocks requests over port 25, which it usually does) + [(is.eq meta.l4proto (f: f.tcp)) (is.eq tcp.dport 25) (mangle meta.mark wan_table)] ] ++ # 1. dnat non-vpn: change rttable to wan builtins.concatLists (map (rule: let - inherit (notnft.inetProtos) tcp udp; - protocols = if rule.tcp && rule.udp then notnft.dsl.set [ tcp udp ] else if rule.tcp then tcp else udp; + protocols = dnatRuleProtos rule; rule4 = rule.target4; rule6 = rule.target6; in with notnft.dsl; with payload; lib.optionals (rule4 != null) [ @@ -550,8 +556,7 @@ in { ++ # 2. dnat vpn: change rttable to vpn builtins.concatLists (map (rule: let - inherit (notnft.inetProtos) tcp udp; - protocols = if rule.tcp && rule.udp then notnft.dsl.set [ tcp udp ] else if rule.tcp then tcp else udp; + protocols = dnatRuleProtos rule; rule4 = rule.target4; rule6 = rule.target6; in with notnft.dsl; with payload; lib.optionals (rule4 != null) [ @@ -640,8 +645,7 @@ in { inetDnatRules = builtins.concatLists (map (rule: let - inherit (notnft.inetProtos) tcp udp; - protocols = if rule.tcp && rule.udp then notnft.dsl.set [ tcp udp ] else if rule.tcp then tcp else udp; + protocols = dnatRuleProtos rule; rule4 = rule.target4; rule6 = rule.target6; in with notnft.dsl; with payload; lib.optionals (rule4 != null) [ @@ -657,8 +661,7 @@ in { # if i ever need this again, i have it right here builtins.concatLists (map (rule: let - inherit (notnft.inetProtos) tcp udp; - protocols = if rule.tcp && rule.udp then notnft.dsl.set [ tcp udp ] else if rule.tcp then tcp else udp; + protocols = dnatRuleProtos rule; rule4 = rule.target4; rule6 = rule.target6; in with notnft.dsl; with payload; lib.optionals (rule4 != null) [