110 lines
2.9 KiB
Nix
110 lines
2.9 KiB
Nix
{
|
|
config,
|
|
lib,
|
|
pkgs,
|
|
util,
|
|
...
|
|
}:
|
|
let
|
|
cfg = config.modules.network.vpn-client; # NOLINT(let_order)
|
|
|
|
vpnIcon = util.glyph [
|
|
"db83"
|
|
"dc9d"
|
|
];
|
|
|
|
vpnStatus = pkgs.writeShellScript "waybar-vpn-status" ''
|
|
interface=${lib.escapeShellArg cfg.interface}
|
|
|
|
if ! ${lib.getExe' pkgs.iproute2 "ip"} link show dev "$interface" >/dev/null 2>&1; then
|
|
printf '{"text":"","class":"idle"}\n'
|
|
exit 0
|
|
fi
|
|
|
|
ipaddr=$(${lib.getExe' pkgs.iproute2 "ip"} -4 -o addr show dev "$interface" | ${lib.getExe' pkgs.gawk "awk"} '{ print $4; exit }')
|
|
|
|
${lib.getExe pkgs.jq} -cn \
|
|
--arg text "${vpnIcon}" \
|
|
--arg tooltip "VPN $interface: ''${ipaddr:-no IPv4}" \
|
|
--arg class "active" \
|
|
'{ text: $text, tooltip: $tooltip, class: $class }'
|
|
'';
|
|
in
|
|
{
|
|
options.modules.network.vpn-client = {
|
|
enable = lib.mkEnableOption "a WireGuard VPN client";
|
|
|
|
interface = lib.mkOption {
|
|
type = lib.types.str;
|
|
default = "wg-home";
|
|
description = "Names the WireGuard interface.";
|
|
};
|
|
|
|
address = lib.mkOption {
|
|
type = lib.types.str;
|
|
example = "10.23.100.3/32";
|
|
description = "Sets the client tunnel address in CIDR notation.";
|
|
};
|
|
|
|
sopsFile = lib.mkOption {
|
|
type = lib.types.nullOr lib.types.path;
|
|
default = null;
|
|
description = "Names the encrypted file that contains the WireGuard private key.";
|
|
};
|
|
|
|
peer = {
|
|
publicKey = lib.mkOption {
|
|
type = lib.types.str;
|
|
description = "Sets the WireGuard public key for the remote peer.";
|
|
};
|
|
|
|
endpoint = lib.mkOption {
|
|
type = lib.types.str;
|
|
example = "203.0.113.10:51820";
|
|
description = "Sets the WireGuard endpoint for the remote peer.";
|
|
};
|
|
};
|
|
};
|
|
|
|
config = lib.mkIf cfg.enable {
|
|
assertions = [
|
|
{
|
|
assertion = cfg.sopsFile != null;
|
|
message = "Set modules.network.vpn-client.sopsFile when the VPN client is enabled.";
|
|
}
|
|
];
|
|
|
|
sops.secrets.wireguard-home-private-key.sopsFile = cfg.sopsFile;
|
|
|
|
registry.shell-shortcut.${config.networking.hostName} = {
|
|
vpn-on = "sudo systemctl start wireguard-${cfg.interface}.target";
|
|
vpn-off = "sudo systemctl stop 'wireguard-${cfg.interface}*.service' wireguard-${cfg.interface}.target";
|
|
};
|
|
|
|
registry.waybar.${config.networking.hostName}."custom/vpn" = {
|
|
order = 50;
|
|
settings = {
|
|
return-type = "json";
|
|
exec = "${vpnStatus}";
|
|
interval = 5;
|
|
};
|
|
};
|
|
|
|
systemd.targets."wireguard-${cfg.interface}".wantedBy = lib.mkForce [ ];
|
|
|
|
networking.wireguard.interfaces.${cfg.interface} = {
|
|
ips = [ cfg.address ];
|
|
mtu = 1280;
|
|
privateKeyFile = config.sops.secrets.wireguard-home-private-key.path;
|
|
|
|
peers = [
|
|
{
|
|
inherit (cfg.peer) publicKey endpoint;
|
|
allowedIPs = [ "10.23.0.0/16" ];
|
|
persistentKeepalive = 25;
|
|
}
|
|
];
|
|
};
|
|
};
|
|
}
|