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