module for requesting headscale auth key

This commit is contained in:
Dmitriy Kholkin 2024-01-25 21:01:09 +03:00
parent 2aeea208ad
commit 561eaeedfb
Signed by: AtaraxiaDev
GPG Key ID: FD266B810DF48DF2
4 changed files with 98 additions and 11 deletions

View File

@ -55,9 +55,23 @@ in {
ram = 12;
fileSystem = "zfs";
};
deviceSpecific.isServer = true;
deviceSpecific.enableVirtualisation = true;
deviceSpecific.vpn.tailscale.enable = true;
deviceSpecific.isServer = true;
# Tailscale auto-login
services.headscale-auth.home-hypervisor = {
outPath = "/tmp/hypervisor-authkey";
before = [ "tailscaled-autoconnect.service" ];
};
services.tailscale = {
authKeyFile = "/tmp/hypervisor-authkey";
extraUpFlags = [
"--login-server=https://wg.ataraxiadev.com"
"--accept-dns=false"
"--advertise-exit-node=false"
"--operator=${config.mainuser}"
];
};
zramSwap = {
enable = true;

View File

@ -0,0 +1,76 @@
{ config, lib, pkgs, inputs, ... }:
with lib;
{
options.services.headscale-auth = mkOption {
description = mdDoc ''
Request headscale auth key.
'';
type = types.attrsOf (types.submodule ({ cfg, name, ... }: {
options = {
autoStart = mkOption {
type = types.bool;
default = false;
description = mdDoc "Request auth key on startup.";
};
ephemeral = mkOption {
type = types.bool;
default = false;
description = mdDoc "Request ephemeral auth key.";
};
expire = mkOption {
type = types.str;
default = "1h";
description = mdDoc "Auth key expiration time.";
};
user = mkOption {
type = types.str;
default = "ataraxiadev";
description = mdDoc "Auth key user.";
};
outPath = mkOption {
type = types.str;
default = "/tmp/auth-key";
description = mdDoc "Where to write down the auth key.";
};
before = mkOption {
type = with types; listOf str;
default = [ ];
description = mdDoc "Start service before this services.";
};
};
}));
default = { };
};
config = mkIf (config.services.headscale-auth != { }) {
sops.secrets.headscale-api-env.sopsFile = inputs.self.secretsDir + /misc.yaml;
systemd.services =
mapAttrs'
(name: cfg: nameValuePair "headscale-auth-${name}" ({
path = [ pkgs.headscale pkgs.jq ];
restartIfChanged = false;
requiredBy = cfg.before;
before = cfg.before;
wants = [ "network-online.target" ];
after = [ "network-online.target" ];
wantedBy = mkIf cfg.autoStart [ "multi-user.target" ];
environment = {
HEADSCALE_CLI_ADDRESS = "wg.ataraxiadev.com:443";
};
script = ''
auth_key=$(headscale preauthkeys create -e ${cfg.expire} -u ${cfg.user} -o json ${optionalString cfg.ephemeral "--ephemeral"} | jq -r .key)
if [ "$auth_key" = "null" ]; then
echo "Cannot retrieve auth key." >&2
exit 1
else
echo $auth_key > "${cfg.outPath}"
fi
'';
serviceConfig = {
EnvironmentFile = config.sops.secrets.headscale-api-env.path;
Type = "oneshot";
};
})
) config.services.headscale-auth;
};
}

View File

@ -3,14 +3,10 @@ let
nodeAddress = "192.168.0.5";
upstream-dns = "100.64.0.1";
in {
systemd.services.gen-headscale-key = {
services.headscale-auth.blocky = {
ephemeral = true;
outPath = "/tmp/blocky-authkey";
before = [ "container@blocky.service" ];
requiredBy = [ "container@blocky.service" ];
serviceConfig.Type = "oneshot";
path = [ pkgs.headscale ];
script = ''
headscale preauthkeys create --ephemeral -e 1h -u ataraxiadev | tee /tmp/blocky-authkey
'';
};
containers.blocky = {
autoStart = true;

View File

@ -1,12 +1,13 @@
headscale-oidc: ENC[AES256_GCM,data:IQaE/1zXfc72iivZBDH3LmQmaljWIyxIeyMGLRetphJ7UWB//MeQbR4eM3gt7pXaFKudXYxuEkSCjJ/CgrxgTrlLoBFlTNwibr5tsDEYLgLdodCQj/Oih7ru1fSAAJR2XBtM/T4CZHWlTHnbGxRZUrUXRUgMog9GsY9Q+ybbzvI81urZTvaRzKUfHJ2YQKOW/k1Ug5fT1yZUdMyU2A==,iv:Fk4UFEnHsHjgMHbny6L7MEULQFELB5dtR1OtEm2A/Zk=,tag:shKxkfdXqpAppiPX06HMYw==,type:str]
headscale-oidc: ENC[AES256_GCM,data:lu1c/XSD7/fV1MuwAETDV1PCn3C7zr0UKK0u4/5Z2AoQXHLsUES3Yvu7B9kStFd3M+GoOq6Y0xYVGLS9x5TcEVFDKSsdRRgGYlu2C/x+NUOlP0cEKKq222NYIZ6iA9emP6A2ZVy1ZpM1UE65vJHk1NHHbS4zYiiJMskOacwW1bs=,iv:o9/TG+9/MU6mchYtj6navG97eJhP/4kUlWcx/xjhvK0=,tag:l2xQhGn1vkcBZvBZevpTOg==,type:str]
headscale-oidc-env: ENC[AES256_GCM,data:LX26VJfqImj5hHGSczey4okdPsNdxsIQ4OD3kRhwRt4P2MAdlVWiBQl47Jj5lk1Nm/yZejf4GXARLoQf3TK1ie4aDaWJx8Yhl8aSpy1s3h/1lcM7OCNb9WhUB+ZmikXaA6sOui4sQfGEtf0ydeIE0CwH04WL+Qomu+WxFzUVSzPW3baR2AKSqKiLGLGB0mZrRmdbhSdxCJN85j2i/Q==,iv:9b4pMMLj9huMg2RnrU10xqjRoA3NCWUKn4rc956Gm+s=,tag:+XN0KzJqWvTS/8ufGooNfg==,type:str]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
age: []
lastmodified: "2024-01-21T19:12:33Z"
mac: ENC[AES256_GCM,data:EpMvPZNJ0JCDMZ+btkQQskZ5TGSftq/S+N/aGwx54lH1w7qNqpuyxD9XsadeIb8wTP5yIuXKkBegcRmMmKHfl3/tMfwbJ779yuJpMDRMYGoaFfYiR3r+14gBYtBONFKv+OtI6+4oWYN7xrVIncMYbs3SptD/Q80SUQ5ZgtF7I9Q=,iv:O2IzGK0YJZ7YuR8g/EiNKlAaY3D4xkwjFgftuFk7Oys=,tag:8uUMxgkF24BGesa7vahP7Q==,type:str]
lastmodified: "2024-01-24T20:09:29Z"
mac: ENC[AES256_GCM,data:akcHfxJrGSPINI28sQdxcz4s6P9Va+GAvF0TC7adgf2mgVtqkZdaZPJZ/BaVlxccWf3tFgBMKwLVHcfmxMi93KnxFxOuA3DWYnjmBfHzxHFq+jWke7BHzRhPvVsKOKKHdfkXPCZnqyHLwRPp0jUyrANw9m9Ub2JTomfHy3j2+FA=,iv:784bnpb7v0z3KewsnH+RXYkdml+o2sj/qvR7qqn/om0=,tag:L1c/p8GcUlT+4sLyr0T5fA==,type:str]
pgp:
- created_at: "2024-01-21T19:12:17Z"
enc: |-