diff --git a/nix/key/flake.nix b/nix/key/flake.nix index 406264b..1452cee 100644 --- a/nix/key/flake.nix +++ b/nix/key/flake.nix @@ -5,5 +5,10 @@ lib.gpgKey = null; # test key lib.dyndnsKey = "Dr1QHSfNtAwgbdoNBtCgl5NxsSXlaw9+qo7juiVTv58="; + # test credentials + lib.pppoe.upstream4 = { + user = "test@example.com"; + password = "secret"; + }; }; } diff --git a/nix/lib/config/legacy.nix b/nix/lib/config/legacy.nix index 8ee518c..df8b472 100644 --- a/nix/lib/config/legacy.nix +++ b/nix/lib/config/legacy.nix @@ -105,7 +105,14 @@ in ]; }; upstream3.interfaces.up3.upstream.provider = "starlink"; - upstream4.interfaces.up4.upstream.provider = "dsi"; + upstream4.interfaces.up4-pppoe = { + type = "pppoe"; + upstream = { + provider = "dsi"; + link = "up4"; + upBandwidth = 95000; + }; + }; upstream1.ospf.upstreamInstance = 3; upstream2.ospf.upstreamInstance = 4; anon1.ospf.upstreamInstance = 5; diff --git a/nix/lib/config/options.nix b/nix/lib/config/options.nix index 6a23843..53f064d 100644 --- a/nix/lib/config/options.nix +++ b/nix/lib/config/options.nix @@ -106,6 +106,11 @@ let provider = mkOption { type = types.str; }; + link = mkOption { + type = with types; nullOr str; + default = null; + description = "Underlying interface name for eg. PPPoE"; + }; upBandwidth = mkOption { type = with types; nullOr int; default = null; @@ -124,7 +129,7 @@ let description = "Static MAC address"; }; type = mkOption { - type = types.enum [ "phys" "veth" ]; + type = types.enum [ "phys" "veth" "pppoe" ]; description = '' veth: Virtual ethernet to be attached to a bridge. diff --git a/nix/nixos-module/container/bird.nix b/nix/nixos-module/container/bird.nix index 4b0d654..2a84dad 100644 --- a/nix/nixos-module/container/bird.nix +++ b/nix/nixos-module/container/bird.nix @@ -116,14 +116,14 @@ in # Enable OSPF only on networks with a secret. Others # are treated as a stubnet whose routes to # advertise. - if config.site.net.${net}.ospf.secret != null + if config.site.net ? net && config.site.net.${net}.ospf.secret != null then '' interface "${net}" { authentication cryptographic; password "${config.site.net.${net}.ospf.secret}"; }; '' - else if config.site.net.${net}.subnet4 != null + else if config.site.net ? net && config.site.net.${net}.subnet4 != null then '' # Advertise route of network ${net} stubnet ${config.site.net.${net}.subnet4} {}; diff --git a/nix/nixos-module/container/upstream.nix b/nix/nixos-module/container/upstream.nix index 195e6f3..fae8242 100644 --- a/nix/nixos-module/container/upstream.nix +++ b/nix/nixos-module/container/upstream.nix @@ -38,8 +38,14 @@ in extraConfig = '' [CAKE] Parent = root - # DOCSIS overhead - OverheadBytes = 18 + ${lib.optionalString (upstream.provider == "vodafone") '' + # DOCSIS overhead + OverheadBytes = 18 + ''} + ${lib.optionalString (upstream.provider == "dsi") '' + # PPPoE overhead + OverheadBytes = 18 + ''} ${lib.optionalString (upstream.upBandwidth != null) '' Bandwidth = ${toString upstream.upBandwidth}K ''} diff --git a/nix/nixos-module/container/upstream/pppoe.nix b/nix/nixos-module/container/upstream/pppoe.nix index a946d87..417d41f 100644 --- a/nix/nixos-module/container/upstream/pppoe.nix +++ b/nix/nixos-module/container/upstream/pppoe.nix @@ -1,4 +1,4 @@ -{ hostName, inputs, lib, ... }: +{ hostName, inputs, config, lib, ... }: let hostConf = config.site.hosts.${hostName}; @@ -7,18 +7,12 @@ let lib.filterAttrs (_: { type, ... }: type == "pppoe") hostConf.interfaces; - firstUpstreamInterface = - if builtins.length (builtins.attrNames upstreamInterfaces) > 0 - then builtins.head ( - builtins.attrNames upstreamInterfaces - ) - else null; - inherit (inputs.zentralwerk-network-key.lib.pppoe.${hostName}) user password; + in lib.mkIf (pppoeInterfaces != {}) { boot.postBootCommands = '' if [ ! -c /dev/ppp ]; then - mknod -m 666 /dev/ppp c 108 0 + mknod -m 600 /dev/ppp c 108 0 fi ''; @@ -61,7 +55,37 @@ in lib.mkIf (pppoeInterfaces != {}) { # Increase debugging level debug ''; - }; + }) pppoeInterfaces; }; + systemd.network.networks = + builtins.foldl' (networks: ifName: let + iface = pppoeInterfaces.${ifName}; + in networks // { + "${ifName}" = { + matchConfig.Name = "${ifName}"; + networkConfig = { + DHCP = lib.mkOverride 900 "ipv6"; + # accept config set by pppd + KeepConfiguration = "yes"; + }; + dhcpV6Config = { + RapidCommit = true; + ForceDHCPv6PDOtherInformation = true; + PrefixDelegationHint = "::/56"; + }; + }; + "${iface.upstream.link}".networkConfig = { + ConfigureWithoutCarrier = true; + LinkLocalAddressing = "no"; + }; + }) {} (builtins.attrNames pppoeInterfaces); + + # TODO: needed? + networking.nat.extraCommands = '' + iptables -A FORWARD \ + -p tcp --tcp-flags SYN,RST SYN \ + -j TCPMSS --clamp-mss-to-pmtu + ''; + } diff --git a/nix/nixos-module/default.nix b/nix/nixos-module/default.nix index f07b9ad..fb904ca 100644 --- a/nix/nixos-module/default.nix +++ b/nix/nixos-module/default.nix @@ -36,6 +36,7 @@ in { ] ++ optionals (builtins.match "upstream.*" hostName != null) [ ./container/upstream.nix + ./container/upstream/pppoe.nix ] ++ optionals (hostName == "mgmt-gw") [ ./container/mgmt-gw.nix diff --git a/nix/nixos-module/server/lxc-containers.nix b/nix/nixos-module/server/lxc-containers.nix index fe62465..4f45b20 100644 --- a/nix/nixos-module/server/lxc-containers.nix +++ b/nix/nixos-module/server/lxc-containers.nix @@ -180,6 +180,9 @@ in # tuntap lxc.cgroup.devices.allow = c 10:200 rw lxc.cgroup2.devices.allow = c 10:200 rw + # ppp + lxc.cgroup.devices.allow = c 108:0 rwm + lxc.cgroup2.devices.allow = c 108:0 rwm ${netConfig ctName containers.${ctName}.physicalInterfaces} '';