Complete guide to managing your Tailscale/Headscale VPN network
100.64.0.0/2464.20.46.182| User | Type | Domain | Purpose |
|---|---|---|---|
dom |
Personal | raywonderis.me | Personal network |
tappedin |
Business | tappedin.fm | Business network |
devinecr |
Business | devine-creations.com | Development network |
Most Secure Easiest Setup
What it is: Generate a one-time or reusable key that allows devices to join automatically.
# Create a key that expires in 7 days
headscale preauthkeys create --user dom --expiration 7d
# Create a reusable key
headscale preauthkeys create --user dom --expiration 30d --reusable
# Create a key that never expires (not recommended)
headscale preauthkeys create --user dom --expiration 90d --reusable
Requires Admin Approval
Process:
# List pending devices
headscale nodes list
# Approve a device
headscale nodes register --user dom --key nodekey:xxxxxx
Interactive
When a device connects, Tailscale generates a registration URL:
https://headscale.tappedin.fm/register/DEVICE_KEY
User opens this URL in browser to complete registration.
# Create a new user
headscale users create matt-turner
# List all users
headscale users list
# Delete a user (WARNING: removes all their devices)
headscale users destroy matt-turner
Admin Dashboard shows all devices with:
# List all devices
headscale nodes list
# Remove a specific device
headscale nodes delete --identifier 1
# Force remove offline device
headscale nodes delete --identifier 1 --force
By default, devices do not expire. To set expiration:
# Expire a device manually
headscale nodes expire --identifier 1
Control which users/devices can communicate with each other.
ACL File: /etc/headscale/acl.yaml
{
"acls": [
{
"action": "accept",
"src": ["*"],
"dst": ["*:*"]
}
]
}
{
"acls": [
{
"action": "accept",
"src": ["dom"],
"dst": ["dom:*"]
},
{
"action": "accept",
"src": ["tappedin"],
"dst": ["tappedin:*", "dom:80,443"]
}
]
}
| Port | Protocol | Purpose |
|---|---|---|
| 8080 | TCP | Headscale API (localhost only) |
| 443 | TCP | Web UI (HTTPS) |
| 3478 | UDP | Tailscale STUN |
| 41641 | UDP | Tailscale DERP |
Exit nodes allow devices to route all internet traffic through the VPN server, making it appear as if they're browsing from the server's location.
# List routes that need approval
headscale routes list
# Approve exit node for a device
headscale routes enable --identifier NODE_ID --route 0.0.0.0/0
headscale routes enable --identifier NODE_ID --route ::/0
# Check Headscale is running
systemctl status headscale
# Check PHP-FPM
systemctl status ea-php81-php-fpm
# Test API directly
curl -sk "https://tailscale.tappedin.fm/api/nodes"
# Restart services
systemctl restart headscale
systemctl restart ea-php81-php-fpm
systemctl reload nginx
headscale preauthkeys list --user USERNAMEjournalctl -u headscale -n 50# Verify NAT rules
iptables -t nat -L POSTROUTING -n | grep 100.64.0.0
# Check IP forwarding
sysctl net.ipv4.ip_forward
# Re-apply exit node config
/usr/local/bin/setup-exit-node.sh
# Monitor all services
/home/devinecr/apps/hubnode/monitoring/universal-service-monitor.sh
# View monitoring logs
tail -f /var/log/universal-service-monitor.log
Direct download links for all platforms:
Last Updated: 2025-10-09 | Headscale v0.23.0