diff --git a/systems/LoutreOS/network.nix b/systems/LoutreOS/network.nix index 141298b..4c51361 100644 --- a/systems/LoutreOS/network.nix +++ b/systems/LoutreOS/network.nix @@ -2,7 +2,12 @@ { boot = { - kernel.sysctl."net.ipv6.conf.all.forwarding" = true; + kernel.sysctl = { + "net.ipv6.conf.all.forwarding" = true; + "net.ipv6.conf.default.forwarding" = true; + "net.ipv4.conf.all.forwarding" = true; + "net.ipv4.conf.default.forwarding" = true; + }; }; # Enable LTE drivers @@ -52,18 +57,6 @@ enp0s21u1.useDHCP = true; }; - # NAT bouygues <-> eno2 - nat = { - enable = true; - externalInterface = "bouygues"; - internalIPs = [ "10.30.0.0/16" ]; - internalInterfaces = [ "eno2" ]; - forwardPorts = [ - { destination = "10.30.0.1:22"; proto = "tcp"; sourcePort = 8443;} - { destination = "10.30.135.35:25565"; proto = "tcp"; sourcePort = 25565; loopbackIPs=[ "195.36.180.44" ];} - ]; - }; - firewall = { enable = true; allowedTCPPorts = [ 80 443 ]; @@ -84,21 +77,59 @@ }; extraCommands = '' + + ################ + # MANGLE rules # + ################ + + # Clean and recreate target + ip46tables -w -t mangle -D PREROUTING -j loutreos-mangle-pre 2>/dev/null || true + ip46tables -w -t mangle -F loutreos-mangle-pre 2>/dev/null || true + ip46tables -w -t mangle -X loutreos-mangle-pre 2>/dev/null || true + ip46tables -w -t mangle -N loutreos-mangle-pre + + # Restore the packet's CONNMARK to the MARK for existing connections + ip46tables -w -t mangle -A loutreos-mangle-pre -j CONNMARK --restore-mark + + # If packet MARK is set, then it means that there is already a connection mark + ip46tables -w -t mangle -A loutreos-mangle-pre -m mark ! --mark 0 -j ACCEPT + + # Else, we need to mark the packet. + # If the packet is incoming on bouygues then set MARK to 1, LTE MARK 2 and VPN MARK 3 + ip46tables -w -t mangle -A loutreos-mangle-pre -i bouygues -j MARK --set-mark 1 + ip46tables -w -t mangle -A loutreos-mangle-pre -i enp0s21u1 -j MARK --set-mark 2 + ip46tables -w -t mangle -A loutreos-mangle-pre -i wg0 -j MARK --set-mark 3 + + # Jump to newly created target + ip46tables -w -t mangle -A PREROUTING -j loutreos-mangle-pre + + # Save MARK to CONNMARK. + ip46tables -w -t mangle -D POSTROUTING -j CONNMARK --save-mark 2>/dev/null || true + ip46tables -w -t mangle -A POSTROUTING -j CONNMARK --save-mark + + ###################### + # IPv6 FORWARD rules # + ###################### + # Forward all IPv6 traffic from local network and reject incoming traffic ip6tables -w -D FORWARD -j loutreos-forward 2>/dev/null || true ip6tables -w -F loutreos-forward 2>/dev/null || true ip6tables -w -X loutreos-forward 2>/dev/null || true ip6tables -w -N loutreos-forward - ip6tables -A loutreos-forward -m state --state RELATED,ESTABLISHED -j ACCEPT - ip6tables -A loutreos-forward -j ACCEPT -i eno2 - ip6tables -A loutreos-forward -j nixos-fw-log-refuse + ip6tables -w -A loutreos-forward -m state --state RELATED,ESTABLISHED -j ACCEPT + ip6tables -w -A loutreos-forward -j ACCEPT -i eno2 + ip6tables -w -A loutreos-forward -j nixos-fw-log-refuse ip6tables -w -A FORWARD -j loutreos-forward + ############################################# + # Enable server access when fiber link down # + ############################################# + # Redirect local network request from server external IP to internal IP - # Make the server available even without internet access iptables -t nat -D PREROUTING -s 10.30.0.0/16 -d 176.180.172.105 -j DNAT --to 10.30.0.1 || true iptables -t nat -A PREROUTING -s 10.30.0.0/16 -d 176.180.172.105 -j DNAT --to 10.30.0.1 ''; + # remove refs to nixos-fw-log-refuse before restarting firewall # prevents "ressource busy" errors extraStopCommands = '' @@ -114,8 +145,24 @@ ]; }; + ################# + # ROUTING RULES # + ################# + + # 0: from all lookup local + # 60: from all iif lo dport 25 lookup vpn # mails are forced to vpn table + # 32766: from all lookup main # main table should contain no default routes, only local network routes + # 32767: from all lookup default + # 41000: from all fwmark 0x1 lookup fiber # fwmark indicate established connection that must go through same interface + # 42000: from all fwmark 0x2 lookup lte + # 43000: from all fwmark 0x3 lookup vpn + # 51000: from all lookup fiber # first table encountered with a default route if fiber is up + # 52000: from all lookup lte # first table encountered with a default route if fiber is down + systemd.network = let routeTables = { + fiber = 1; + lte = 2; vpn = 3; }; in { @@ -164,14 +211,17 @@ # Set route metric to highest priority # Set DHCP client magic settings for Bouygues "40-bouygues" = { - dhcpV4Config.RouteMetric = 1; + dhcpV4Config.RouteTable = routeTables.fiber; dhcpV6Config = { DUIDRawData = "00:03:00:01:E8:AD:A6:21:73:68"; WithoutRA = "solicit"; }; - ipv6AcceptRAConfig.DHCPv6Client = true; + ipv6AcceptRAConfig = { + DHCPv6Client = true; + RouteTable = routeTables.fiber; + }; networkConfig = { KeepConfiguration = "dhcp-on-stop"; @@ -181,6 +231,25 @@ # Static attribution of first IPv6 subnet dhcpPrefixDelegationConfig.SubnetId = "0"; + + # Route everything to fiber link with a priority of 40000 + routingPolicyRules = [ + { + routingPolicyRuleConfig = { + FirewallMark = 1; + Table = routeTables.fiber; + Priority = 41000; + Family = "both"; + }; + } + { + routingPolicyRuleConfig = { + Table = routeTables.fiber; + Priority = 51000; + Family = "both"; + }; + } + ]; }; # Don't check VLAN physical interface as it is not directly used @@ -191,21 +260,39 @@ ####### # Set LTE route to lower priority - "40-enp0s21u1".dhcpV4Config.RouteMetric = 1024; + "40-enp0s21u1" = { + dhcpV4Config.RouteTable = routeTables.lte; + + # Route all to lte link with a priority of 50000 + routingPolicyRules = [ + { + routingPolicyRuleConfig = { + FirewallMark = 2; + Table = routeTables.lte; + Priority = 42000; + Family = "both"; + }; + } + { + routingPolicyRuleConfig = { + Table = routeTables.lte; + Priority = 52000; + Family = "both"; + }; + } + ]; + }; ####### # VPN # ####### # Wireguard ARN network configuation - "10-wg0" = let - vpnIPv4 = "89.234.141.196/32"; - vpnIPv6 = "2a00:5881:8119:400::1/128"; - in { + "10-wg0" = { matchConfig.Name = "wg0"; address = [ - vpnIPv4 - vpnIPv6 + "89.234.141.196/32" + "2a00:5881:8119:400::1/128" ]; routingPolicyRules = [ # Route outgoing emails to VPN table @@ -214,7 +301,7 @@ IncomingInterface = "lo"; DestinationPort = "25"; Table = routeTables.vpn; - Priority = 50; + Priority = 60; Family = "both"; }; } @@ -222,16 +309,10 @@ # Allow server to respond on the wg0 interface requests { routingPolicyRuleConfig = { - From = vpnIPv4; + FirewallMark = 3; Table = routeTables.vpn; - Priority = 49; - }; - } - { - routingPolicyRuleConfig = { - From = vpnIPv6; - Table = routeTables.vpn; - Priority = 49; + Priority = 43000; + Family = "both"; }; } ]; @@ -247,6 +328,7 @@ IPv6SendRA = true; DHCPPrefixDelegation = true; DHCPServer = true; + IPMasquerade = "ipv4"; }; dhcpServerConfig = { EmitRouter = true;