{ pkgs, notnft, config, ... }: { services.ifstate.settings.namespaces.border = { routing.routes = [ { to = "0.0.0.0/0"; dev = "ppp-wan"; } ]; interfaces = [ { name = "slan-vlan"; link = { kind = "vlan"; link = "slan"; link_netns = null; vlan_id = 6; state = "up"; mtu = config.bananapi.mtu.slan-vlan; }; } # { # name = "ppp-slan"; # link = { # kind = "ppp"; # addresses = [ # "192.168.1.1/24" # ] # } # } { name = "wan-vlan"; link = { kind = "vlan"; link = "wan"; link_netns = null; vlan_id = 6; state = "up"; mtu = config.bananapi.mtu.wan-vlan; }; } # { # name = "ppp-wan"; # link = { # kind = "dummy"; # }; # addresses = [ # "8.8.8.8/32" # ]; # } { name = "dmz"; link = { kind = "veth"; peer = "border"; peer_netns = "dmz"; state = "up"; }; addresses = [ "10.0.0.1/24" ]; } ]; }; networking.notnft.namespaces.border.rules = # --- with notnft.dsl; with payload; # --- ruleset { filter = add table {family = f: f.inet;} { port_dnat = add notnft.dsl.map { map = f: [f.ipv4_addr f.inet_service]; type = f: [f.inet_proto f.ipv4_addr f.inet_service]; flags = f: with f; [interval]; } [ [(concat ["udp" "86.80.70.193" 6666]) (concat ["10.0.0.2" 6666])] [(concat ["udp" "86.80.70.193" 500]) (concat ["10.0.0.2" 500])] [(concat ["udp" "86.80.70.193" 501]) (concat ["10.0.0.2" 501])] [(concat ["tcp" "192.168.1.1" 22]) (concat ["10.0.0.2" 22])] ]; local_nets4 = add set { type = f: f.ipv4_addr; flags = f: with f; [interval]; } [ (cidr "10.0.0.0" 8) (cidr "172.16.0.0" 12) (cidr "192.168.0.0" 16) ]; input = add chain { type = f: f.filter; hook = f: f.input; prio = -300; policy = f: f.drop; } [(is.eq meta.iifname "lo") accept] [ (is.eq ip.saddr (set [ (cidr "192.168.1.0" 25) ])) (is.eq ip.daddr (set [ "192.168.1.1" "86.80.70.193" ])) (is.eq ip.protocol (f: f.icmp)) accept ] [ (is.eq ip.saddr (set [ (cidr "10.0.0.0" 24) (cidr "10.1.0.0" 19) ])) (is.eq ip.daddr (set [ "10.0.0.1" "86.80.70.193" ])) (is.eq ip.protocol (f: f.icmp)) accept ] [ (log { prefix = "[drop] border.input: "; queue-threshold = 1; group = 2; }) drop ]; output = add chain { type = f: f.filter; hook = f: f.output; prio = -300; policy = f: f.drop; } # accept related, established [ (vmap ct.state { established = accept; related = accept; }) ] [ (is.eq ip.saddr (set [ "192.168.1.1" "86.80.70.193" ])) (is.eq ip.daddr (set [ (cidr "192.168.1.0" 25) ])) (is.eq ip.protocol (f: f.icmp)) (is.eq icmp.type (f: f.echo-reply)) accept ] [ (is.eq ip.saddr (set [ "10.0.0.1" "86.80.70.193" ])) (is.eq ip.daddr (set [ (cidr "10.0.0.0" 24) (cidr "10.1.0.0" 19) ])) (is.eq ip.protocol (f: f.icmp)) (is.eq icmp.type (f: f.echo-reply)) accept ] [ (log { prefix = "[drop] border.output: "; queue-threshold = 1; group = 2; }) drop ]; forward = add chain { type = f: f.filter; hook = f: f.forward; prio = -300; policy = f: f.drop; } # accept related, established [ (vmap ct.state { established = accept; related = accept; invalid = drop; }) ] # allow forwarding traffic for the internet [ (is.eq meta.iifname (set ["dmz" "ppp-slan"])) (is.eq meta.oifname "ppp-wan") accept ] # accept port forwarding from `wan`, `ppp-slan`, `ppp-wan` to `dmz` [ (is.eq meta.iifname (set ["ppp-wan" "ppp-slan" "dmz"])) (is.eq meta.oifname "dmz") (is."in" ct.status "dnat") accept ] [ (log { prefix = "[drop] border.forward: "; queue-threshold = 1; group = 2; }) drop ]; prerouting = add chain { type = f: f.nat; hook = f: f.prerouting; prio = -100; policy = f: f.accept; } [ (dnat.ip { addr.map = { key = concat [ip.protocol ip.daddr th.dport]; data = "@port_dnat"; }; }) ]; postrouting = add chain { type = f: f.nat; hook = f: f.postrouting; prio = -100; policy = f: f.accept; } [ (is.eq meta.iifname "dmz") (is.eq meta.oifname "dmz") (is.eq (concat [ip.protocol th.dport]) (set [ (concat ["udp" 500]) (concat ["udp" 501]) (concat ["udp" 6666]) ])) (is.eq ip.saddr "10.0.0.2") (is.eq ip.daddr "10.0.0.2") masquerade ] [ (is.eq meta.iifname "ppp-slan") (is.eq meta.oifname "ppp-slan") (is.eq (concat [ip.protocol th.dport]) (set [ (concat ["udp" 500]) (concat ["udp" 6666]) (concat ["tcp" 2288]) ])) (is.eq ip.saddr "192.168.1.2") (is.eq ip.daddr "192.168.1.2") masquerade ] [ (is.eq meta.oifname "ppp-wan") masquerade ]; }; }; services.pppoe-server.kpn = { interface = "slan-vlan"; localAddress = "192.168.1.1"; remoteAddressFile = pkgs.writeText "kpn-remote-address-file" '' 192.168.1.2 ''; C = "195.190.228.154"; pppdSettings = { ifname = ["ppp-slan"]; mtu = [1500]; mru = [1500]; }; }; systemd.services.pppoe-server-kpn = { after = ["ifstate.service"]; serviceConfig.NetworkNamespacePath = "/var/run/netns/border"; }; services.pppd = { enable = true; peers.kpn = { config = '' plugin ${pkgs.rp-pppoe}/etc/ppp/plugins/rp-pppoe.so nic-wan-vlan name "internet" password "internet" noauth hide-password debug +ipv6 ipv6cp-accept-local noipdefault defaultroute defaultroute6 persist maxfail 0 holdoff 5 mtu 1500 mru 1500 ifname ppp-wan ''; }; }; systemd.services.pppd-kpn = { after = ["ifstate.service"]; serviceConfig.NetworkNamespacePath = "/var/run/netns/border"; }; systemd.services.ulogd-border = { description = "Ulogd Daemon"; wantedBy = ["multi-user.target"]; wants = ["network-pre.target"]; before = ["network-pre.target"]; after = ["ifstate.service"]; serviceConfig = let settingsFormat = pkgs.formats.ini {listsAsDuplicateKeys = true;}; settingsFile = settingsFormat.generate "ulogd.conf" { # This one for logging to local file in emulated syslog format. global.stack = "log2:NFLOG,base1:BASE,ifi1:IFINDEX,ip2str1:IP2STR,print1:PRINTPKT,emu1:LOGEMU"; log2.group = 2; emu1 = { file = "/var/log/nft_border_drop.log"; sync = 1; }; }; in { NetworkNamespacePath = "/var/run/netns/border"; ExecStart = "${pkgs.ulogd}/bin/ulogd -c ${settingsFile} --verbose --loglevel ${ toString 5 }"; ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID"; }; }; }