summaryrefslogtreecommitdiffhomepage
path: root/ci/ios/test-router/nftables.nix
blob: 41e78f1e4591361306578c32902f4d3aa0b0ab9d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
{ lib, config, ... }:
with lib; let
  cfg = config.services.nftables;
in
{
  options.services.nftables.internetHostOverride = mkOption {
    type = types.str;
    default = false;
    description = ''
      Gateway address to which traffic to 8.8.8.8:80 will be forwarded to.
    '';
  };

  options.services.nftables.lanInterfaces = mkOption {
    type = types.str;
    default = false;
    description = ''
      A string representing the interfaces on the LAN side of the network.
    '';
  };

  config.systemd.services.nftables = {
    before = lib.mkForce [ ];
    bindsTo = [
      "sys-subsystem-net-devices-wan.device"
      "sys-subsystem-net-devices-lan.device"
    ];
    after = [
      "systemd-networkd.service"
      "sys-subsystem-net-devices-wan.device"
      "sys-subsystem-net-devices-lan.device"
    ];
  };

  config.networking.nftables = {
    enable = true;
    preCheckRuleset = ''
      sed 's/lan/lo/g' -i ruleset.conf
      sed 's/wan/lo/g' -i ruleset.conf
      sed 's/wifi/lo/g' -i ruleset.conf
    '';
    ruleset = ''
      table inet filter {
        chain output {
          type filter hook output priority 100; policy accept;
        }


        chain input {
           type filter hook input priority filter; policy drop;

           # allow reaching systemd-resolve
           ip saddr 127.0.0.1 ip daddr 127.0.0.53 accept
           iifname lo accept;
           oifname lo accept;
           # Allow trusted networks to access the router
           iifname { lan } counter accept;
           # Allow WiFi clients reach the following:
           # - DNS
           # - DHCP
           # - DHCPv6
           iifname { wan, ${cfg.lanInterfaces} } udp dport 53 counter accept
           iifname { wan, ${cfg.lanInterfaces} } tcp dport 53 counter accept
           iifname { wifi } udp sport 68 udp dport 67 counter accept
           iifname { wifi } ip6 saddr fe80::/10 udp sport 546 ip6 daddr fe80::/10 udp dport 547 accept

           iifname wan meta nfproto ipv6 accept


           # allow SSH from WAN
           iifname "wan" tcp dport 2021 counter accept
           # allow WG from WAN
           iifname "wan" udp dport 6070 counter accept


           # allow random traffic for testing purposes
           iifname "wan" udp dport {9090, 9091} counter accept
           iifname "wan" tcp dport {9090, 9091} counter accept

           iifname { "wan", "staging" } ct state vmap { established : accept, related : accept, invalid : drop }
           iifname "wan" udp sport 67 udp dport 68 counter accept;
           iifname "wan" ip6 saddr fe80::/10 udp sport 547 ip6 daddr fe80::/10 udp dport 546 counter accept

           icmpv6 code no-route counter accept
           iifname "wan" icmpv6 mtu > 0 counter accept comment "Allow ALL ICMP from wan"
           icmpv6 type { nd-neighbor-solicit, nd-router-advert, nd-neighbor-advert } counter accept

        }

        chain forward {
          type filter hook forward priority filter; policy drop;

          ip daddr 192.168.0.0/23 drop

          # offload established HTTP connections
          # ip protocol { tcp, udp } ct state established flow offload @internetNat counter

          # Allow traffic from established and related packets, drop invalid
          ct state vmap { established : accept, related : accept, invalid : drop }

          # Allow trusted network WAN access
          iifname {
                  lo, ${cfg.lanInterfaces}
          } oifname {
                  "wan", "staging"
          } counter accept comment "Allow trusted LAN to WAN and staging interface"

          iifname "lan" oifname "wifi" counter accept comment "Allow LAN to IoS WiFi"

          # Allow established WAN to return
          iifname { "wan", "wifi" } oifname { ${cfg.lanInterfaces} } ct state established,related counter accept comment "Allow established back to LANs"
          iifname {"wan", "staging" } oifname { "lan", "wifi"} ct mark 1919 accept comment "Allow DNAtted traffic"
        }

        chain srcnat {
          type nat hook postrouting priority srcnat; policy accept;
          iifname { ${cfg.lanInterfaces} }  masquerade comment "Masquerade all traffic"
        }

        chain dstnat {
          type nat hook prerouting priority dstnat; policy accept;
          ip daddr 8.8.8.8 tcp dport 80 dnat to ${cfg.internetHostOverride};
          # host of the bridge IP address
          ip daddr 85.203.53.200 tcp dport 443 dnat to ${cfg.internetHostOverride};
        }
      }
    '';
  };
}