commit 159db097be3a1375b72c2d23247251e3d22fab77
parent af1d8ed39711acc5b759f540805ab898d7eff857
Author: Katja (zaphyra) <git@ctu.cx>
Date: Thu, 29 May 2025 18:16:08 +0200
parent af1d8ed39711acc5b759f540805ab898d7eff857
Author: Katja (zaphyra) <git@ctu.cx>
Date: Thu, 29 May 2025 18:16:08 +0200
config/nixos/modules/presets/katja: add `router`
4 files changed, 492 insertions(+), 0 deletions(-)
A
|
93
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
A
|
89
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
A
|
227
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
A
|
83
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
diff --git a/config/nixos/modules/presets/katja/router/enable.nix b/config/nixos/modules/presets/katja/router/enable.nix @@ -0,0 +1,93 @@ +{ + inputs, + pov, + pkgs, + lib, + config, + hostConfig, + ... +}: +let + inherit (lib) types; + cfg = lib.getAttrFromPath pov config; + +in +{ + + option = { + type = types.bool; + default = false; + }; + + config = lib.mkIf cfg.enable { + + environment.systemPackages = [ pkgs.wireguard-tools ]; + + boot.initrd.kernelModules = [ "jool" ]; + + hardware.firmware = [ + (pkgs.runCommandNoCC "rtl8168h-firmware" { } '' + mkdir -p $out/lib/firmware/rtl_nic + cp ${pkgs.linux-firmware}/lib/firmware/rtl_nic/rtl8168h-2.fw $out/lib/firmware/rtl_nic/rtl8168h-2.fw + '') + ]; + + modules.presets.katja.router = { + systemd-networkd = true; + pppd = true; + }; + + networking = { + useNetworkd = true; + useDHCP = false; + firewall.enable = false; + + nftables.enable = true; + nftables.rulesetFile = inputs.self.resources.katja.routerRuleset; + + jool.enable = true; + jool.nat64.default = { }; + }; + + services = { + resolved.enable = false; + + avahi.enable = true; + avahi.reflector = true; + avahi.allowInterfaces = [ "brlan" ]; + + kresd.enable = true; + kresd.listenPlain = [ "53" ]; + kresd.extraConfig = '' + require 'math' + math.randomseed(os.time()) + + modules.load('dns64') + modules.load('view') + + dns64.config('64:ff9b::') + + -- disable dns64 for all IPv4 source addresses + view:addr('0.0.0.0/0', policy.all(policy.FLAGS('DNS64_DISABLE'))) + + dns_providers = { + { -- Quad9 + '9.9.9.9', '149.112.112.112' + }, + { -- Cloudflare + '1.1.1.1', '1.0.0.1' + }, + { -- Google + '8.8.8.8', '8.8.4.4' + } + } + + policy.add(function (request, query) + return policy.FORWARD(dns_providers[math.random(1, #dns_providers)]) + end) + ''; + }; + + }; + +}
diff --git a/config/nixos/modules/presets/katja/router/pppd.nix b/config/nixos/modules/presets/katja/router/pppd.nix @@ -0,0 +1,89 @@ +{ + povSelf, + pkgs, + lib, + config, + hostConfig, + utils, + ... +}: +let + inherit (lib) types; + cfg = lib.getAttrFromPath povSelf config; + +in +{ + + option = { + type = types.bool; + default = false; + }; + + config = lib.mkIf cfg { + sops.secrets."environments/pppd" = {}; + + services.pppd = { + enable = true; + peers.dtagdsl.config = '' + plugin pppoe.so dtagdsl + user "''${DTAG_PPP_USER}" + password "''${DTAG_PPP_PASS}" + hide-password + ifname ppp-dtagdsl + persist + + maxfail 0 + holdoff 5 + + noipdefault + + lcp-echo-interval 20 + lcp-echo-failure 3 + + mtu 1492 + defaultroute + replacedefaultroute + +ipv6 + ''; + }; + + environment.etc."ppp/peers/dtagdsl".enable = false; + environment.etc."ip-up.d/1systemd-networkd" = { + mode = "755"; + text = '' + #!{pkgs.bash}/bin/bash + networkctl reconfigure "$PPP_IFACE"; + ''; + }; + + systemd.services."pppd-dtagdsl".serviceConfig = + let + preStart = '' + mkdir -p /etc/ppp/peers + + # Created files only readable by root + umask u=rw,g=,o= + + # Copy config and substitute env-vars + rm -f /etc/ppp/peers/dtagdsl + ${pkgs.envsubst}/bin/envsubst -i "${ + config.environment.etc."ppp/peers/dtagdsl".source + }" > /etc/ppp/peers/dtagdsl + ''; + + preStartFile = utils.systemdUtils.lib.makeJobScript { + name = "pppd-dtagdsl-pre-start"; + text = preStart; + enableStrictShellChecks = true; + }; + + in { + EnvironmentFile = config.sops.secrets."environments/pppd".path; + ExecStartPre = [ + # "+" marks script to be executed without priviledge restrictions + "+${preStartFile}" + ]; + }; + }; + +}
diff --git a/config/nixos/modules/presets/katja/router/systemd-networkd.nix b/config/nixos/modules/presets/katja/router/systemd-networkd.nix @@ -0,0 +1,227 @@ +{ + povSelf, + pkgs, + lib, + config, + hostConfig, + ... +}: +let + inherit (lib) types; + cfg = lib.getAttrFromPath povSelf config; + +in +{ + + option = { + type = types.bool; + default = false; + }; + + config = lib.mkIf cfg { + sops.secrets.wireguardPrivKey = { + mode = "640"; + owner = "root"; + group = "systemd-network"; + }; + + systemd.network = { + enable = true; + wait-online.enable = false; + + config.networkConfig = { + IPv4Forwarding = true; + IPv6Forwarding = true; + }; + + links."5-dtagdsl" = { + matchConfig.PermanentMACAddress = "d0:37:45:06:de:de"; + linkConfig.Name = "dtagdsl"; + }; + + links."5-iphone" = { + matchConfig.PermanentMACAddress = "aa:ab:b5:18:95:d9"; + linkConfig.Name = "iphone"; + }; + + netdevs."20-brlan" = { + netdevConfig = { + Kind = "bridge"; + Name = "brlan"; + }; + }; + + netdevs."10-wg-novus" = { + netdevConfig = { + Kind = "wireguard"; + Name = "wg-novus"; + }; + + wireguardConfig = { + PrivateKeyFile = config.sops.secrets.wireguardPrivKey.path; + ListenPort = 51820; + FirewallMark = 51820; + }; + + wireguardPeers = [{ + Endpoint = "novus.infra.zaphyra.eu:51820"; + PublicKey = "J+kRRNU65JGc0yk04v6P3tFwHSQOIfq8EkfD2gFupg4="; + AllowedIPs = [ "::/0" ]; + PersistentKeepalive = 10; + }]; + }; + + networks = { + "5-dtagdsl" = { + matchConfig.Name = "dtagdsl"; + + address = [ "192.168.1.2/24" ]; + + linkConfig.RequiredForOnline = false; + networkConfig.LinkLocalAddressing = false; + }; + + "5-enp1s0" = { + matchConfig.Name = "enp1s0"; + + bridge = [ "brlan" ]; + networkConfig.ConfigureWithoutCarrier = true; + }; + + "5-iphone" = { + matchConfig.Name = "iphone"; + + networkConfig.DHCP = true; + }; + + "10-ppp-dtagdsl" = { + matchConfig.Name = "ppp-dtagdsl"; + + networkConfig = { + KeepConfiguration = true; + IPv6AcceptRA = true; + DHCP = "ipv6"; + }; + + ipv6AcceptRAConfig = { + UseDNS = false; + }; + + dhcpV6Config = { + WithoutRA = "solicit"; + PrefixDelegationHint = "::/56"; + IAID = 0; + UseDNS = false; + }; + }; + + "10-wg-novus" = { + matchConfig.Name = "wg-novus"; + + linkConfig.RequiredForOnline = false; + routes = [{ + Destination = "::/0"; + Table = "1234"; + }]; + }; + + "20-brlan" = { + matchConfig = { + Name = "brlan"; + Driver = "bridge"; + }; + + address = [ + "${hostConfig.networking.ip4Address}/${toString hostConfig.networking.ip4PrefixLength}" + "${hostConfig.networking.ip6Address}/${toString hostConfig.networking.ip6PrefixLength}" + ]; + + routingPolicyRules = [ + { + From = "2a03:4000:4d:5e:acab::/112"; + Table = 254; + Priority = 1900; + SuppressPrefixLength = 0; + } + { + From = "2a03:4000:4d:5e:acab::/112"; + Table = 1234; + Priority = 2000; + } + ]; + + networkConfig = { + ConfigureWithoutCarrier = true; + + DHCPPrefixDelegation = true; + IPv6PrivacyExtensions = false; + IPv6AcceptRA = false; + IPv6SendRA = true; + + DHCPServer = true; + DNS = hostConfig.networking.ip4Address; + }; + + dhcpPrefixDelegationConfig = { + UplinkInterface = "ppp-dtagdsl"; + Announce = true; + SubnetId = 0; + Token = "::1"; + }; + + ipv6SendRAConfig = { + EmitDNS = true; + DNS = "_link_local"; + }; + + ipv6PREF64Prefixes = [{ + Prefix = "64:ff9b::/96"; + }]; + + dhcpServerConfig = { + PersistLeases = true; + PoolOffset = 100; + PoolSize = 100; + EmitDNS = true; + DNS = hostConfig.networking.ip4Address; + IPv6OnlyPreferredSec = 300; + }; + + dhcpServerStaticLeases = [ + { + # accesspoint + MACAddress = "48:a9:8a:8e:dd:0b"; + Address = "10.0.0.2"; + } + { + # pbx + MACAddress = "34:31:c4:46:88:31"; + Address = "10.0.0.3"; + } + { + # scanner + MACAddress = "5c:f3:70:b9:35:9c"; + Address = "10.0.0.4"; + } + { + # printer + MACAddress = "70:77:81:2a:e7:96"; + Address = "10.0.0.5"; + } + { + # nix snowflake (wled) + MACAddress = "28:37:2f:6a:e7:14"; + Address = "10.0.0.6"; + } + { + # katja x13 + MACAddress = "04:CF:4B:76:93:55"; + Address = "10.0.0.10"; + } + ]; + }; + }; + }; + }; + +}
diff --git a/resources/katja/routerRuleset.nft b/resources/katja/routerRuleset.nft @@ -0,0 +1,82 @@ +flush ruleset + +table inet firewall { + chain inbound { + # By default, drop all traffic unless it meets a filter + # criteria specified by the rules that follow below. + type filter hook input priority 0; + policy drop; + + # Allow traffic from established and related packets. + ct state established,related accept + + # Drop invalid packets. + ct state invalid drop + + # Allow local connections. + iifname lo accept + iifname brlan accept + + # Allow all ICMP and IGMP traffic, but enforce a rate limit + # to help prevent some types of flood attacks. + ip protocol icmp limit rate 5/second accept + ip protocol igmp limit rate 5/second accept + ip6 nexthdr ipv6-icmp limit rate 5/second accept + + # required for dhcp-pd to work! + udp dport dhcpv6-client accept + + # Allow some ports + tcp dport ssh accept + tcp dport http accept + tcp dport https accept + tcp dport 8443 accept comment "step-ca" + tcp dport 22000 accept comment "syncthing" + udp dport 21027 accept comment "syncthing" + } + + chain forward { + # By default, drop all traffic unless it meets a filter + type filter hook forward priority 0; + policy drop; + + tcp flags syn tcp option maxseg size set rt mtu + + # Allow traffic from established and related packets. + ct state established,related accept + + # Drop invalid packets. + ct state invalid drop + + # local clients can do whatever + iifname brlan accept + + # Allow all ICMP and IGMP traffic, but enforce a rate limit + # to help prevent some types of flood attacks. + ip protocol icmp limit rate 5/second accept + ip protocol igmp limit rate 5/second accept + ip6 nexthdr ipv6-icmp limit rate 5/second accept + + # drop incomming netbios traffic + tcp dport {139, 445} counter drop comment "silently drop NetBios" + udp dport {137, 138} counter drop comment "silently drop NetBios" + } + + chain outbound { + # Allow all outbound traffic + type filter hook output priority 0 + policy accept + } +} + +table ip nat { + chain prerouting { + type nat hook prerouting priority -100 + policy accept + } + + chain postrouting { + type nat hook postrouting priority srcnat + 1; policy accept; + ip saddr 10.0.0.0/8 masquerade; + } +}+ \ No newline at end of file