mirror of
https://github.com/Swarsel/.dotfiles.git
synced 2025-12-06 00:57:22 +01:00
176 lines
6.8 KiB
Nix
176 lines
6.8 KiB
Nix
{ self, lib, pkgs, config, confLib, nodes, globals, ... }:
|
|
let
|
|
wgInterface = "wg0";
|
|
inherit (confLib.gen { name = "wireguard"; port = 52829; user = "systemd-network"; group = "systemd-network"; }) servicePort serviceName serviceUser serviceGroup;
|
|
|
|
inherit (config.swarselsystems) sopsFile;
|
|
wgSopsFile = self + "/secrets/repo/wg.yaml";
|
|
inherit (config.swarselsystems.server.wireguard) peers isClient isServer serverName serverNetConfigPrefix ifName;
|
|
in
|
|
{
|
|
options = {
|
|
swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} settings";
|
|
swarselsystems.server.wireguard = {
|
|
isServer = lib.mkEnableOption "set this as a wireguard server";
|
|
isClient = lib.mkEnableOption "set this as a wireguard client";
|
|
serverName = lib.mkOption {
|
|
type = lib.types.str;
|
|
default = "";
|
|
};
|
|
serverNetConfigPrefix = lib.mkOption {
|
|
type = lib.types.str;
|
|
default = "${if nodes.${serverName}.config.swarselsystems.isCloud then nodes.${serverName}.config.node.name else "home"}";
|
|
readOnly = true;
|
|
};
|
|
ifName = lib.mkOption {
|
|
type = lib.types.str;
|
|
default = wgInterface;
|
|
};
|
|
peers = lib.mkOption {
|
|
type = lib.types.listOf lib.types.str;
|
|
default = [ ];
|
|
description = "Wireguard peer config names";
|
|
};
|
|
};
|
|
|
|
};
|
|
config = lib.mkIf config.swarselmodules.server.${serviceName} {
|
|
|
|
environment.systemPackages = with pkgs; [
|
|
wireguard-tools
|
|
];
|
|
|
|
sops = {
|
|
secrets = {
|
|
wireguard-private-key = { inherit sopsFile; owner = serviceUser; group = serviceGroup; mode = "0600"; };
|
|
# create this secret only if this is a simple client with only one peer (the server)
|
|
"wireguard-${serverName}-${config.node.name}-presharedKey" = lib.mkIf (isClient && peers == [ ]) { sopsFile = wgSopsFile; owner = serviceUser; group = serviceGroup; mode = "0600"; };
|
|
}
|
|
# create these secrets only if this host has multiple peers
|
|
// lib.optionalAttrs (peers != [ ]) (builtins.listToAttrs (map
|
|
(clientName: {
|
|
name = "wireguard-${config.node.name}-${clientName}-presharedKey";
|
|
value = { sopsFile = wgSopsFile; owner = serviceUser; group = serviceGroup; mode = "0600"; };
|
|
})
|
|
peers));
|
|
};
|
|
|
|
networking = {
|
|
firewall.checkReversePath = lib.mkIf isClient "loose";
|
|
firewall.allowedUDPPorts = [ servicePort ];
|
|
# nat = lib.mkIf (config.swarselsystems.isCloud && isServer) {
|
|
# enable = true;
|
|
# enableIPv6 = true;
|
|
# externalInterface = "enp0s6";
|
|
# internalInterfaces = [ ifName ];
|
|
# };
|
|
# interfaces.${ifName}.mtu = 1280; # the default (1420) is not enough!
|
|
};
|
|
|
|
systemd.network = {
|
|
enable = true;
|
|
|
|
networks."50-${ifName}" = {
|
|
matchConfig.Name = ifName;
|
|
linkConfig = {
|
|
MTUBytes = 1408; # TODO: figure out where we lose those 12 bits (8 from pppoe maybe + ???)
|
|
};
|
|
|
|
# networkConfig = lib.mkIf (config.swarselsystems.isCloud && isServer) {
|
|
# IPv4Forwarding = true;
|
|
# IPv6Forwarding = true;
|
|
# };
|
|
|
|
address =
|
|
if isServer then [
|
|
globals.networks."${config.swarselsystems.server.netConfigPrefix}-wg".hosts.${config.node.name}.cidrv4
|
|
globals.networks."${config.swarselsystems.server.netConfigPrefix}-wg".hosts.${config.node.name}.cidrv6
|
|
] else [
|
|
globals.networks."${serverNetConfigPrefix}-wg".hosts.${config.node.name}.cidrv4
|
|
globals.networks."${serverNetConfigPrefix}-wg".hosts.${config.node.name}.cidrv6
|
|
];
|
|
};
|
|
|
|
netdevs."50-${ifName}" = {
|
|
netdevConfig = {
|
|
Kind = "wireguard";
|
|
Name = ifName;
|
|
};
|
|
|
|
wireguardConfig = {
|
|
ListenPort = lib.mkIf isServer servicePort;
|
|
|
|
# ensure file is readable by `systemd-network` user
|
|
PrivateKeyFile = config.sops.secrets.wireguard-private-key.path;
|
|
|
|
# To automatically create routes for everything in AllowedIPs,
|
|
# add RouteTable=main
|
|
RouteTable = lib.mkIf isClient "main";
|
|
|
|
# FirewallMark marks all packets send and received by wg0
|
|
# with the number 42, which can be used to define policy rules on these packets.
|
|
# FirewallMark = 42;
|
|
};
|
|
wireguardPeers = lib.optionals isClient [
|
|
{
|
|
PublicKey = builtins.readFile "${self}/secrets/public/wg/${serverName}.pub";
|
|
PresharedKeyFile = config.sops.secrets."wireguard-${serverName}-${config.node.name}-presharedKey".path;
|
|
Endpoint = "server.${serverName}.${globals.domains.main}:${toString servicePort}";
|
|
# Access to the whole network is routed through our entry node.
|
|
# PersistentKeepalive = 25;
|
|
AllowedIPs =
|
|
let
|
|
wgNetwork = globals.networks."${serverNetConfigPrefix}-wg";
|
|
in
|
|
(lib.optional (wgNetwork.cidrv4 != null) wgNetwork.cidrv4)
|
|
++ (lib.optional (wgNetwork.cidrv6 != null) wgNetwork.cidrv6);
|
|
}
|
|
] ++ lib.optionals isServer (map
|
|
(clientName: {
|
|
PublicKey = builtins.readFile "${self}/secrets/public/wg/${clientName}.pub";
|
|
PresharedKeyFile = config.sops.secrets."wireguard-${config.node.name}-${clientName}-presharedKey".path;
|
|
# PersistentKeepalive = 25;
|
|
AllowedIPs =
|
|
let
|
|
clientInWgNetwork = globals.networks."${config.swarselsystems.server.netConfigPrefix}-wg".hosts.${clientName};
|
|
in
|
|
(lib.optional (clientInWgNetwork.ipv4 != null) (lib.net.cidr.make 32 clientInWgNetwork.ipv4))
|
|
++ (lib.optional (clientInWgNetwork.ipv6 != null) (lib.net.cidr.make 128 clientInWgNetwork.ipv6));
|
|
})
|
|
peers);
|
|
|
|
};
|
|
};
|
|
|
|
# networking = {
|
|
# wireguard = {
|
|
# enable = true;
|
|
# interfaces = {
|
|
# wg1 = {
|
|
# privateKeyFile = config.sops.secrets.wireguard-private-key.path;
|
|
# ips = [ "192.168.178.201/24" ];
|
|
# peers = [
|
|
# {
|
|
# publicKey = "PmeFInoEJcKx+7Kva4dNnjOEnJ8lbudSf1cbdo/tzgw=";
|
|
# presharedKeyFile = config.sops.secrets.wireguard-home-preshared-key.path;
|
|
# name = "moonside";
|
|
# persistentKeepalive = 25;
|
|
# # endpoint = "${config.repo.secrets.common.ipv4}:51820";
|
|
# endpoint = "${config.repo.secrets.common.wireguardEndpoint}";
|
|
# # allowedIPs = [
|
|
# # "192.168.3.0/24"
|
|
# # "192.168.1.0/24"
|
|
# # ];
|
|
# allowedIPs = [
|
|
# "192.168.178.0/24"
|
|
# ];
|
|
# }
|
|
# ];
|
|
# };
|
|
# };
|
|
# };
|
|
# };
|
|
|
|
|
|
};
|
|
}
|