382 lines
8.4 KiB
Markdown
382 lines
8.4 KiB
Markdown
# 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://<your-public-ip>:8085 \
|
|
--authkey=<your-preauth-key> \
|
|
--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://<your-public-ip>:8085 \
|
|
--authkey=<your-preauth-key> \
|
|
--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://<your-public-ip-or-local-ip>:8085 \
|
|
--authkey=<your-preauth-key> \
|
|
--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://<your-public-ip>: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://<your-public-ip>: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://<your-public-ip>: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://<your-public-ip>: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 <ID>
|
|
```
|
|
|
|
### Rename a Device
|
|
|
|
```bash
|
|
docker exec headscale headscale nodes rename <OLD-NAME> <NEW-NAME>
|
|
```
|
|
|
|
### 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://<your-public-ip>:8085 \
|
|
--authkey=<key-from-step-1> \
|
|
--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!
|