diff --git a/lib/default.nix b/lib/default.nix index d00d75a..de3c734 100644 --- a/lib/default.nix +++ b/lib/default.nix @@ -260,8 +260,14 @@ rec { interval = "04:45"; }; }; - kelder = { + kelder = rec { domain = "hentai.engineer"; + vpn = { + port = 51820; + start = "100.69.69."; + }; + start = "172.16.69."; + prefix = "${start}0/24"; }; sshKeyFiles = { me = ../.keys/me.pub; diff --git a/nixos/boxes/colony/vms/estuary/default.nix b/nixos/boxes/colony/vms/estuary/default.nix index 92ff57c..750748a 100644 --- a/nixos/boxes/colony/vms/estuary/default.nix +++ b/nixos/boxes/colony/vms/estuary/default.nix @@ -87,6 +87,7 @@ in environment = { systemPackages = with pkgs; [ ethtool + wireguard-tools ]; }; @@ -143,6 +144,7 @@ in #systemd.services.systemd-networkd.environment.SYSTEMD_LOG_LEVEL = "debug"; systemd.network = { + wait-online.enable = false; config = { networkConfig = { ManageForeignRoutes = false; @@ -168,6 +170,28 @@ in (mkVLAN "nl-ix" 1845) (mkVLAN "fogixp" 1147) (mkVLAN "ifog-transit" 702) + + { + "30-kelder" = { + netdevConfig = { + Name = "kelder"; + Kind = "wireguard"; + }; + wireguardConfig = { + PrivateKeyFile = config.age.secrets."estuary/kelder-wg.key".path; + ListenPort = lib.my.kelder.vpn.port; + }; + wireguardPeers = [ + { + wireguardPeerConfig = { + PublicKey = "7N9YdQaCMWWIwAnW37vrthm9ZpbnG4Lx3gheHeRYz2E="; + AllowedIPs = [ "${lib.my.kelder.vpn.start}2" ]; + PersistentKeepalive = 25; + }; + } + ]; + }; + } ]; links = { @@ -303,23 +327,35 @@ in ]; "90-l2mesh-as211024" = { + matchConfig.Name = "as211024"; address = with assignments.as211024; [ (with ipv4; "${address}/${toString mask}") (with ipv6; "${address}/${toString mask}") ]; networkConfig.IPv6AcceptRA = false; }; + "95-kelder" = { + matchConfig.Name = "kelder"; + address = [ "${lib.my.kelder.vpn.start}1/30" ]; + }; } ]; }; my = { #deploy.generate.system.mode = "boot"; - secrets.key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIF9up7pXu6M/OWCKufTOfSiGcxMUk4VqUe7fLuatNFFA"; + secrets = { + key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIF9up7pXu6M/OWCKufTOfSiGcxMUk4VqUe7fLuatNFFA"; + files = { + "estuary/kelder-wg.key" = { + owner = "systemd-network"; + }; + }; + }; server.enable = true; firewall = { trustedInterfaces = [ "base" "as211024" ]; - udp.allowed = [ 5353 ]; + udp.allowed = [ 5353 lib.my.kelder.vpn.port ]; tcp.allowed = [ 5353 "bgp" ]; nat = { enable = true; @@ -328,27 +364,33 @@ in forwardPorts = [ { port = "http"; - dst = allAssignments.middleman.internal.ipv4.address + ":http"; + dst = allAssignments.middleman.internal.ipv4.address; } { port = "https"; - dst = allAssignments.middleman.internal.ipv4.address + ":https"; + dst = allAssignments.middleman.internal.ipv4.address; } { port = 8448; - dst = allAssignments.middleman.internal.ipv4.address + ":8448"; + dst = allAssignments.middleman.internal.ipv4.address; } { port = 2456; - dst = allAssignments.valheim-oci.internal.ipv4.address + ":2456"; + dst = allAssignments.valheim-oci.internal.ipv4.address; proto = "udp"; } { port = 2457; - dst = allAssignments.valheim-oci.internal.ipv4.address + ":2457"; + dst = allAssignments.valheim-oci.internal.ipv4.address; proto = "udp"; } + + { + port = 6922; + dst = "${lib.my.kelder.vpn.start}2"; + dstPort = "ssh"; + } ]; }; extraRules = diff --git a/nixos/boxes/kelder/default.nix b/nixos/boxes/kelder/default.nix index 13ae521..cc414cb 100644 --- a/nixos/boxes/kelder/default.nix +++ b/nixos/boxes/kelder/default.nix @@ -7,6 +7,8 @@ configuration = { lib, pkgs, modulesPath, config, systems, assignments, allAssignments, ... }: let inherit (lib) mkIf mkMerge mkForce; + + vpnTable = 51820; in { imports = [ ./boot.nix ]; @@ -49,6 +51,12 @@ }; }; + environment = { + systemPackages = with pkgs; [ + wireguard-tools + ]; + }; + services = { fstrim.enable = true; lvm = { @@ -69,6 +77,28 @@ systemd = { network = { + netdevs = { + "30-estuary" = { + netdevConfig = { + Name = "estuary"; + Kind = "wireguard"; + }; + wireguardConfig = { + PrivateKeyFile = config.age.secrets."kelder/estuary-wg.key".path; + RouteTable = vpnTable; + }; + wireguardPeers = [ + { + wireguardPeerConfig = { + PublicKey = "bP1XUNxp9i8NLOXhgPaIaRzRwi5APbam44/xjvYcyjU="; + Endpoint = "estuary-vm.${lib.my.colony.domain}:${toString lib.my.kelder.vpn.port}"; + AllowedIPs = [ "0.0.0.0/0" ]; + PersistentKeepalive = 25; + }; + } + ]; + }; + }; links = { "10-et1g0" = { matchConfig.MACAddress = "74:d4:35:e9:a1:73"; @@ -80,6 +110,17 @@ matchConfig.Name = "et1g0"; DHCP = "yes"; }; + "95-estuary" = { + matchConfig.Name = "estuary"; + address = [ "${lib.my.kelder.vpn.start}2/30" ]; + routingPolicyRules = map (r: { routingPolicyRuleConfig = r; }) [ + { + From = "${lib.my.kelder.vpn.start}2"; + Table = vpnTable; + Priority = 100; + } + ]; + }; }; }; }; @@ -93,6 +134,11 @@ deploy.node.hostname = "10.16.9.21"; secrets = { key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOFvUdJshXkqmchEgkZDn5rgtZ1NO9vbd6Px+S6YioWi"; + files = { + "kelder/estuary-wg.key" = { + owner = "systemd-network"; + }; + }; }; server.enable = true; diff --git a/nixos/modules/firewall.nix b/nixos/modules/firewall.nix index 0ce0dcc..c8b54e7 100644 --- a/nixos/modules/firewall.nix +++ b/nixos/modules/firewall.nix @@ -1,7 +1,7 @@ { lib, options, config, ... }: let inherit (lib) optionalString concatStringsSep concatMapStringsSep optionalAttrs mkIf mkDefault mkMerge mkOverride; - inherit (lib.my) parseIPPort mkOpt' mkBoolOpt'; + inherit (lib.my) isIPv6 mkOpt' mkBoolOpt'; allowICMP = '' icmp type { @@ -36,11 +36,12 @@ let udp dport 33434-33625 accept ''; - forwardOpts = with lib.types; { + forwardOpts = with lib.types; { config, ... }: { options = { proto = mkOpt' (enum [ "tcp" "udp" ]) "tcp" "Protocol."; port = mkOpt' (either port str) null "Incoming port."; - dst = mkOpt' str null "Destination (ip:port)."; + dst = mkOpt' str null "Destination IP."; + dstPort = mkOpt' (either port str) config.port "Destination port."; }; }; @@ -168,15 +169,15 @@ in my.firewall.extraRules = let makeFilter = f: - let - ipp = parseIPPort f.dst; - in - "ip${optionalString ipp.v6 "6"} daddr ${ipp.ip} ${f.proto} dport ${toString f.port} accept"; + let + v6 = isIPv6 f.dst; + in + "ip${optionalString v6 "6"} daddr ${f.dst} ${f.proto} dport ${toString f.dstPort} accept"; makeForward = f: let - ipp = parseIPPort f.dst; + v6 = isIPv6 f.dst; in - "${f.proto} dport ${toString f.port} dnat ip${optionalString ipp.v6 "6"} to ${f.dst}"; + "${f.proto} dport ${toString f.port} dnat ip${optionalString v6 "6"} to ${f.dst}:${toString f.dstPort}"; in '' table inet filter { diff --git a/secrets/estuary/kelder-wg.key.age b/secrets/estuary/kelder-wg.key.age new file mode 100644 index 0000000..fefa8d1 --- /dev/null +++ b/secrets/estuary/kelder-wg.key.age @@ -0,0 +1,12 @@ +-----BEGIN AGE ENCRYPTED FILE----- +YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IG44Q3BVdyB2dVJq +ZmdZWnV2R2JUU1hPYnQ3ak4rTTFUamw0aG92L1pyenlZN0hDZVRFClV4UThWL3hr +TGltOUNRc2FUZUdWUHRQNnZuK09BQ1RJR0gzaHZaOGFoV2sKLT4gWDI1NTE5IGYw +TGFvMi8reDcwa1ZkVWFucmVHTG90dlVkUnY1VGdmdUh1UFVvNUFyRUUKcHZXWE1K +Nk43NzV5djdkUFVZbGRwalhZYm84bUU5NEVJYzRTMmVPM0ROSQotPiBZZiMtZ3Jl +YXNlIHYrIDwhaz53Xjcge1NpKm89IEQoPy8oLGUKOEsySnM0S1Y1ZGpReGRJU3ZL +RHpiRGl0VlZERlJNczFVb3Y0WW5YanZaOAotLS0gZHhkNTZEUUI5OFBwdWtaVEYw +Y3o1ak9DbG8vM1RSOGk1MzE0VUdxS2JHWQquguFjLOP0I+STSbo6YBmgPielDdT3 +0lvk4KTTx1HP2gjRBBFTS6cJ0HDCORpnWXIhoanj+MDPejWXj9sDPh1zhYKrWCB6 +ZbGE5Waphg== +-----END AGE ENCRYPTED FILE----- diff --git a/secrets/kelder/estuary-wg.key.age b/secrets/kelder/estuary-wg.key.age new file mode 100644 index 0000000..20ab608 --- /dev/null +++ b/secrets/kelder/estuary-wg.key.age @@ -0,0 +1,12 @@ +-----BEGIN AGE ENCRYPTED FILE----- +YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IGV5cTNkZyA1Skpw +c2FiaFBFTzcydXFIN25yRFlKeDk1UkQydWdkaWJTVUJhRHVQd1dJCjN2RkN5ZDBD +RllGWkk2VEZYRDFUMXF6STFQRVVCRTA0UnAzTk5tc0NWT1kKLT4gWDI1NTE5IDVi +MVl4VFVxeVhFaUkrV1RqaDk5Q2ZSdDFUTTI3V3J4aS93RzVDOVU1MlkKMXcwMFc1 +RlA0N09UT0daMjRmbTNnbnBPc2JRNXQzNzY0TTJUcEpmdUFRawotPiBNN3s0YC1n +cmVhc2UgKyh3NSdNIEhndz13UF48IH1WREpwIFdmJgpYSDJEUWNtUEl6L0h4OXJI +OTdJTjJEdjBLQzdCVUVheit5OTc5T3Rsb3ZTTFlnQ3RiMVg0L1pyT3FtSE1mRW5z +Ck1nZUhFYncKLS0tIEJHYVFoVXVTamEzYXlDTlY3dy84ZGxobm5PcytNMzJjTWlv +eTVuUEduRGMK7gE8vk0dwaoaVoDEjLej2eKtqOMcU7lYUOVtAgHC+YLvgaC5YB1y +3Q5cWVkA4StDI7wgPp58+jEM+7VzwdOhqgsGhdX2qehd20GKTOQ= +-----END AGE ENCRYPTED FILE-----