pinix's Headscale now allocates its own range (100.96.0.0/24, fd7a:115c:a1e0:96::/64). The pinix-dns namespace node forwards exactly TCP 443 to a new Traefik web-internal entrypoint on the veth host side (:8443, websecure untouched) and TCP 22 to sshd. unbound-pinix answers git.lukasrosier.com (AAAA only), distributed via split DNS for that name only. gitserver/: cgit via services.cgit, reduced to reading and snapshot downloads, built without its Python filters; git@ with git-shell and a from= restricted key. Verified from tnix's pinixnet namespace (DNS, HTTPS, snapshot, ls-remote, push) and refused from the public IPv6, the blunix tailnet and the LAN. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JGodmgtRqahbT52gApsM8N
35 lines
1.7 KiB
Bash
35 lines
1.7 KiB
Bash
#!/usr/bin/env bash
|
|
# Run as root on pinix after activating tailnet-dns.nix. Only provisions the
|
|
# dedicated machine identity; no LLDAP accounts or existing clients change.
|
|
set -euo pipefail
|
|
set +x
|
|
socket=/run/tailscale-pinix/tailscaled.sock
|
|
state=$(tailscale --socket "$socket" status --json | jq -r .BackendState)
|
|
if [[ "$state" != Running ]]; then
|
|
# The fixed .1 address assumes this is the first node in the new prefix.
|
|
# Existing registrations keep their old 100.64.0.x addresses until
|
|
# `headscale nodes backfillips`, so enrol before backfilling. Refuse if
|
|
# .1 is already taken instead of silently getting another address.
|
|
if headscale nodes list --output json |
|
|
jq -e '(. // []) | any(.[]; .ip_addresses // [] | any(. == "100.96.0.1" or . == "fd7a:115c:a1e0:96::1"))' >/dev/null; then
|
|
printf 'Refusing bootstrap: 100.96.0.1 is already assigned; review DNS address allocation first.\n' >&2
|
|
exit 1
|
|
fi
|
|
user_id=$(headscale users list --output json |
|
|
jq -r '. // [] | .[] | select(.name == "pinix-dns") | .id')
|
|
if [[ -z "$user_id" ]]; then
|
|
user_id=$(headscale users create pinix-dns --output json | jq -er .id)
|
|
fi
|
|
umask 077
|
|
keyfile=$(mktemp /run/pinix-dns-auth.XXXXXX)
|
|
trap 'rm -f "$keyfile"' EXIT
|
|
headscale preauthkeys create --user "$user_id" --expiration 10m --output json |
|
|
jq -er .key > "$keyfile"
|
|
tailscale --socket "$socket" up \
|
|
--login-server=https://head.lukasrosier.com \
|
|
--hostname=pinix-dns --accept-dns=false --accept-routes=false \
|
|
--netfilter-mode=off --auth-key="file:$keyfile" --timeout=60s
|
|
fi
|
|
test "$(tailscale --socket "$socket" ip -4)" = 100.96.0.1
|
|
test "$(tailscale --socket "$socket" ip -6)" = fd7a:115c:a1e0:96::1
|
|
printf 'Isolated DNS node enrolled with the expected addresses.\n'
|