{ pkgs, config, inputs', lib, ... }: let inherit (lib) mkDefault concatMap mkImageMediaOverride getExe' ; notnft = inputs'.notnft.lib.${pkgs.stdenv.system}; in { _module.args = {inherit notnft;}; imports = [ inputs'.self.nixosModules.ifstate inputs'.self.nixosModules.notnft-ns ./qemu-vm.nix ]; nixpkgs.overlays = [ inputs'.self.overlays.ifstate ]; networking = { hostName = "hela"; useDHCP = false; firewall.enable = false; }; environment.systemPackages = [pkgs.tcpdump]; networking.notnft.enable = true; networking.notnft.namespaces.default.firewall.interfaces."lan".rules = # --- with notnft.dsl; with payload; # --- { input = [ [(is.eq ip.protocol (f: f.icmp)) accept] [(is.eq ip.protocol (f: f.udp)) (is.eq th.dport 67) accept] ]; }; networking.notnft.namespaces.default.rules = # --- with notnft.dsl; with payload; # --- ruleset { filter = add table {family = f: f.inet;} { input = add chain { type = f: f.filter; hook = f: f.input; prio = -300; policy = f: f.drop; } [(is.eq meta.iifname "lan") (jump "input-lan")]; }; }; networking.notnft.namespaces.dmz.firewall.interfaces."internet".rules = # --- with notnft.dsl; with payload; # --- { input = [ [(is.eq meta.protocol (_: 34915)) accept] # allow PPPoE [drop] ]; }; networking.notnft.namespaces.dmz.rules = # --- with notnft.dsl; with payload; # --- ruleset { filter = add table {family = f: f.inet;} { input = add chain { type = f: f.filter; hook = f: f.input; prio = -300; policy = f: f.drop; } # accept related, established and drop invalid [ (vmap ct.state { established = accept; related = accept; invalid = drop; }) ] [(is.eq meta.iifname "internet") (jump "input-internet")]; }; }; services.ifstate = { enable = true; settings = { namespaces = { dmz = { interfaces = [ { name = "wan"; link = { kind = "physical"; permaddr = "00:11:22:33:44:10"; state = "up"; }; } { name = "internet"; link = { kind = "vlan"; link = "wan"; vlan_id = 6; state = "up"; }; } { name = "iptv"; link = { kind = "vlan"; link = "wan"; vlan_id = 4; }; } { name = "telephony"; link = { kind = "vlan"; link = "wan"; vlan_id = 7; }; } ]; }; }; interfaces = [ { name = "eth1"; link = { kind = "physical"; address = "00:11:22:33:44:01"; state = "down"; }; } { name = "eth2"; link = { kind = "physical"; address = "00:11:22:33:44:02"; state = "down"; }; } { name = "lan0"; link = { kind = "physical"; address = "00:11:22:33:44:11"; master = "lan"; state = "up"; }; } { name = "lan1"; link = { kind = "physical"; address = "00:11:22:33:44:12"; master = "lan"; state = "up"; }; } { name = "lan2"; link = { kind = "physical"; address = "00:11:22:33:44:13"; master = "lan"; state = "up"; }; } { name = "village"; link = { kind = "vlan"; link = "lan"; vlan_id = 1; }; } { name = "bastion"; link = { kind = "vlan"; link = "lan"; vlan_id = 2; }; } { name = "lan"; link = { kind = "bridge"; state = "up"; }; addresses = [ "10.10.0.1/24" ]; } ]; }; }; services.kea.dhcp4 = { enable = true; settings = { interfaces-config.interfaces = [ "lan" ]; subnet4 = [ { pools = [ {pool = "10.10.0.2 - 10.10.0.200";} ]; id = 1; subnet = "10.10.0.0/24"; option-data = [ { name = "routers"; data = "10.10.0.1"; } ]; } ]; }; }; # reference: https://gist.github.com/c0deaddict/64cc4ee262e428e8d8ff4fe507ab1f9b services.pppd = let rp-pppoe = pkgs.callPackage ./rp-pppoe.nix {}; in { enable = true; peers.kpn = { config = '' plugin ${rp-pppoe}/etc/ppp/plugins/rp-pppoe.so nic-internet name "internet" noauth hide-password password "internet" debug +ipv6 ipv6cp-accept-local noipdefault defaultroute defaultroute6 persist maxfail 0 holdoff 5 mtu 1500 mru 1500 ''; }; }; systemd.services.pppd-kpn = { after = ["ifstate.service"]; serviceConfig.NetworkNamespacePath = "/var/run/netns/dmz"; }; virtualisation.qemu.options = (concatMap (index: let index' = toString index; in [ "-net nic,model=e1000,macaddr=00:11:22:33:44:0${index'},netdev=eth${index'}" "-netdev stream,id=eth${index'},addr.type=unix,addr.path=/dev/null" # "-netdev vde,id=eth${index'},sock=../../../hel/switch" ]) [1 2]) ++ [ "-net nic,model=e1000,macaddr=00:11:22:33:44:10,netdev=wan" "-netdev stream,id=wan,server=on,addr.type=unix,addr.path=../../../midgard/link" # "-netdev vde,id=wan,sock=../../../midgard/switch" "-net nic,model=e1000,macaddr=00:11:22:33:44:11,netdev=lan1" "-netdev vde,id=lan1,sock=../../../hel/switch" ] ++ (concatMap (index: let index' = toString index; in [ "-net nic,model=e1000,macaddr=00:11:22:33:44:1${index'},netdev=lan${index'}" "-netdev stream,id=lan${index'},addr.type=unix,addr.path=/dev/null" # "-netdev vde,id=lan${index'},sock=../../../hel/switch" ]) [2 3]); }