nixos: tailscale auto-connect via agenix auth key

This commit is contained in:
2026-02-13 04:35:47 -08:00
committed by Kat Huang
parent 14c86c61d4
commit 5d16fb00c0
4 changed files with 116 additions and 1 deletions

View File

@@ -149,6 +149,25 @@
};
};
systemd.user.services.tailscale-systray = {
Unit = {
Description = "Tailscale systray";
After = [ "graphical-session.target" "tray.target" ];
PartOf = [ "graphical-session.target" ];
Requires = [ "tray.target" ];
};
Service = {
ExecStart = "${pkgs.tailscale}/bin/tailscale systray";
Restart = "on-failure";
RestartSec = 3;
};
Install = {
WantedBy = [ "graphical-session.target" ];
};
};
xdg.desktopEntries.google-chrome-devtools = {
name = "Google Chrome (DevTools)";
genericName = "Web Browser";

View File

@@ -25,4 +25,8 @@ in
"org-api-ssh-key.age".publicKeys = keys.hostKeys ++ keys.kanivanKeys ++ keys.railbird-sf;
"google-assistant-integration-service-key.age".publicKeys = keys.hostKeys ++ keys.kanivanKeys;
"zwave-js.json.age".publicKeys = keys.hostKeys ++ keys.kanivanKeys;
# Optional Tailscale pre-auth key for unattended enrollment.
# This is safe to commit encrypted; default plaintext is "DISABLED".
"tailscale-authkey.age".publicKeys = keys.kanivanKeys;
}

View File

@@ -0,0 +1,43 @@
age-encryption.org/v1
-> ssh-rsa gwJx0Q
FvsNlNlVhNMmvbbOlPTC49Db7OMVIxCrRCamo5A1jSZQ3IWf6XbyErhzSLQY3Gfw
zEwt8HegamDqsZu28y4V6g2ibLCAK7cGMHQXnfBBQbKK0KriJZdGCCaQo9wSZBAf
A05WHB0NHuLVEHXWhQc5fAdKz/pwTRD9NOXQCqZ76IDha/jcL9UwjFmb6zOWaM65
FDLPiNBgvGpAhEWcWpQ833lfk/2ixlOwZ6NeXker7U72RZWHaDAWullnLzqnLcoa
Kz5mD9N6BnAS1DpCyDUYrQkyPAkcXM5CPs57efN5/u+wyyyCa2tlXiPbVSQ9OEiE
spDiBTzqak978FiP5d3FMA
-> ssh-ed25519 YFIoHA x6bVPZ5yMz6r22ZNLchRsEa9LqiYd3qG2GTSSOgL9QY
PIIV7mv82vo0iVF+FbCEe0Wqfx93GBP3qi/MPXjyddI
-> ssh-ed25519 KQfiow lllzjgCHkHWBzynEUHSQNiUYltbRxw2juRmzOcswr3I
Rz9yf8YadqxSWoCmVcByKjF0Jve1pRCC6EEYhM8B7fs
-> ssh-ed25519 kScIxg k7UXiHGM4vS8CBTXGi5GVWIbK/kevYuus5nhB5H4ChI
yJmfqVIxkfeqUNx+yBfoBnQ1liXTGlOTEObmDL4/B0M
-> ssh-ed25519 HzX1zw EmVR4oAFYSdjxQjPIAV1/MGs/p75bYgDLgtzAnbvCl8
yUZcTll16d4oRwx87+o2twEB5jbkkMr7SCXIkVHQkMw
-> ssh-ed25519 KQfiow bVHXOFAcHmDQnJTOkvAa2yqB1B2Q+Th6/8+/hAQzym0
HXlTQupGi2HGwL1YYBWdyVIeB6kHzfuPI6EmlL4n4hk
-> ssh-ed25519 1o2X0w yJ1ZYo+Ivml5SUg8x3FC9Z5ScoemWbxPXYeH1A77vT8
PIL0dOiZJ/MZJtuHdqRtixxGOYhWmQ9L0gnZ7blCM1I
-> ssh-ed25519 KQ5iUA STHZY7izxKR7bhmRWoLvqJo2KhqAFguy1w2ybF3LvBo
zX/mc5bPR1P7PWSzdD6HzQMeiGU2iyRfl46GIdztv2s
-> ssh-ed25519 AKGkDw 2Tsz3GP4MoVSfqyapthWeXAdOjYiJm/n497m12sKOUM
1z8W39Vp39gkHeFG4IrWSqnyDfTk/faGOqXVR0cgYeU
-> ssh-ed25519 0eS5+A Ys6bSdBmt8tFmb+0w3aOvhD7AskFXPZvey3mlR6yh1k
K7A+9MR8E4pi3oE5/BaS75NG8jQitT4SgghUBsTKOWs
-> ssh-ed25519 9/4Prw a6Hn8su2hMt0M1n361VwSehJb5kpoAmuqSdbtL3nZE4
G8CVhYjq1BwT1k6Fg+dWKy5iwJSZH1XPWq42Ut6DGwQ
-> ssh-ed25519 gAk3+Q Ojgh8mIG055OCOgmzy+ONM5hAwepuSW6Y6NQZ/lKmWg
R6CFZdFNWvGLeDRjruMUtU/VkASUrgBRckS3UKTQJBk
-> ssh-ed25519 X6eGtQ TC7xl6oPV3OfcRtUAh1cVZFwlXUPpi1AdeucGv/U5RQ
ItNKgWhglMLdWXsZuFc3wBzaHIWDWH1P8M5WGTxOZRE
-> ssh-ed25519 0ma8Cw uYMGharDkTjlsd47H6664Z+c6w4B4QyxYx/WCG5vVyQ
jvhGw3qcTR2OaqMoMLGhu9ZbjFk1oVBLCmPSByUdzxM
-> ssh-ed25519 Tp0Z1Q bGhWGaTFhZF7L5ZKrkvLTPsb0Y0FDnSl/3YUzVTEqXY
2JBDa7pUzUWTvjErVKKs2AUO36UTvJ0bVcp8dcjVrLk
-> ssh-ed25519 ePNWZQ wF/LEqfLfanzl0V4FVZTv6b0t/l1nPnfxCSHuFFBMwA
ask3AqAmkTp02Y+ZxwT1qTo8nqXlqdFVmsKRKmjfZ0c
-> ssh-ed25519 hILzzA x5K6ekDUTem831ZVB1232b21D9qlrs5wbDPTpvO+1jQ
qTwvmdBz82DHpx53P/OrAP0sK3R325pN64+umM18qM8
--- Py2A4BqLJSNtJ3C7ZmuyV1jpxo6aLirCj2z2egPQdQ4
<EFBFBD><EFBFBD>Ւ|ASh<53>[N?c^k<><16><>һ<EFBFBD>T
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>"F혋*u<75>

View File

@@ -6,5 +6,54 @@ makeEnable config "myModules.tailscale" true {
# Handy even if you only enable the service and run `tailscale up` manually.
environment.systemPackages = [ pkgs.tailscale ];
}
# Optional: unattended enrollment using a pre-auth key stored in agenix.
#
# Plaintext content "DISABLED" means "do nothing".
age.secrets.tailscale-authkey = {
file = ./secrets/tailscale-authkey.age;
owner = "root";
group = "root";
mode = "0400";
};
systemd.services.tailscale-autoconnect = {
description = "Auto-connect Tailscale (optional, via agenix auth key)";
wantedBy = [ "multi-user.target" ];
after = [ "network-online.target" "tailscaled.service" "agenix.service" ];
wants = [ "network-online.target" "tailscaled.service" ];
unitConfig = {
ConditionPathExists = config.age.secrets.tailscale-authkey.path;
};
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
};
script = ''
set -euo pipefail
key_file='${config.age.secrets.tailscale-authkey.path}'
if [ ! -s "$key_file" ]; then
exit 0
fi
if [ "$(cat "$key_file")" = "DISABLED" ]; then
exit 0
fi
state="$(${pkgs.tailscale}/bin/tailscale status --json 2>/dev/null | ${pkgs.jq}/bin/jq -r '.BackendState // empty' || true)"
if [ "$state" = "Running" ]; then
exit 0
fi
# First-time (or post-logout) login.
${pkgs.tailscale}/bin/tailscale up \\
--auth-key "file:$key_file" \\
--accept-dns=true \\
--operator=imalison \\
--timeout=60s
'';
};
}