nixos-config/modules/wireguard/home.nix

181 lines
5.2 KiB
Nix

{ lib, config, machines, pkgs, ... }:
let
serverHostName = "vueko";
serverPort = 51820;
peers = {
hitagi = {
address = "10.80.0.5";
publicKey = "t7hpd2yZupAKHxYerHtXnlPRUjV1aGbrrzjYakKdOwE=";
};
vueko = {
address = "10.80.0.6";
publicKey = "JbOfL4FxPCzJOjI8AGklPHY2FniCXq0QwOa08gjSyns=";
};
fuuko = {
address = "10.80.0.7";
publicKey = "VXic8mhaJBSl6yFkx0Cu6JI8tqqjjM3UbW7x+05pV0M=";
};
mayushii = {
address = "10.80.0.9";
publicKey = "nnLdgywXmDg8HWH6I0G28Z2zb4OmmyFDpnvvEBzKJTg=";
};
renge = {
address = "10.80.0.11";
publicKey = "RlLs/uiWb9qaBU2iDgRag7Q+FFaR7oHI3yOPLZPKgmA=";
};
nunotaba = {
address = "10.80.0.4";
publicKey = "LscDAJR0IjOzNuwX3geYgcvxyvaNhAOc/ojgvGyunT8=";
};
};
cfg = config.sbruder.wireguard.home;
enableServer = config.networking.hostName == serverHostName;
in
{
options = {
sbruder.wireguard.home = {
enable = lib.mkEnableOption "WireGuard tunnel wg-home";
address = lib.mkOption {
type = lib.types.str;
visible = false;
readOnly = true;
};
};
};
config = lib.mkIf cfg.enable {
sops.secrets.wg-home-private-key = {
owner = config.users.users.systemd-network.name;
sopsFile = ./../../machines + "/${config.networking.hostName}/secrets.yaml";
};
sbruder.wireguard.home.address = peers."${config.networking.hostName}".address;
systemd.network = {
enable = true;
netdevs = {
wg-home = {
netdevConfig = {
Kind = "wireguard";
Name = "wg-home";
};
wireguardConfig = {
PrivateKeyFile = config.sops.secrets.wg-home-private-key.path;
} // (lib.optionalAttrs enableServer {
ListenPort = serverPort;
});
wireguardPeers =
if enableServer
then
map
(peerConfig: with peerConfig; {
wireguardPeerConfig = {
PublicKey = publicKey;
AllowedIPs = [ "${address}/32" ];
};
})
(lib.attrValues
(lib.filterAttrs
(n: v: n != config.networking.hostName)
peers))
else [
{
wireguardPeerConfig = {
PublicKey = peers."${serverHostName}".publicKey;
AllowedIPs = [ "10.80.0.0/24" ];
#Endpoint = "${serverHostName}.sbruder.de:${toString serverPort}"; # not possible because sadly not all devices have IPv6 connectivity
Endpoint = "195.201.139.15:${toString serverPort}";
PersistentKeepalive = 25;
};
}
];
};
};
networks = {
wg-home = {
name = "wg-home";
address = lib.singleton "${config.sbruder.wireguard.home.address}/24";
networkConfig = lib.optionalAttrs enableServer {
IPForward = "ipv4";
};
};
};
};
networking.firewall = {
trustedInterfaces = [ "wg-home" ];
allowedUDPPorts = lib.optionals enableServer [
serverPort
53
];
};
services.bind = lib.mkIf enableServer {
enable = true;
zones = lib.singleton {
name = "vpn.sbruder.de";
master = true;
file =
let
# !!! very hacky
hexStringToInt = hex: (builtins.fromTOML "int = 0x${hex}").int;
peerRecords = lib.concatStrings
(lib.mapAttrsToList
(peer: peerConfig: ''
${peer} IN A ${peerConfig.address}
'')
peers);
peerRecordsHash = builtins.hashString "sha256" peerRecords;
serial = hexStringToInt (lib.substring 0 8 peerRecordsHash);
in
pkgs.writeText "vpn.sbruder.de.zone" (''
$TTL 3600
@ IN SOA ${serverHostName}.sbruder.de. hostmaster.sbruder.de. ${toString serial} 28800 3600 604800 3600
@ IN NS ${serverHostName}.sbruder.de.
@ IN A ${peers.${serverHostName}.address}
'' + peerRecords);
};
};
services.nginx = lib.mkIf enableServer {
virtualHosts."vpn.sbruder.de" = {
root =
let
templateData = {
machines = lib.mapAttrs
(machine: { config, ... }: {
syncthing = if config.services.syncthing.enable then 8384 else null;
})
machines;
};
in
pkgs.stdenv.mkDerivation {
name = "vpn-home";
src = ./home;
nativeBuildInputs = with pkgs; [ j2cli ];
buildPhase = ''
runHook preBuild
j2 -f json -o index.html index.html.j2 - << EOF
${builtins.toJSON templateData}
EOF
runHook postBuild
'';
installPhase = ''
runHook preInstall
install -D index.html $out/index.html
install -D style.css $out/style.css
runHook postInstall
'';
};
};
};
};
}