-{ pkgs, lib, config, hostName, private, ... }:
+{ pkgs, lib, config, hostName, credentials, ... }:
let
iface = "wg-intra";
- hosts = import wg-intra/hosts.nix;
+ peers = import wg-intra/peers.nix;
wg = config.networking.wireguard.interfaces.${iface};
in
{
+# Each peer select the other peers allowed to connect to it
+options.networking.wireguard.${iface}.peers =
+ lib.genAttrs (lib.attrNames peers) (peerName: {
+ enable = lib.mkEnableOption "this peer";
+ });
+config = {
+systemd.services."wireguard-${iface}".serviceConfig.LoadCredentialEncrypted = "privateKey:${credentials}/wireguard/${iface}/privateKey.secret";
networking.wireguard.interfaces.${iface} = lib.recursiveUpdate
- (removeAttrs hosts.${hostName} ["ipv4" "persistentKeepalive" "peer"])
+ (removeAttrs peers.${hostName} ["ipv4" "persistentKeepalive" "peer"])
{
peers =
- lib.mapAttrsToList (peerName: peer: lib.recursiveUpdate
- { persistentKeepalive =
- peer.persistentKeepalive # Useful if this peer is behind a NAT
- or hosts.${hostName}.persistentKeepalive # Useful if this host is behind a NAT
- or null; }
- peer.peer
- ) (removeAttrs hosts [hostName]);
- privateKeyFile = lib.mkDefault "${private}/${hostName}/wireguard/${iface}/privateKey";
+ lib.mapAttrsToList (peerName: peer:
+ lib.recursiveUpdate
+ {
+ persistentKeepalive =
+ peer.persistentKeepalive # Useful if this peer is behind a NAT
+ or peers.${hostName}.persistentKeepalive # Useful if this host is behind a NAT
+ or null;
+ }
+ peer.peer)
+ (removeAttrs
+ (lib.filterAttrs (peerName: _: config.networking.wireguard.${iface}.peers.${peerName}.enable) peers)
+ [hostName]);
+ privateKeyFile = "$CREDENTIALS_DIRECTORY/privateKey";
# Set the MTU to a minimum
# (IPv4 requires at least 68 but it's 1280 for IPv6).
};
networking.hosts = lib.mkMerge [
(lib.mapAttrs' (hostName: host:
- lib.nameValuePair host.ipv4 [ "${hostName}.wg" ]) hosts)
- { "${hosts.losurdo.ipv4}" = [
- "nix-extracache.losurdo.wg"
- "nix-localcache.losurdo.wg"
- ]; }
+ lib.nameValuePair host.ipv4 [ "${hostName}.wg" ]) peers)
+ {
+ "${peers.losurdo.ipv4}" = [
+ "nix-extracache.losurdo.wg"
+ "nix-localcache.losurdo.wg"
+ "sftp.losurdo.wg"
+ ];
+ }
];
-networking.firewall.extraCommands = ''
- ip46tables -A nixos-fw -i ${iface} -p tcp -m tcp --dport 22 -j ACCEPT
-'' + lib.optionalString (wg.listenPort != null) ''
+networking.firewall.extraCommands = lib.optionalString (wg.listenPort != null) ''
ip46tables -A nixos-fw -i any -p udp -m udp --dport ${toString wg.listenPort} -j ACCEPT
'';
+
+networking.nftables.ruleset = lib.optionalString (wg.listenPort != null) ''
+ table inet filter {
+ chain input-lan {
+ udp dport ${toString wg.listenPort} counter accept comment "Wireguard ${iface} input from peers"
+ }
+ chain input-net {
+ udp dport ${toString wg.listenPort} counter accept comment "Wireguard ${iface} input from peers"
+ }
+ chain input-intra {
+ ${lib.optionalString (peers.${hostName}.peer.endpointsUpdater.enable or false) ''
+ tcp dport ${toString peers.${hostName}.listenPort} ip daddr ${peers.${hostName}.ipv4} counter accept comment "Wireguard ${iface} from peers to endpointUpdater"
+ ''
+ }
+ }
+ chain input {
+ iifname ${iface} jump input-intra
+ iifname ${iface} log level warn prefix "input-intra: " counter drop
+ }
+
+ chain output-lan {
+ udp sport ${toString wg.listenPort} counter accept comment "Wireguard ${iface} output to peers"
+ }
+ chain output-net {
+ udp sport ${toString wg.listenPort} counter accept comment "Wireguard ${iface} output to peers"
+ }
+ chain output-intra {
+ ${lib.concatStringsSep "\n"
+ (lib.mapAttrsToList (peerName: peer: ''
+ tcp dport ${toString peer.listenPort} ip daddr ${peer.ipv4} counter accept comment "Wireguard ${iface} to endpointUpdater ${peerName}"
+ '')
+ (lib.filterAttrs (peerName: peer:
+ config.networking.wireguard.${iface}.peers.${peerName}.enable &&
+ (peers.${peerName}.peer.endpointsUpdater.enable or false))
+ peers))
+ }
+ }
+ chain output {
+ oifname ${iface} jump output-intra
+ oifname ${iface} log level warn prefix "output-intra: " counter drop
+ }
+ }
+'';
+
services.fail2ban.ignoreIP = lib.concatMap
(host: host.peer.allowedIPs)
- (lib.attrValues hosts);
+ (lib.attrValues peers);
+networking.networkmanager.unmanaged = ["wg-intra"];
+};
}