Add saved Headscale DNS choice for MagicDNS manager addresses

This commit is contained in:
2026-10-04 11:50:50 +02:00
parent 492c036da1
commit 7e584e953e
+25 -7
View File
@@ -16,6 +16,7 @@ installed_label() { if [[ $1 == 1 ]]; then printf 'vorhanden'; else printf 'fehl
LIST=0; DRY=0; MANAGER=''; VERSION=''; LOGIN_SERVER=''; SELECTION=''; VERSION_EXPLICIT=0
SSH_ENABLED=1; SSH_USER=''; SSH_SUDO=0; SSH_NOPASSWD=0; SAVE_SETTINGS=1
TS_ACCEPT_DNS=0; DNS_SAVED=0
VARS_FILE=/etc/lxc-enroll/.vars
while [[ $# -gt 0 ]]; do
case "$1" in
@@ -82,7 +83,8 @@ p=sys.argv[1]; s=os.lstat(p)
if not stat.S_ISREG(s.st_mode) or s.st_uid != 0 or stat.S_IMODE(s.st_mode) & 0o077:
sys.exit('Unsichere Rechte der .vars: regulaere Datei, root, Modus 600 erforderlich.')
d=json.load(open(p))
for k in ('manager','agent_version','login_server','ssh_enabled','ssh_user','ssh_sudo','ssh_nopasswd'):
for k in ('manager','agent_version','login_server','ssh_enabled','ssh_user','ssh_sudo','ssh_nopasswd','ts_accept_dns'):
if k not in d: continue
v=d.get(k,'')
if not isinstance(v,str) or any(c in v for c in '\n\r\t\0') or len(v)>16384:
sys.exit('Ungueltige .vars.')
@@ -98,6 +100,7 @@ PY
ssh_user) SSH_USER=$value;;
ssh_sudo) [[ $value =~ ^[01]$ ]] || fail 'Ungueltige Sudo-Einstellung.'; SSH_SUDO=$value;;
ssh_nopasswd) [[ $value =~ ^[01]$ ]] || fail 'Ungueltige Sudo-Einstellung.'; SSH_NOPASSWD=$value;;
ts_accept_dns) [[ $value =~ ^[01]$ ]] || fail 'Ungueltige DNS-Einstellung.'; TS_ACCEPT_DNS=$value; DNS_SAVED=1;;
esac
done <<<"$fields"
}
@@ -105,10 +108,10 @@ PY
save_settings() {
[[ $SAVE_SETTINGS == 1 ]] || return 0
install -d -m 700 /etc/lxc-enroll
python3 - "$VARS_FILE" "$MANAGER" "$VERSION" "$LOGIN_SERVER" "$SSH_ENABLED" "$SSH_USER" "$SSH_SUDO" "$SSH_NOPASSWD" <<'PY'
python3 - "$VARS_FILE" "$MANAGER" "$VERSION" "$LOGIN_SERVER" "$SSH_ENABLED" "$SSH_USER" "$SSH_SUDO" "$SSH_NOPASSWD" "$TS_ACCEPT_DNS" <<'PY'
import json, os, sys, tempfile
p=sys.argv[1]
keys=('manager','agent_version','login_server','ssh_enabled','ssh_user','ssh_sudo','ssh_nopasswd')
keys=('manager','agent_version','login_server','ssh_enabled','ssh_user','ssh_sudo','ssh_nopasswd','ts_accept_dns')
fd,tmp=tempfile.mkstemp(prefix='.vars.',dir=os.path.dirname(p))
try:
os.fchmod(fd,0o600)
@@ -191,6 +194,8 @@ set +x
umask 077
DIR=$1; MANAGER=$2; AGENT_VERSION=$3; LOGIN=$4; NAME=$5; WANT_TS=$6; WANT_WZ=$7
SSH_ENABLED=$8; SSH_USER=$9; SSH_SUDO=${10}; SSH_NOPASSWD=${11}
TS_ACCEPT_DNS=${12}
case "$TS_ACCEPT_DNS" in 1) DNS_FLAG=true;; 0) DNS_FLAG=false;; *) exit 1;; esac
trap 'rm -f -- "$DIR/headscale.key" "$DIR/enrollment.pass" "$DIR/sudo.pass"' EXIT
export DEBIAN_FRONTEND=noninteractive
present() { [[ $(dpkg-query -W -f='${Status}' "$1" 2>/dev/null || true) == 'install ok installed' ]]; }
@@ -222,13 +227,17 @@ if [[ $WANT_TS == 1 ]]; then
apt-get -o DPkg::Lock::Timeout=120 update
apt-get -o DPkg::Lock::Timeout=120 install -y --no-install-recommends tailscale
systemctl enable --now tailscaled
# File reference keeps the key out of command arguments/history. Keep local DNS.
timeout 90 tailscale up --login-server="$LOGIN" --auth-key="file:$DIR/headscale.key" --hostname="$NAME" --accept-dns=false --timeout=60s
# File reference keeps the key out of command arguments/history.
timeout 90 tailscale up --login-server="$LOGIN" --auth-key="file:$DIR/headscale.key" --hostname="$NAME" --accept-dns="$DNS_FLAG" --timeout=60s
rm -f -- "$DIR/headscale.key"
tailscale ip -4
echo 'Tailscale installiert und angemeldet.'
fi
# Explicitly accepted DNS settings may also enable MagicDNS on an existing client.
# Do not disable or reauthenticate an existing client when this option is declined.
if [[ $TS_ACCEPT_DNS == 1 && $WANT_TS == 0 ]]; then tailscale set --accept-dns=true; fi
if [[ $WANT_WZ == 1 ]]; then
# A Headscale manager IP only becomes reachable after the new client joins.
for port in 1514 1515; do
@@ -319,7 +328,7 @@ deploy_one() {
if [[ -s $TMP/sudo.pass ]]; then pct push "$id" "$TMP/sudo.pass" "$dir/sudo.pass" --user 0 --group 0 --perms 600 || return 1; fi
fi
# Credentials are files, never pct arguments. bash receives only non-secret settings.
pct exec "$id" -- bash "$dir/worker.sh" "$dir" "$MANAGER" "$VERSION" "$LOGIN_SERVER" "${NAMES[$id]}" "$ts" "$wz" "$SSH_ENABLED" "$SSH_USER" "$SSH_SUDO" "$SSH_NOPASSWD" || return 1
pct exec "$id" -- bash "$dir/worker.sh" "$dir" "$MANAGER" "$VERSION" "$LOGIN_SERVER" "${NAMES[$id]}" "$ts" "$wz" "$SSH_ENABLED" "$SSH_USER" "$SSH_SUDO" "$SSH_NOPASSWD" "$TS_ACCEPT_DNS" || return 1
if [[ $ts == 1 ]]; then
pct exec "$id" -- tailscale status --json | python3 -c 'import json,sys; d=json.load(sys.stdin); sys.exit(0 if d.get("BackendState")=="Running" and d.get("Self",{}).get("Online") is True else 1)' || {
say "LXC $id: Headscale-Verbindung nicht als online bestaetigt."; return 1;
@@ -394,7 +403,16 @@ main() {
if [[ $need_ts == 1 ]]; then
if [[ -z $LOGIN_SERVER ]]; then ask 'Headscale-Login-Server (vollstaendige HTTPS-URL):'; LOGIN_SERVER=$REPLY; fi
[[ $LOGIN_SERVER =~ ^https://[A-Za-z0-9][A-Za-z0-9.:-]*/?$ ]] || fail 'Bitte eine HTTPS-Server-URL ohne Zugangsdaten/Query eingeben.'
say 'Neue Tailscale-Clients verwenden Headscale; vorhandene lokale DNS-Einstellungen bleiben aktiv.'
say 'Neue Tailscale-Clients verwenden Headscale.'
fi
if [[ $need_wz == 1 && ! $MANAGER =~ ^[0-9.:]+$ && $DNS_SAVED == 0 ]]; then TS_ACCEPT_DNS=1; fi
if [[ $TS_ACCEPT_DNS == 1 ]]; then input='[J/n]'; else input='[j/N]'; fi
yes_no "Headscale-DNS/MagicDNS fuer die Auswahl uebernehmen? $input" "$TS_ACCEPT_DNS"
TS_ACCEPT_DNS=$REPLY
if [[ $TS_ACCEPT_DNS == 1 ]]; then
say 'Headscale-DNS wird fuer ausgewaehlte Clients aktiviert. Lokale Namensaufloesung muss zu den Headscale-DNS-Einstellungen passen.'
else
say 'Neue Clients behalten lokales DNS bei. Der Manager-Name muss ueber diesen Resolver aufloesbar sein.'
fi
ask 'Nur diese fehlenden Komponenten installieren? Bitte INSTALL eingeben:'
[[ $REPLY == INSTALL ]] || { say 'Abgebrochen.'; return 0; }