]> Git — Sourcephile - sourcephile-nix.git/blob - hosts/losurdo/networking/wireguard/intranet.nix
nix: update nixpkgs
[sourcephile-nix.git] / hosts / losurdo / networking / wireguard / intranet.nix
1 { pkgs, lib, config, inputs, ... }:
2 let
3 inherit (config.security) gnupg;
4 inherit (config.boot) initrd;
5 iface = "wg-intra";
6 wg = config.networking.wireguard.interfaces.${iface};
7 wg-intra-peers = import (inputs.julm-nix + "/nixos/profiles/wireguard/wg-intra/peers.nix");
8 relay = wg-intra-peers.mermet;
9 in
10 {
11 imports = [
12 (inputs.julm-nix + "/nixos/profiles/wireguard/wg-intra.nix")
13 ];
14 networking.wireguard.${iface}.peers = {
15 mermet.enable = true;
16 oignon.enable = true;
17 patate.enable = true;
18 carotte.enable = true;
19 };
20 networking.wireguard.interfaces.${iface} = {
21 privateKeyFile = gnupg.secrets."wireguard/${iface}/privateKey".path;
22 };
23 security.gnupg.secrets."wireguard/${iface}/privateKey" = {
24 /*
25 systemdConfig.serviceConfig = {
26 before = [ "wireguard-${iface}.service" ];
27 wantedBy = [ "wireguard-${iface}.service" ];
28 requiredBy = [ "wireguard-${iface}.service" ];
29 };
30 */
31 };
32 systemd.services."wireguard-${iface}" = {
33 after = [ gnupg.secrets."wireguard/${iface}/privateKey".service ];
34 requires = [ gnupg.secrets."wireguard/${iface}/privateKey".service ];
35 unitConfig.Upholds = [ "upnpc-${toString wg.listenPort}.service" ];
36 };
37 networking.nftables.ruleset = ''
38 # Allow initiating connection to and from other peers
39 add rule inet filter fw2net udp sport ${toString wg.listenPort} counter accept comment "WireGuard ${iface} output to peers"
40 add rule inet filter net2fw udp dport ${toString wg.listenPort} counter accept comment "WireGuard ${iface} input from peers"
41
42 # Hook ${iface} into relevant chains
43 add rule inet filter input iifname "${iface}" jump intra2fw
44 add rule inet filter input iifname "${iface}" log level warn prefix "intra2fw: " counter drop
45 add rule inet filter output oifname "${iface}" jump fw2intra
46 add rule inet filter output oifname "${iface}" log level warn prefix "fw2intra: " counter drop
47
48 # ${iface} firewalling
49 add rule inet filter fw2intra counter accept
50 ${lib.concatMapStringsSep "\n" (ip: ''
51 add rule inet filter intra2fw ip saddr ${ip} counter accept comment "relay"
52 '') relay.ips}
53 add rule inet filter forward iifname "${iface}" jump fwd-intra
54 '';
55 # Apparently required to get NAT reflection.
56 services.upnpc.redirections = [
57 { description = "WireGuard"; externalPort = wg.listenPort; protocol = "UDP"; duration = 30 * 60;
58 service.requiredBy = [ "wireguard-${iface}.service" ];
59 service.before = [ "wireguard-${iface}.service" ];
60 }
61 ];
62 boot.kernel.sysctl."net.ipv4.ip_forward" = 1;
63
64 # Open a wireguard tunnel to a relay
65 # in case the host is hosted behind a NAT and has no SSH port forwarding.
66 # This enables to send the disk password to the initrd, like that:
67 # ssh -J mermet.sourcephile.fr root@losurdo.wg -p 2222
68 boot.initrd.secrets."/root/initrd/${iface}.key" = "/root/initrd/${iface}.key";
69 boot.initrd.kernelModules = [ "wireguard" ];
70 boot.initrd.extraUtilsCommands = ''
71 #copy_bin_and_libs ${pkgs.wireguard-tools}/bin/wg
72 cp -fpdv ${pkgs.wireguard-tools}/bin/.wg-wrapped $out/bin/wg
73 '';
74 boot.initrd.network.postCommands = ''
75 ip link add dev ${iface} type wireguard
76 ${lib.concatMapStringsSep "\n" (ip: ''
77 ip address add ${ip} dev ${iface}
78 '') wg.ips}
79 wg set ${iface} private-key /root/initrd/${iface}.key \
80 listen-port ${toString wg.listenPort}
81 ip link set up dev ${iface} mtu 1280
82 wg set ${iface} peer ${relay.peer.publicKey} \
83 endpoint ${relay.ipv4}:${toString relay.listenPort} \
84 allowed-ips ${relay.ipv4}/32 \
85 persistent-keepalive 5
86 ip route replace ${relay.ipv4}/32 dev ${iface} table main
87 '';
88 boot.initrd.postMountCommands = lib.mkIf initrd.network.flushBeforeStage2 ''
89 ip link del dev ${iface}
90 '';
91 }