tailscale + wg-quick on clients

This commit is contained in:
Dmitriy Kholkin 2023-07-05 20:42:56 +03:00
parent eb1d4b6a49
commit a1f6e3d7f5
4 changed files with 126 additions and 64 deletions

View File

@ -44,10 +44,12 @@
deviceSpecific.isShared = false; deviceSpecific.isShared = false;
deviceSpecific.isGaming = true; deviceSpecific.isGaming = true;
deviceSpecific.enableVirtualisation = true; deviceSpecific.enableVirtualisation = true;
deviceSpecific.vpn.mullvad.enable = false; # VPN
deviceSpecific.vpn.ivpn.enable = true; deviceSpecific.vpn.tailscale.enable = true;
# hardware.firmware = [ pkgs.rtl8761b-firmware ]; secrets.wg-ataraxia.services = [ "wg-quick-wg0.service" ];
networking.wg-quick.interfaces.wg0.configFile = config.secrets.wg-ataraxia.decrypted;
hardware.firmware = [ pkgs.rtl8761b-firmware ];
programs.nix-ld.enable = true; programs.nix-ld.enable = true;
secrets.files-veracrypt = { }; secrets.files-veracrypt = { };
@ -101,14 +103,4 @@
persist.state.homeDirectories = [ ".local/share/winbox" ]; persist.state.homeDirectories = [ ".local/share/winbox" ];
system.stateVersion = "23.05"; system.stateVersion = "23.05";
secrets.wg-ataraxia.services = [ "wg-quick-wg0.service" ];
networking.wg-quick.interfaces.wg0 = {
autostart = false;
configFile = config.secrets.wg-ataraxia.decrypted;
};
services.tailscale.enable = true;
services.tailscale.useRoutingFeatures = "client";
persist.state.directories = [ "/var/lib/tailscale" ];
} }

View File

@ -25,7 +25,9 @@
}; };
deviceSpecific.isGaming = false; deviceSpecific.isGaming = false;
deviceSpecific.enableVirtualisation = true; deviceSpecific.enableVirtualisation = true;
deviceSpecific.vpn.ivpn.enable = true; deviceSpecific.vpn.tailscale.enable = true;
secrets.wg-dell.services = [ "wg-quick-wg0.service" ];
networking.wg-quick.interfaces.wg0.configFile = config.secrets.wg-dell.decrypted;
boot.blacklistedKernelModules = [ boot.blacklistedKernelModules = [
"psmouse" "psmouse"
@ -33,14 +35,6 @@
services.fwupd.enable = true; services.fwupd.enable = true;
# systemd.services.unbind-usb2 = {
# wantedBy = [ "multi-user.target" ];
# serviceConfig = {
# ExecStart = "${pkgs.coreutils}/bin/echo 'usb2' | ${pkgs.coreutils}/bin/tee /sys/bus/usb/drivers/usb/unbind";
# Type = "oneshot";
# };
# };
services.tlp = { services.tlp = {
enable = true; enable = true;
settings = { settings = {

View File

@ -89,6 +89,60 @@ with types; {
type = bool; type = bool;
default = false; default = false;
}; };
wireguard = {
enable = mkOption {
type = bool;
default = false;
};
autostart = mkOption {
type = bool;
default = false;
};
port = mkOption {
type = int;
default = 51820;
};
endpoint = mkOption {
type = str;
default = "";
};
address = mkOption {
type = listOf str;
default = [];
};
allowedIPs = mkOption {
type = listOf str;
default = [];
};
dns = mkOption {
type = listOf str;
default = [];
};
gateway = {
ipv4 = mkOption {
type = nullOr str;
default = null;
};
ipv6 = mkOption {
type = nullOr str;
default = null;
};
};
keys = {
public = mkOption {
type = nullOr str;
default = null;
};
presharedFile = mkOption {
type = nullOr path;
default = null;
};
privateFile = mkOption {
type = nullOr path;
default = null;
};
};
};
}; };
}; };
}; };

View File

@ -1,53 +1,75 @@
{ pkgs, lib, config, ... }: { pkgs, lib, config, ... }:
let let
isMullvad = config.deviceSpecific.vpn.mullvad.enable;
isIVPN = config.deviceSpecific.vpn.ivpn.enable;
isTailscale = config.deviceSpecific.vpn.tailscale.enable; isTailscale = config.deviceSpecific.vpn.tailscale.enable;
wg = config.deviceSpecific.vpn.wireguard;
wgIFName = "wg0";
isRouteAll = (builtins.elem "0.0.0.0/0" wg.allowedIPs) || (builtins.elem "::0/0" wg.allowedIPs);
in { in {
config = lib.mkMerge [ config = lib.mkMerge [
(lib.mkIf isIVPN {
# services.ivpn.enable = true;
persist.state.directories = [ "/etc/opt/ivpn" ];
persist.state.homeDirectories = [ ".config/IVPN" ];
})
(lib.mkIf isTailscale { (lib.mkIf isTailscale {
services.tailscale = { services.tailscale.enable = true;
enable = true; services.tailscale.useRoutingFeatures = "client";
#interfaceName = "userspace-networking";
interfaceName = "tailscale0";
};
systemd.services.tailscaled.serviceConfig.ExecStart = [
""
"${pkgs.mullvad}/bin/mullvad-exclude ${pkgs.tailscale}/bin/tailscaled --state=/var/lib/tailscale/tailscaled.state --socket=/run/tailscale/tailscaled.sock --port=\${PORT} $FLAGS"
];
persist.state.directories = [ "/var/lib/tailscale" ]; persist.state.directories = [ "/var/lib/tailscale" ];
}) })
# TODO: currently broken, i'm using wg-quick for now
(lib.mkIf (isMullvad && isTailscale) { (lib.mkIf wg.enable {
# FIXME: allow mullvad custom dns networking.useNetworkd = false;
networking.nftables.ruleset = let systemd.network = {
resolver_addrs = "100.100.100.100"; enable = false;
excluded_ipv4 = "100.64.0.1/10"; wait-online.ignoredInterfaces = lib.optionals (!isRouteAll) [ wgIFName ];
excluded_ipv6 = "fd7a:115c:a1e0::/48"; netdevs."90-${wgIFName}" = {
in '' netdevConfig = {
table inet mullvad-ts { Name = wgIFName;
chain excludeOutgoing { Kind = "wireguard";
type route hook output priority 0; policy accept; Description = "${wgIFName} - wireguard tunnel";
ip daddr ${excluded_ipv4} ct mark set 0x00000f41 meta mark set 0x6d6f6c65; };
ip6 daddr ${excluded_ipv6} ct mark set 0x00000f41 meta mark set 0x6d6f6c65; wireguardConfig = {
} PrivateKeyFile = wg.keys.privateFile;
chain allow-incoming { FirewallMark = 34952; # 0x8888
type filter hook input priority -100; policy accept; ListenPort = wg.port + 1;
iifname "${config.services.tailscale.interfaceName}" ct mark set 0x00000f41 meta mark set 0x6d6f6c65; };
} wireguardPeers = [{
chain excludeDns { wireguardPeerConfig = {
type filter hook output priority -10; policy accept; PublicKey = wg.keys.public;
ip daddr ${resolver_addrs} udp dport 53 ct mark set 0x00000f41 meta mark set 0x6d6f6c65; PresharedKeyFile = wg.keys.presharedFile;
ip daddr ${resolver_addrs} tcp dport 53 ct mark set 0x00000f41 meta mark set 0x6d6f6c65; AllowedIPs = lib.concatStringsSep "," wg.allowedIPs;
} Endpoint = wg.endpoint;
} PersistentKeepalive = 25;
''; };
}];
};
networks."90-${wgIFName}" = {
matchConfig.Name = wgIFName;
address = wg.address;
linkConfig.ActivationPolicy = if wg.autostart then "up" else "manual";
networkConfig = {
# IPForward = true;
# IPMasquerade = "both";
DNSDefaultRoute = true;
DNS = wg.dns;
Domains = "~";
};
routes = lib.optionals (isRouteAll && wg.gateway.ipv4 != null) [
{
routeConfig.Gateway = wg.gateway.ipv4;
routeConfig.Destination = "0.0.0.0/0";
routeConfig.GatewayOnLink = true;
routeConfig.Table = 1000;
}
{
routeConfig.Gateway = wg.gateway.ipv6;
routeConfig.GatewayOnLink = true;
routeConfig.Table = 1000;
}
];
routingPolicyRules = lib.optionals (isRouteAll && wg.gateway != null) [{
routingPolicyRuleConfig.FirewallMark = 34952; # 0x8888
routingPolicyRuleConfig.InvertRule = true;
routingPolicyRuleConfig.Table = 1000;
routingPolicyRuleConfig.Priority = 10;
}];
};
};
}) })
]; ];
} }