Files changed: .gitignore CLAUDE.md credentials engine/.embcache.json engine/changelog.md engine/config.yaml engine/lib/__pycache__/agent.cpython-312.pyc engine/lib/agent.py engine/lib/lint.py engine/lint-report.md engine/sweep-full.log engine/sweep.sh vault/.obsidian/graph.json vault/.obsidian/workspace.json vault/INDEX.md vault/archive/projects/mmud/last-ember-chronicle.html vault/archive/projects/mmud/last-ember-howto.html vault/archive/projects/mmud/last-ember.html vault/archive/projects/mmud/mmud-phase5-prompt.md vault/archive/projects/mmud/mmud-phase6-prompt.md vault/archive/projects/mmud/mmud-prompts/mmud-prompts/01-update-planned.md vault/archive/projects/mmud/mmud-prompts/mmud-prompts/02-npc-nodes.md vault/archive/projects/mmud/mmud-prompts/mmud-prompts/03-darkcragg.md vault/archive/projects/mmud/mmud-prompts/mmud-prompts/04-dcrg-node.md vault/archive/projects/mmud/mmud-prompts/mmud-prompts/05-phase5.md vault/archive/projects/mmud/mmud-prompts/mmud-prompts/06-phase6.md vault/archive/projects/mmud/mmud-prompts/mmud-prompts/README.md vault/archive/projects/mmud/mmud-prompts/mmud-prompts/mmud-project.md vault/docs/hardware/environment.md vault/docs/hardware/ip-allocation.md vault/docs/matrix/archivist.md vault/docs/matrix/matrix_host.md vault/docs/matrix/mautrix_signal.md vault/docs/matrix/synapse.md vault/docs/matrix/synapse_retention_discovery.md vault/docs/navi/cc-rules.md vault/docs/navi/deployment.md vault/docs/navi/themes.md vault/docs/services/ots-setup.md vault/docs/services/services.md vault/docs/services/usenet.md vault/docs/software/authentik.md vault/docs/software/caddy.md vault/docs/software/dns.md vault/docs/software/geo-tools.md vault/docs/software/recon.md vault/docs/software/searxng.md vault/glossary.md vault/notes/echo6-landing-page-data-export.md vault/notes/ia-download-queue.md vault/plans/vaultwarden-plan.md vault/projects/advbbs-project.md vault/projects/argus.md vault/projects/deploy-livesync.md vault/projects/matrix-synapse-deployment.md vault/projects/meshtastic-headscale-runbook.md vault/projects/mmud-project.md vault/runbooks/add-peertube-channel.md vault/runbooks/authentik-access-groups.md vault/runbooks/authentik-create-invitation.md vault/runbooks/authentik-oidc-application.md vault/runbooks/authentik-upgrade.md vault/runbooks/ct-runbook.md vault/runbooks/edge2-access-reference.md vault/runbooks/expose-service-contabo.md vault/runbooks/expose-service-edge2.md vault/runbooks/expose-service-home.md vault/runbooks/headscale-onboard-node.md vault/runbooks/ia-cli-reference.md vault/runbooks/ia-download-mirror.md vault/runbooks/idahomesh-bridge-setup.md vault/runbooks/idahomesh-vpn-device-setup.md vault/runbooks/lxc-service-migration.md vault/runbooks/mailcow-create-mailbox.md vault/runbooks/meshmonitor-password-reset.md vault/runbooks/meshtastic-sidecar-node.md vault/runbooks/meshtasticd-sim-nodes-runbook.md vault/runbooks/nordvpn-lxc.md vault/runbooks/peertube-remote-runner.md vault/runbooks/pg-backup.md vault/runbooks/pi-nas-omv-runbook.md vault/runbooks/pipeline-patterns.md vault/runbooks/proxmox-create-ubuntu-vm.md vault/runbooks/proxmox-onboard-node.md vault/runbooks/recon-operations.md vault/runbooks/recon-service-integration.md vault/runbooks/syncthing-add-node.md vault/session-resume/SESSION-HANDOFF-meshai-test.md
114 lines
4.7 KiB
Markdown
114 lines
4.7 KiB
Markdown
---
|
|
title: Headscale / Tailscale — Onboard a New Node
|
|
type: runbook
|
|
tags:
|
|
- proxmox
|
|
aliases: []
|
|
related:
|
|
- [[proxmox-onboard-node]]
|
|
- [[ct-runbook]]
|
|
- [[caddy]]
|
|
- [[meshtastic-headscale-runbook]]
|
|
- [[lxc-service-migration]]
|
|
updated: 2026-06-18
|
|
---
|
|
# Headscale / Tailscale — Onboard a New Node
|
|
|
|
Standard procedure to bring any new system (Proxmox host, bare-metal, VM, or LXC) onto the Echo6 tailnet.
|
|
|
|
## Overview
|
|
- **Control server:** Headscale on Contabo — `ssh root@100.64.0.1`, Docker container `headscale`.
|
|
- **Login server:** `https://vpn.echo6.co` · **Admin UI (Headplane):** `https://vpn.echo6.co/admin`
|
|
- **User/namespace:** all Echo6 nodes join `echo6` (user ID 1).
|
|
- **MagicDNS base domain:** `echo6.mesh` (e.g. `ping data.echo6.mesh`).
|
|
- **Naming:** lowercase, hyphens OK, no dots/underscores. Matches `--hostname` and the cortex SSH alias.
|
|
|
|
## 1. Generate a preauth key (on Contabo)
|
|
```bash
|
|
ssh root@100.64.0.1 'docker exec headscale headscale preauthkeys create --user echo6 --reusable --expiration 1h'
|
|
# If the name form errors, use the user ID: --user 1
|
|
```
|
|
|
|
## 2. Install Tailscale on the node
|
|
```bash
|
|
curl -fsSL https://tailscale.com/install.sh | sh
|
|
systemctl enable --now tailscaled
|
|
```
|
|
|
|
## 3. DNS-bootstrap drop-in (REQUIRED on LXCs, recommended everywhere)
|
|
Without this, tailscaled can't resolve `vpn.echo6.co` on a cold boot. Makes onboarding survive a reboot.
|
|
```bash
|
|
mkdir -p /etc/systemd/system/tailscaled.service.d
|
|
cat > /etc/systemd/system/tailscaled.service.d/dns-bootstrap.conf <<'EOF'
|
|
[Service]
|
|
ExecStartPre=/bin/sh -c "grep -q nameserver /etc/resolv.conf || echo nameserver 1.1.1.1 > /etc/resolv.conf"
|
|
EOF
|
|
systemctl daemon-reload
|
|
```
|
|
|
|
## 4. LXC containers only — TUN device prerequisite
|
|
On the Proxmox host, before starting the container (needs `nesting=1,keyctl=1` features set):
|
|
```bash
|
|
pct stop <CTID>
|
|
cat >> /etc/pve/lxc/<CTID>.conf <<'EOF'
|
|
lxc.cgroup2.devices.allow: c 10:200 rwm
|
|
lxc.mount.entry: /dev/net/tun dev/net/tun none bind,create=file
|
|
EOF
|
|
pct start <CTID>
|
|
```
|
|
(Privileged variant: create with `--unprivileged 0`, use `lxc.mount.entry: /dev/net dev/net none bind,create=dir`.)
|
|
|
|
## 5. Register with Headscale
|
|
```bash
|
|
tailscale up --login-server=https://vpn.echo6.co --auth-key=<KEY> --hostname=<NAME>
|
|
```
|
|
- Standard nodes pass **no** `--advertise-routes` / `--accept-routes` / `--advertise-tags`.
|
|
- Add `--ssh` to enable Tailscale SSH.
|
|
- **Always include `--login-server=https://vpn.echo6.co`** — without it the node registers against Tailscale's public servers instead of Echo6 Headscale.
|
|
- Subnet-router exception: the mesh-bridge advertises `100.100.0.0/16 --accept-routes`, then enable on Headscale (`headscale routes list` / `routes enable -r <ID>`).
|
|
|
|
## 6. Verify
|
|
```bash
|
|
tailscale status
|
|
tailscale ip -4
|
|
ssh root@100.64.0.1 'docker exec headscale headscale nodes list' # confirm node + assigned 100.64.0.x
|
|
```
|
|
Headscale assigns the IP **sequentially at registration** — don't pre-assign; read it back here.
|
|
|
|
## 7. SSH config aliases on cortex (`~/.ssh/config`)
|
|
```
|
|
Host <alias>
|
|
HostName <local-or-public-IP>
|
|
User root
|
|
|
|
Host ts-<alias>
|
|
HostName <tailscale-IP>
|
|
User root
|
|
```
|
|
Most nodes use `User root`. Per-node exceptions exist — e.g. **edge2** uses `User admin` + `IdentityFile ~/.ssh/contabo2_ed25519` (cloud image, no root login).
|
|
|
|
## 8. Update inventory
|
|
- `docs/hardware/environment.md` — Key Servers table **and** Headscale Node List (bump count + "updated" line).
|
|
- `docs/hardware/ip-allocation.md` — Tailscale IPs section.
|
|
- `CLAUDE.md` cluster cheat-sheet — Proxmox hosts only.
|
|
- `docs/services/services.md` — once [[services]] are deployed on the node.
|
|
|
|
## Worked example — edge2 (2026-06-16)
|
|
Proxmox host on Contabo. Preauth key → `tailscale up --login-server=https://vpn.echo6.co --auth-key=<KEY> --hostname=edge2` → assigned **100.64.0.26** (Headscale node 42). SSH aliases `edge2` / `ts-edge2` use `User admin` + `~/.ssh/contabo2_ed25519`.
|
|
|
|
## Gotchas
|
|
- `environment.md`'s Headscale Node List is the authoritative IP source — `ip-allocation.md`'s table has gone stale before.
|
|
- A node deleted from Headscale does not get its old IP auto-reused; confirm the real next IP with `headscale nodes list`.
|
|
- The old `ct-runbook` `tailscale up --authkey ... --ssh` form omits `--login-server` — don't copy it blindly.
|
|
|
|
## Checklist
|
|
```
|
|
[ ] Preauth key generated on Contabo (user echo6)
|
|
[ ] Tailscale installed + tailscaled enabled
|
|
[ ] DNS-bootstrap drop-in in place (LXC: required)
|
|
[ ] (LXC) TUN device added to CT config
|
|
[ ] tailscale up with --login-server=https://vpn.echo6.co --hostname=<name>
|
|
[ ] Node appears in headscale nodes list; IP captured
|
|
[ ] SSH aliases (<alias> + ts-<alias>) added on cortex and tested
|
|
[ ] Inventory updated (environment.md, ip-allocation.md, CLAUDE.md)
|
|
```
|