# Connecting Devices to Headscale VPN > Step-by-step guide for connecting various devices to your Headscale mesh network > Created: 2025-11-11 ## Overview Once connected to Headscale, devices can access all services via mesh IPs (10.99.0.x): - Organizr: http://10.99.0.1:9999 - Portainer: http://10.99.0.1:8001 - Netdata: http://10.99.0.1:19999 - All other services using mesh IPs ## Prerequisites **You need a pre-auth key from Headscale:** ```bash # Generate a new pre-auth key (run on tower-of-joy) docker exec headscale headscale preauthkeys create --user homelab --expiration 24h # Output example: # b4c17f9e9f01ea2e54b24e0369e2949bd28bfaf46944c634 ``` **Save this key - you'll use it to connect each device.** ## macOS (MacBook/iMac) ### Method 1: Tailscale App (Recommended) **Step 1: Install Tailscale** ```bash # Option A: Using Homebrew brew install tailscale # Option B: Download from website # Visit: https://tailscale.com/download/mac # Download and install the .pkg file ``` **Step 2: Start Tailscale** ```bash # Start the Tailscale service sudo tailscaled install-system-daemon sudo /Applications/Tailscale.app/Contents/MacOS/Tailscale up ``` **Step 3: Connect to Headscale** Open the Tailscale app from menu bar → Preferences → Login Server OR use command line: ```bash sudo tailscale up --login-server=http://:8085 \ --authkey= \ --hostname=macbook # Example: # sudo tailscale up --login-server=http://your-public-ip:8085 \ # --authkey=b4c17f9e9f01ea2e54b24e0369e2949bd28bfaf46944c634 \ # --hostname=macbook ``` **Step 4: Verify Connection** ```bash # Check status tailscale status # Should show: # 10.99.0.1 tower-of-joy homelab linux - # 10.99.0.2 macbook homelab darwin - # Get your mesh IP tailscale ip -4 # Example output: 10.99.0.2 ``` **Step 5: Test Access** ```bash # Ping tower-of-joy ping 10.99.0.1 # Access Organizr open http://10.99.0.1:9999 # Or use curl curl http://10.99.0.1:9999 ``` ### Method 2: Using Public IP (If port 8085 forwarded) If you've forwarded port 8085 on your router: ```bash sudo tailscale up --login-server=http://:8085 \ --authkey= \ --hostname=macbook ``` ## Linux (Laptop/Desktop) ```bash # Install Tailscale curl -fsSL https://tailscale.com/install.sh | sh # Connect to Headscale sudo tailscale up --login-server=http://:8085 \ --authkey= \ --hostname=linux-laptop # Verify tailscale status ping 10.99.0.1 # Access Organizr xdg-open http://10.99.0.1:9999 ``` ## Windows **Step 1: Download Tailscale** - Visit: https://tailscale.com/download/windows - Download and run the installer **Step 2: Configure Custom Login Server** - After installation, Tailscale runs in system tray - Right-click Tailscale icon → Settings → Admin Console URL - Change to: `http://:8085` **Step 3: Login with Pre-Auth Key** - Right-click Tailscale icon → "Log in to Tailscale" - Use the pre-auth key when prompted **Step 4: Verify** ```powershell # In PowerShell or CMD tailscale status ping 10.99.0.1 # Access Organizr in browser start http://10.99.0.1:9999 ``` ## iOS (iPhone/iPad) **Step 1: Install Tailscale App** - Open App Store - Search "Tailscale" - Install official Tailscale app **Step 2: Configure Custom Control Server** - Open Tailscale app - Tap Settings (gear icon) - Tap "Use Custom Control Server" - Enter: `http://:8085` **Step 3: Connect** - Tap "Log In" - If prompted for key, use your pre-auth key - Grant VPN permissions when prompted **Step 4: Test** - Open Safari - Navigate to: `http://10.99.0.1:9999` - You should see Organizr interface ## Android **Step 1: Install Tailscale App** - Open Google Play Store - Search "Tailscale" - Install official Tailscale app **Step 2: Configure Custom Control Server** - Open Tailscale app - Tap menu (three dots) - Settings → Use custom control server - Enter: `http://:8085` **Step 3: Connect** - Tap "Log In" - Use pre-auth key if prompted - Grant VPN permissions **Step 4: Test** - Open Chrome/Firefox - Navigate to: `http://10.99.0.1:9999` - Organizr should load ## Troubleshooting ### Can't Connect to Headscale Server **Problem:** "Failed to connect to login server" **Solutions:** 1. **Check port 8085 is forwarded:** ```bash # Test from outside network curl http://:8085 # Should return HTML or redirect ``` 2. **Check Headscale is running:** ```bash # On tower-of-joy docker ps | grep headscale docker logs headscale ``` 3. **Use local IP if on same network:** ```bash # Instead of public IP, use local IP sudo tailscale up --login-server=http://192.168.86.149:8085 ... ``` ### Connected but Can't Reach Services **Problem:** Connected to VPN but can't access 10.99.0.1 **Check:** ```bash # Verify VPN connection tailscale status # Should show tower-of-joy as online # Test ping ping 10.99.0.1 # Should respond # Check firewall (on tower-of-joy) # Ensure mesh interface accepts traffic sudo iptables -L -n | grep tailscale ``` **Solution:** ```bash # On tower-of-joy, allow traffic from mesh network sudo iptables -A INPUT -i tailscale0 -j ACCEPT ``` ### Pre-Auth Key Expired **Problem:** "Invalid auth key" **Solution:** ```bash # Generate new key (on tower-of-joy) docker exec headscale headscale preauthkeys create --user homelab --expiration 24h # Use the new key to connect ``` ### DNS Not Resolving **Problem:** Can ping 10.99.0.1 but browser can't resolve **Solution:** - Use IP addresses directly: `http://10.99.0.1:9999` - Don't use hostnames unless you've configured DNS - Mesh IPs always work ## Verifying Your Connection ### Quick Test Checklist From your newly connected device: ```bash # 1. Check VPN status tailscale status # Should show: connected, online # 2. Get your mesh IP tailscale ip -4 # Example: 10.99.0.2 # 3. Ping tower-of-joy ping -c 4 10.99.0.1 # Should get responses # 4. Test Organizr curl -I http://10.99.0.1:9999 # Should return HTTP 200 OK # 5. Test other services curl -I http://10.99.0.1:8001 # Portainer curl -I http://10.99.0.1:19999 # Netdata curl -I http://10.99.0.1:3001 # Uptime Kuma ``` ### View All Connected Devices ```bash # On tower-of-joy docker exec headscale headscale nodes list # Shows all devices: # ID | Hostname | IP | Last Seen # 1 | tower-of-joy | 10.99.0.1 | now # 2 | macbook | 10.99.0.2 | now # 3 | iphone | 10.99.0.3 | now ``` ## Managing Devices ### Remove a Device ```bash # On tower-of-joy docker exec headscale headscale nodes list # Note the ID of the device to remove docker exec headscale headscale nodes delete ``` ### Rename a Device ```bash docker exec headscale headscale nodes rename ``` ### Generate Multiple Pre-Auth Keys ```bash # For different devices or time periods docker exec headscale headscale preauthkeys create --user homelab --expiration 1h --reusable docker exec headscale headscale preauthkeys create --user homelab --expiration 7d docker exec headscale headscale preauthkeys create --user homelab --expiration 30d ``` ### List All Pre-Auth Keys ```bash docker exec headscale headscale preauthkeys list ``` ## Security Best Practices ### Key Expiration - ✅ Use short expiration for one-time device setups (1h-24h) - ✅ Use longer expiration for trusted devices (7d-30d) - ⚠️ Never use permanent keys ### Device Management - ✅ Use descriptive hostnames (macbook, work-laptop, phone) - ✅ Regularly review connected devices - ✅ Remove old/unused devices - ✅ Regenerate keys periodically ### Network Security - ✅ Headscale port (8085) should be firewalled to trusted IPs if possible - ✅ Use strong authentication on services - ✅ Consider adding MFA to Organizr for public access - ✅ Monitor Headscale logs for suspicious activity ## Quick Reference ### MacBook Connection (Your Current Task) ```bash # 1. Generate pre-auth key (on tower-of-joy) docker exec headscale headscale preauthkeys create --user homelab --expiration 24h # 2. On MacBook brew install tailscale sudo tailscale up --login-server=http://:8085 \ --authkey= \ --hostname=macbook # 3. Verify tailscale status open http://10.99.0.1:9999 ``` --- **Next Steps After Connecting:** 1. Access Organizr: http://10.99.0.1:9999 2. Complete setup wizard 3. Add tabs for all services using mesh IPs 4. Enjoy unified dashboard from anywhere!