]> Git — Sourcephile - julm/julm-nix.git/blob - nixos/profiles/wireguard/wg-intra.nix
creds: move creds-* scripts to a NixOS module
[julm/julm-nix.git] / nixos / profiles / wireguard / wg-intra.nix
1 { inputs, pkgs, lib, config, hostName, ... }:
2 let
3 wgIface = "wg-intra";
4 peers = import wg-intra/peers.nix;
5 wg = config.networking.wireguard.interfaces.${wgIface};
6 in
7 {
8 # Each peer select the other peers allowed to connect to it
9 options.networking.wireguard.${wgIface}.peers =
10 lib.genAttrs (lib.attrNames peers) (peerName: {
11 enable = lib.mkEnableOption "this peer";
12 });
13 config = {
14 systemd.services."wireguard-${wgIface}".serviceConfig.LoadCredentialEncrypted =
15 [ ("privateKey:${inputs.self}/hosts/${hostName}/wireguard/${wgIface}/privateKey.cred") ];
16 networking.wireguard.interfaces.${wgIface} = lib.recursiveUpdate
17 (removeAttrs peers.${hostName} ["ipv4" "persistentKeepalive" "peer"])
18 {
19 peers =
20 lib.mapAttrsToList (peerName: peer:
21 lib.recursiveUpdate
22 {
23 persistentKeepalive =
24 peer.persistentKeepalive # Useful if this peer is behind a NAT
25 or peers.${hostName}.persistentKeepalive # Useful if this host is behind a NAT
26 or null;
27 }
28 peer.peer)
29 (removeAttrs
30 (lib.filterAttrs (peerName: _: config.networking.wireguard.${wgIface}.peers.${peerName}.enable) peers)
31 [hostName]);
32 privateKeyFile = "$CREDENTIALS_DIRECTORY/privateKey";
33
34 # Set the MTU to a minimum
35 # (IPv4 requires at least 68 but it's 1280 for IPv6).
36 # This prevents connections to stall on huge packets,
37 # or delaying their initializing due to TCP PMTU probing.
38 postSetup = ''
39 ip link set dev ${wgIface} mtu 1280
40 '';
41 };
42 networking.hosts = lib.mkMerge [
43 (lib.mapAttrs' (hostName: host:
44 lib.nameValuePair host.ipv4 [ "${hostName}.wg" ]) peers)
45 {
46 "${peers.losurdo.ipv4}" = [
47 "nix-extracache.losurdo.wg"
48 "nix-localcache.losurdo.wg"
49 "sftp.losurdo.wg"
50 ];
51 }
52 ];
53 networking.firewall.extraCommands = lib.optionalString (wg.listenPort != null) ''
54 ip46tables -A nixos-fw -i any -p udp -m udp --dport ${toString wg.listenPort} -j ACCEPT
55 '';
56
57 networking.nftables.ruleset = lib.optionalString (wg.listenPort != null) ''
58 table inet filter {
59 chain input-lan {
60 udp dport ${toString wg.listenPort} counter accept \
61 comment "Wireguard ${wgIface} input from peers"
62 }
63 chain input-net {
64 udp dport ${toString wg.listenPort} counter accept \
65 comment "Wireguard ${wgIface} input from peers"
66 }
67 chain input-intra {
68 ${lib.optionalString (peers.${hostName}.peer.endpointsUpdater.enable or false) ''
69 tcp dport ${toString peers.${hostName}.listenPort} ip daddr ${peers.${hostName}.ipv4} counter accept comment "Wireguard ${wgIface} from peers to endpointUpdater"
70 ''
71 }
72 }
73 chain input {
74 iifname ${wgIface} jump input-intra
75 iifname ${wgIface} log level warn prefix "input-intra: " counter drop
76 }
77
78 chain output-lan {
79 udp sport ${toString wg.listenPort} counter accept \
80 comment "Wireguard ${wgIface} output to peers"
81 }
82 chain output-net {
83 udp sport ${toString wg.listenPort} counter accept \
84 comment "Wireguard ${wgIface} output to peers"
85 }
86 chain output-intra {
87 ${lib.concatStringsSep "\n"
88 (lib.mapAttrsToList (peerName: peer: ''
89 ip daddr ${peer.ipv4} \
90 tcp dport ${toString peer.listenPort} \
91 counter accept \
92 comment "Wireguard ${wgIface} to endpointUpdater ${peerName}"
93 '')
94 (lib.filterAttrs (peerName: peer:
95 config.networking.wireguard.${wgIface}.peers.${peerName}.enable &&
96 (peers.${peerName}.peer.endpointsUpdater.enable or false))
97 peers))
98 }
99 }
100 chain output {
101 oifname ${wgIface} jump output-intra
102 oifname ${wgIface} log level warn prefix "output-intra: " counter drop
103 }
104 }
105 '';
106
107 services.fail2ban.ignoreIP = lib.concatMap
108 (host: host.peer.allowedIPs)
109 (lib.attrValues peers);
110 networking.networkmanager.unmanaged = [ wgIface ];
111 systemd.services.sshd.after = ["wireguard-${wgIface}.service"];
112 services.openssh.listenAddresses = [
113 { addr = peers.${hostName}.ipv4; port = 22; }
114 ];
115 };
116 }