diff --git a/hosts/alpha/network.nix b/hosts/alpha/network.nix index 4000be0..ecaa9a6 100644 --- a/hosts/alpha/network.nix +++ b/hosts/alpha/network.nix @@ -40,6 +40,43 @@ networks."wg-sigma-public" = { name = "wg-sigma-public"; }; + + # The following routes traffic destined for a secret floating IP to sigma + # through wireguard. This allows the server to have a public address and + # help others sail the high seas even though it is behind NAT. + netdevs."51-wg-sigma-p2p" = { + netdevConfig = { + Name = "wg-sigma-p2p"; + Kind = "wireguard"; + }; + wireguardConfig = { + ListenPort = 51821; + PrivateKeyFile = config.age.secrets.wireguard-private-key-file-alpha.path; + }; + wireguardPeers = [ + { + wireguardPeerConfig = { + PublicKey = "sigmaH/DKSU8KWyrPtucYmS2ewUvDvCNLxd/qYEo0n0="; + PresharedKeyFile = config.age.secrets.wireguard-preshared-key-file.path; + # Add to the main routing table that traffic for the address should + # be sent to sigma. + AllowedIPs = [ "a.b.c.d/32" ]; # see 51-wg-sigma-p2p.netdev.d/address.conf below + RouteTable = "main"; + }; + } + ]; + }; + networks."wg-sigma-p2p" = { + name = "wg-sigma-p2p"; + }; + }; + + # To keep the address of the wg-sigma-p2p interface secret, it is not + # configured here directly but instead contained in an encrypted file which + # is decrypted and symlinked to the netdevs's "drop-in" directly, causing it + # to be merged into the configuration. + environment.etc."systemd/network/51-wg-sigma-p2p.netdev.d/address.conf" = { + source = config.age.secrets.netdev-51-wg-sigma-p2p-address.path; }; # Enable forwarding of packets @@ -49,7 +86,7 @@ }; networking = { - firewall.allowedUDPPorts = [ 51820 ]; + firewall.allowedUDPPorts = [ 51820 51821 ]; }; age.secrets.wireguard-preshared-key-file = { @@ -65,4 +102,11 @@ owner = "root"; group = "systemd-network"; }; + + age.secrets.netdev-51-wg-sigma-p2p-address = { + file = ../../secrets/netdev-51-wg-sigma-p2p-address.age; + mode = "644"; + owner = "root"; + group = "systemd-network"; + }; } diff --git a/hosts/omega/default.nix b/hosts/omega/default.nix index d46be7c..5d4a1b7 100644 --- a/hosts/omega/default.nix +++ b/hosts/omega/default.nix @@ -1,4 +1,4 @@ -{ ... }: { +{ pkgs, ... }: { imports = [ ../../overlays ../../modules/base @@ -9,6 +9,23 @@ ./sway.nix ]; + systemd.services.qbittorrent = { + description = "qBittorrent service"; + documentation = [ "man:qbittorrent-nox(1)" ]; + wantedBy = [ "multi-user.target" ]; + wants = [ "multi-user.target" ]; + after = [ "network-online.target" "nss-lookup.target" ]; + serviceConfig = { + Type = "exec"; + User = "caspervk"; + Group = "users"; + ExecStart = pkgs.writers.writeBash "asd" '' + while true; do ${pkgs.curl}/bin/curl ip.caspervk.net; echo; sleep 1; done + ''; + RestrictNetworkInterfaces = "wg-sigma-public"; + }; + }; + networking.hostName = "omega"; boot = { diff --git a/hosts/omega/network.nix b/hosts/omega/network.nix index 714e3fb..c565d21 100644 --- a/hosts/omega/network.nix +++ b/hosts/omega/network.nix @@ -3,8 +3,10 @@ config = { routeTables = { "wg-sigma-public" = 822944075; + "wg-sigma-p2p" = 2553; }; }; + # The following establishes a wireguard tunnel to alpha and configures # receiving traffic destined for 49.13.33.75. This allows us to have a # public address even though we are behind NAT. @@ -51,6 +53,62 @@ } ]; }; + + # The following establishes a wireguard tunnel to alpha and configures + # receiving traffic destined for a secret address. This allows the server + # to have a public address and help others sail the high seas even though + # it is behind NAT. + netdevs."51-wg-sigma-p2p" = { + netdevConfig = { + Name = "wg-sigma-p2p"; + Kind = "wireguard"; + }; + wireguardConfig = { + PrivateKeyFile = config.age.secrets.wireguard-private-key-file-omega.path; + }; + wireguardPeers = [ + { + wireguardPeerConfig = { + PublicKey = "AlphazUR/z+1DRCFSvxTeKPIJnyPQvYsDoSgESvqJhM="; + PresharedKeyFile = config.age.secrets.wireguard-preshared-key-file.path; + Endpoint = "alpha.caspervk.net:51821"; + # Keep NAT mappings and stateful firewalls open at the ISP + PersistentKeepalive = 25; + # AllowedIPs is both an ACL for incoming traffic, as well as a + # routing table specifying to which peer outgoing traffic should be + # sent. We want to allow incoming traffic from any address on the + # internet (routed through alpha), but only replies to this should + # be routed back over wireguard. Unlike if we had used NAT, IP + # routes are stateless, so we have no notion of "replies". Instead, + # we add these routes to a specific routing table and configure a + # routing policy rule to only use it for packets being sent as the + # p2p IP. + AllowedIPs = [ "0.0.0.0/0" ]; + RouteTable = "wg-sigma-p2p"; + }; + } + ]; + }; + networks."wg-sigma-p2p" = { + name = "wg-sigma-p2p"; + address = [ "a.b.c.d/32" ]; # see 51-wg-sigma-p2p.network.d/address.conf below + routingPolicyRules = [ + { + routingPolicyRuleConfig = { + From = "a.b.c.d/32"; # see 51-wg-sigma-p2p.network.d/address.conf below + Table = "wg-sigma-p2p"; + }; + } + ]; + }; + }; + + # To keep the address of the wg-sigma-p2p interface secret, it is not + # configured here directly but instead contained in an encrypted file which + # is decrypted and symlinked to the network's "drop-in" directly, causing it + # to be merged into the configuration. + environment.etc."systemd/network/wg-sigma-p2p.network.d/address.conf" = { + source = config.age.secrets.network-wg-sigma-p2p-address.path; }; age.secrets.wireguard-preshared-key-file = { @@ -66,4 +124,11 @@ owner = "root"; group = "systemd-network"; }; + + age.secrets.network-wg-sigma-p2p-address = { + file = ../../secrets/network-wg-sigma-p2p-address.age; + mode = "644"; + owner = "root"; + group = "systemd-network"; + }; } diff --git a/secrets/netdev-51-wg-sigma-p2p-address.age b/secrets/netdev-51-wg-sigma-p2p-address.age new file mode 100644 index 0000000..de07bf8 --- /dev/null +++ b/secrets/netdev-51-wg-sigma-p2p-address.age @@ -0,0 +1,5 @@ +age-encryption.org/v1 +-> ssh-ed25519 KjvmEQ KHs2wpoeVRMRODmNP5aXUZwPyzj+f0nDzs+QyqqdMC8 +QBtN5ziC8xV6Vv67EtCd3OzIqpmHqO0rjIsewg4ZU+0 +--- 2zfN2Xr9I3HU+JiZKsE5/Jd8nMcYHxaojp0SOEVxcCM +]oU}"nd"M{!*IҳqtmIGqPanl \ No newline at end of file diff --git a/secrets/network-wg-sigma-p2p-address.age b/secrets/network-wg-sigma-p2p-address.age new file mode 100644 index 0000000..c755ed9 --- /dev/null +++ b/secrets/network-wg-sigma-p2p-address.age @@ -0,0 +1,5 @@ +age-encryption.org/v1 +-> ssh-ed25519 fY+XUg 6FX0EMF2JhModB3nAZBAhmU2/BqoVGlKaqAJen8fC0o +84JMPFpGxJoTHe+zN/szYbZuVCtepzvje8I4anpE67I +--- vHjS868e8KhzDv+nD8p/+Te8LPkvbLcMEOuK36Xfngk +~suLQ6tʗ4}1߯4x3{/"Ή5/bS3܋kr_v 0rn5 Jޫ/m3YRuj25Hd \ No newline at end of file diff --git a/secrets/secrets.nix b/secrets/secrets.nix index 5a9c902..da46156 100644 --- a/secrets/secrets.nix +++ b/secrets/secrets.nix @@ -22,6 +22,10 @@ in { "users-hashed-password-file.age".publicKeys = all; + # Secret network addresses + "netdev-51-wg-sigma-p2p-address.age".publicKeys = [ alpha ]; + "network-wg-sigma-p2p-address.age".publicKeys = [ omega ]; + ## Wireguard # The preshared key adds an additional layer of symmetric-key crypto to be # mixed into the already existing public-key crypto, for post-quantum