150 lines
4.9 KiB
Nix
150 lines
4.9 KiB
Nix
{ config
|
|
, pkgs
|
|
, lib
|
|
, ...
|
|
}:
|
|
{
|
|
sops.secrets = {
|
|
"wg_privkey" = {
|
|
sopsFile = ./secrets/wg_privkey.yaml;
|
|
};
|
|
|
|
"wg_preshared/nixy" = {
|
|
sopsFile = ../common/secrets/wg_preshared.yaml;
|
|
};
|
|
|
|
"wg_privkey_proton" = {
|
|
sopsFile = ./secrets/wg_privkey_proton.yaml;
|
|
};
|
|
|
|
"wg_endpoint_proton" = {
|
|
sopsFile = ./secrets/wg_privkey_proton.yaml;
|
|
};
|
|
};
|
|
|
|
# Personal mesh: dials into the magpie hub (10.100.0.0/24)
|
|
networking.wireguard.interfaces = {
|
|
wg0 = {
|
|
ips = [ "10.100.0.6/24" ];
|
|
privateKeyFile = config.sops.secrets."wg_privkey".path;
|
|
peers = [
|
|
{
|
|
publicKey = builtins.readFile ../magpie/wg_pubkey;
|
|
presharedKeyFile = config.sops.secrets."wg_preshared/nixy".path;
|
|
allowedIPs = [ "10.100.0.0/24" ];
|
|
endpoint = "5.75.229.224:51820";
|
|
persistentKeepalive = 25;
|
|
}
|
|
];
|
|
};
|
|
};
|
|
|
|
systemd = {
|
|
services = {
|
|
# ProtonVPN split tunnel: proton_wg lives inside the `wg` network
|
|
# namespace; anything that should egress over Proton is launched
|
|
# with `ip netns exec wg ...`.
|
|
"netns@" = {
|
|
description = "%I network namespace";
|
|
before = [ "network.target" ];
|
|
serviceConfig = {
|
|
Type = "oneshot";
|
|
RemainAfterExit = true;
|
|
ExecStart = "${pkgs.iproute2}/bin/ip netns add %I";
|
|
ExecStop = "${pkgs.iproute2}/bin/ip netns del %I";
|
|
};
|
|
};
|
|
|
|
"wg_proton" = {
|
|
description = "wg network interface";
|
|
bindsTo = [ "netns@wg.service" ];
|
|
requires = [ "network-online.target" ];
|
|
wants = [ "dnscrypt-proxy_proton.service" ];
|
|
after = [ "netns@wg.service" ];
|
|
before = [ "dnscrypt-proxy_proton.service" ];
|
|
serviceConfig = {
|
|
Type = "oneshot";
|
|
RemainAfterExit = true;
|
|
ExecStart = pkgs.writers.writeBash "wg-up" ''
|
|
set -e
|
|
ENDPOINT_IP=$(${pkgs.coreutils-full}/bin/cat "${config.sops.secrets."wg_endpoint_proton".path}")
|
|
${pkgs.iproute2}/bin/ip link add proton_wg type wireguard
|
|
${pkgs.iproute2}/bin/ip link set proton_wg netns wg
|
|
${pkgs.iproute2}/bin/ip -n wg address add 10.2.0.2/32 dev proton_wg
|
|
${pkgs.iproute2}/bin/ip netns exec wg \
|
|
${pkgs.wireguard-tools}/bin/wg set "proton_wg" private-key "${
|
|
config.sops.secrets."wg_privkey_proton".path
|
|
}"
|
|
${pkgs.iproute2}/bin/ip netns exec wg \
|
|
${pkgs.wireguard-tools}/bin/wg set "proton_wg" peer "${lib.fileContents ../common/wg_pubkey_proton}" \
|
|
endpoint "$ENDPOINT_IP:51820" \
|
|
persistent-keepalive "25" \
|
|
allowed-ips "0.0.0.0/0"
|
|
${pkgs.iproute2}/bin/ip -n wg link set lo up
|
|
${pkgs.iproute2}/bin/ip -n wg link set proton_wg up
|
|
${pkgs.iproute2}/bin/ip -n wg route add default dev proton_wg
|
|
'';
|
|
ExecStop = pkgs.writers.writeBash "wg-down" ''
|
|
${pkgs.iproute2}/bin/ip -n wg route del default dev proton_wg
|
|
${pkgs.iproute2}/bin/ip -n wg link del proton_wg
|
|
'';
|
|
};
|
|
};
|
|
|
|
"dnscrypt-proxy_proton" = {
|
|
description = "DNSCrypt-proxy client proton";
|
|
wants = [
|
|
"network-online.target"
|
|
"nss-lookup.target"
|
|
];
|
|
before = [ "nss-lookup.target" ];
|
|
after = [ "wg_proton.service" ];
|
|
partOf = [ "wg_proton.service" ];
|
|
serviceConfig = {
|
|
AmbientCapabilities = "CAP_NET_BIND_SERVICE";
|
|
CacheDirectory = "dnscrypt-proxy";
|
|
DynamicUser = true;
|
|
ExecStart = "${pkgs.dnscrypt-proxy}/bin/dnscrypt-proxy -config ${config.services.dnscrypt-proxy.configFile}";
|
|
LockPersonality = true;
|
|
LogsDirectory = "dnscrypt-proxy";
|
|
MemoryDenyWriteExecute = true;
|
|
NetworkNamespacePath = "/var/run/netns/wg";
|
|
NonBlocking = true;
|
|
NoNewPrivileges = true;
|
|
PrivateDevices = true;
|
|
ProtectClock = true;
|
|
ProtectControlGroups = true;
|
|
ProtectHome = true;
|
|
ProtectHostname = true;
|
|
ProtectKernelLogs = true;
|
|
ProtectKernelModules = true;
|
|
ProtectKernelTunables = true;
|
|
ProtectSystem = "strict";
|
|
Restart = "always";
|
|
RestrictAddressFamilies = [
|
|
"AF_INET"
|
|
"AF_INET6"
|
|
];
|
|
RestrictNamespaces = true;
|
|
RestrictRealtime = true;
|
|
RuntimeDirectory = "dnscrypt-proxy";
|
|
StateDirectory = "dnscrypt-proxy";
|
|
SystemCallArchitectures = "native";
|
|
SystemCallFilter = [
|
|
"@system-service"
|
|
"@chown"
|
|
"~@aio"
|
|
"~@keyring"
|
|
"~@memlock"
|
|
"~@setuid"
|
|
"~@timer"
|
|
];
|
|
};
|
|
};
|
|
};
|
|
|
|
# Don't bring wg0 up at boot
|
|
targets."wireguard-wg0".wantedBy = lib.mkForce [ ];
|
|
};
|
|
}
|