-{ pkgs, lib, config, hosts, hostName, wireguard, ... }:
+{ pkgs, lib, config, inputs, ... }:
let
- inherit (builtins) hasAttr removeAttrs;
inherit (config.security) gnupg;
inherit (config.boot) initrd;
- wg = "wg-intra";
- relay = hosts.mermet.extraArgs.wireguard."${wg}";
- peers = lib.filterAttrs (peerName: host:
- hasAttr "${wg}" host.extraArgs.wireguard
- ) (removeAttrs hosts [hostName]);
+ iface = "wg-intra";
+ wg = config.networking.wireguard.interfaces.${iface};
+ wg-intra-peers = import (inputs.julm-nix + "/nixos/profiles/wireguard/wg-intra/peers.nix");
+ relay = wg-intra-peers.mermet;
in
{
-security.gnupg.secrets."wireguard/${wg}/privateKey" = {};
-systemd.services."wireguard-${wg}" = {
- after = [ gnupg.secrets."wireguard/${wg}/privateKey".service ];
- requires = [ gnupg.secrets."wireguard/${wg}/privateKey".service ];
+imports = [
+ (inputs.julm-nix + "/nixos/profiles/wireguard/wg-intra.nix")
+];
+networking.wireguard.${iface}.peers = {
+ mermet.enable = true;
+ oignon.enable = true;
+ patate.enable = true;
+};
+networking.wireguard.interfaces.${iface} = {
+ privateKeyFile = gnupg.secrets."wireguard/${iface}/privateKey".path;
+};
+security.gnupg.secrets."wireguard/${iface}/privateKey" = {
+/*
+ systemdConfig.serviceConfig = {
+ before = [ "wireguard-${iface}.service" ];
+ wantedBy = [ "wireguard-${iface}.service" ];
+ requiredBy = [ "wireguard-${iface}.service" ];
+ };
+*/
+};
+systemd.services."wireguard-${iface}" = {
+ after = [ gnupg.secrets."wireguard/${iface}/privateKey".service ];
+ requires = [ gnupg.secrets."wireguard/${iface}/privateKey".service ];
+ unitConfig.Upholds = [ "upnpc-${toString wg.listenPort}.service" ];
};
networking.nftables.ruleset = ''
- # Allow initiating connection for ${wg}
- add rule inet filter fw2net ip daddr ${hosts.mermet.extraArgs.ipv4} udp dport ${toString relay.listenPort} counter accept comment "${wg}"
- #add rule inet filter fw2net udp sport ${toString wireguard."${wg}".listenPort} counter accept comment "${wg}"
- # Allow peers to initiate connection for ${wg}
- #add rule inet filter net2fw udp dport ${toString wireguard."${wg}".listenPort} counter accept comment "${wg}"
+ # Allow initiating connection to and from other peers
+ add rule inet filter fw2net udp sport ${toString wg.listenPort} counter accept comment "WireGuard ${iface} output to peers"
+ add rule inet filter net2fw udp dport ${toString wg.listenPort} counter accept comment "WireGuard ${iface} input from peers"
- # Hook ${wg} into relevant chains
- add rule inet filter input iifname "${wg}" jump intra2fw
- add rule inet filter input iifname "${wg}" log level warn prefix "intra2fw: " counter drop
- add rule inet filter output oifname "${wg}" jump fw2intra
- add rule inet filter output oifname "${wg}" log level warn prefix "fw2intra: " counter drop
+ # Hook ${iface} into relevant chains
+ add rule inet filter input iifname "${iface}" jump intra2fw
+ add rule inet filter input iifname "${iface}" log level warn prefix "intra2fw: " counter drop
+ add rule inet filter output oifname "${iface}" jump fw2intra
+ add rule inet filter output oifname "${iface}" log level warn prefix "fw2intra: " counter drop
- # ${wg} firewalling
+ # ${iface} firewalling
add rule inet filter fw2intra counter accept
- add rule inet filter intra2fw ip saddr ${relay.ipv4} counter accept comment "relay"
- add rule inet filter forward iifname "${wg}" jump fwd-intra
+ ${lib.concatMapStringsSep "\n" (ip: ''
+ add rule inet filter intra2fw ip saddr ${ip} counter accept comment "relay"
+ '') relay.ips}
+ add rule inet filter forward iifname "${iface}" jump fwd-intra
'';
+# Apparently required to get NAT reflection.
+services.upnpc.redirections = [
+ { description = "WireGuard"; externalPort = wg.listenPort; protocol = "UDP"; duration = 30 * 60;
+ service.requiredBy = [ "wireguard-${iface}.service" ];
+ service.before = [ "wireguard-${iface}.service" ];
+ }
+];
boot.kernel.sysctl."net.ipv4.ip_forward" = 1;
-networking.wireguard.interfaces."${wg}" = {
- ips = [ "${wireguard."${wg}".ipv4}/24" ];
- listenPort = wireguard."${wg}".listenPort;
- privateKeyFile = gnupg.secrets."wireguard/${wg}/privateKey".path;
- peers = lib.mapAttrsToList (peerName: host:
- host.extraArgs.wireguard."${wg}".peer //
- { inherit (wireguard."${wg}") persistentKeepalive; }
- ) peers;
-};
-networking.hosts = lib.mapAttrs' (hostName: host: lib.nameValuePair
- host.extraArgs.wireguard."${wg}".ipv4
- [ "${hostName}.intranet" ]
- ) peers;
# Open a wireguard tunnel to a relay
# in case the host is hosted behind a NAT and has no SSH port forwarding.
# This enables to send the disk password to the initrd, like that:
-# ssh -J mermet.sourcephile.fr root@losurdo.intranet -p 2222
-boot.initrd.secrets."/root/initrd/${wg}.key" = "/root/initrd/${wg}.key";
-/*
-installer.ssh-nixos.script = ''
- # Send the wireguard key of the initrd
- gpg --decrypt '${gnupg.store}/wireguard/${wg}/privateKey.gpg' |
- ssh '${config.installer.ssh-nixos.target}' \
- install -D -m 400 -o root -g root /dev/stdin /root/initrd/${wg}.key
-'';
-*/
+# ssh -J mermet.sourcephile.fr root@losurdo.wg -p 2222
+boot.initrd.secrets."/root/initrd/${iface}.key" = "/root/initrd/${iface}.key";
boot.initrd.kernelModules = [ "wireguard" ];
boot.initrd.extraUtilsCommands = ''
#copy_bin_and_libs ${pkgs.wireguard-tools}/bin/wg
cp -fpdv ${pkgs.wireguard-tools}/bin/.wg-wrapped $out/bin/wg
'';
boot.initrd.network.postCommands = ''
- ip link add dev ${wg} type wireguard
- ip address add ${wireguard."${wg}".ipv4}/24 dev ${wg}
- wg set ${wg} private-key /root/initrd/${wg}.key \
- listen-port ${toString wireguard."${wg}".listenPort}
- ip link set up dev ${wg}
- wg set ${wg} peer ${relay.peer.publicKey} \
- endpoint ${hosts.mermet.extraArgs.ipv4}:${toString relay.listenPort} \
+ ip link add dev ${iface} type wireguard
+ ${lib.concatMapStringsSep "\n" (ip: ''
+ ip address add ${ip} dev ${iface}
+ '') wg.ips}
+ wg set ${iface} private-key /root/initrd/${iface}.key \
+ listen-port ${toString wg.listenPort}
+ ip link set up dev ${iface} mtu 1280
+ wg set ${iface} peer ${relay.peer.publicKey} \
+ endpoint ${relay.ipv4}:${toString relay.listenPort} \
allowed-ips ${relay.ipv4}/32 \
persistent-keepalive 5
- ip route replace ${relay.ipv4}/32 dev ${wg} table main
+ ip route replace ${relay.ipv4}/32 dev ${iface} table main
'';
boot.initrd.postMountCommands = lib.mkIf initrd.network.flushBeforeStage2 ''
- ip link del dev ${wg}
+ ip link del dev ${iface}
'';
}