- Add Groups field to User struct with JSON storage - Include GetGroups() and SetGroups() helper methods - Extract groups from OIDC claims in FromClaim() - Add database migration 202509161200 for groups column - Update config-example.yaml with groups scope - Add comprehensive documentation and testing
8.6 KiB
8.6 KiB
Testing Verification Checklist
This checklist ensures the Headscale Docker environment is working correctly. Follow these steps to verify your setup.
✅ Pre-Setup Verification
System Requirements
- Docker installed and running
- Docker Compose installed
- Ports 8180, 9090, 50443 available on host
- At least 2GB free disk space
- Network subnet 10.99.0.0/24 not in use
Port Conflicts Check
# Check if required ports are free
sudo lsof -i :8180 :9090 :50443
# Should return no results if ports are free
Network Conflicts Check
# Check for existing Docker networks using similar subnets
docker network ls --format '{{.Name}}' | xargs -I {} sh -c 'echo "Network: {}"; docker network inspect {} 2>/dev/null | jq -r ".[0].IPAM.Config[0].Subnet // \"No subnet\""; echo' | grep -A1 "10.99"
# Should return no results
✅ Initial Setup Verification
1. Environment Startup
cd /path/to/headscale/docker-dev
make up
Expected results:
- All containers start without errors
- Headscale container shows "listening and serving" messages
- No port binding errors
- User 'testuser' created successfully
- Pre-auth keys generated and saved to .env
2. Container Status Check
docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"
Expected results:
headscale-serverstatus:Up X secondstailscale-client1status:Up X secondstailscale-client2status:Up X secondstest-webserverstatus:Up X seconds- Port mappings visible:
0.0.0.0:8180->8080/tcpetc.
3. Network Creation Check
docker network inspect headscale-dev_headscale-net
Expected results:
- Network exists with subnet
10.99.0.0/24 - Gateway at
10.99.0.1 - All 4 containers attached to network
- Each container has assigned IP in correct range
✅ Headscale Server Verification
1. Health Check
curl -s http://localhost:8180/health
Expected result:
- Returns:
{"status":"pass"}
2. User Management
docker exec headscale-server headscale users list
Expected results:
- Shows user with ID 1
- Username:
testuser - Created timestamp present
3. Pre-auth Keys
docker exec headscale-server headscale preauthkeys list --user 1
Expected results:
- Shows 2 pre-auth keys
- Both keys marked as
reusable: true - Expiration set to 24h from creation
- Keys not yet used
4. Configuration Validation
docker exec headscale-server headscale configtest
Expected result:
- Configuration validates successfully (if command exists)
- Or server starts without configuration errors
✅ Tailscale Client Verification
1. Client Registration
docker exec headscale-server headscale nodes list
Expected results:
- Shows 2 nodes (client1, client2)
- Both nodes have status
online - IP addresses:
100.64.0.1and100.64.0.2 - IPv6 addresses:
fd7a:115c:a1e0::1andfd7a:115c:a1e0::2 - Both nodes associated with
testuser - No expired nodes
2. Client Status
docker exec tailscale-client1 tailscale status
docker exec tailscale-client2 tailscale status
Expected results:
- Client1 shows itself at
100.64.0.1 - Client1 shows client2 at
100.64.0.2 - Client2 shows itself at
100.64.0.2 - Client2 shows client1 at
100.64.0.1 - Both show status as logged in to
testuser
3. Authentication Verification
cat .env | grep TS_AUTHKEY
Expected results:
- Two auth keys present:
TS_AUTHKEY_CLIENT1andTS_AUTHKEY_CLIENT2 - Keys are non-empty 32-character hex strings
- Keys are different from each other
✅ Network Connectivity Testing
1. Docker Network Connectivity
# Test basic Docker networking
docker exec tailscale-client1 ping -c 3 headscale
docker exec tailscale-client1 ping -c 3 10.99.0.22
docker exec tailscale-client2 ping -c 3 10.99.0.21
Expected results:
- All pings successful with 0% packet loss
- Round trip times < 10ms (local network)
- DNS resolution working (headscale resolves to 10.99.0.10)
2. Tailscale Network Connectivity
# Test Tailscale VPN connectivity
docker exec tailscale-client1 tailscale ping client2
docker exec tailscale-client2 tailscale ping client1
Expected results:
- Both pings return successful "pong" messages
- Response shows Tailscale IP (100.64.0.x)
- Response shows underlying transport (via 10.99.0.x:port)
- Response time < 1s
3. IP-level Connectivity
# Test direct IP ping through Tailscale
docker exec tailscale-client1 ping -c 3 100.64.0.2
docker exec tailscale-client2 ping -c 3 100.64.0.1
Expected results:
- Pings successful through Tailscale tunnel
- 0% packet loss
- Consistent round trip times
✅ Application Layer Testing
1. Web Server Connectivity
# Test HTTP connectivity through Tailscale
docker exec tailscale-client1 curl -s http://webserver | grep -i "hello"
Expected results:
- Successfully retrieves web page
- HTML content contains expected text
- No connection errors
2. Make Target Testing
# Test automation commands
make status
make ping-test
Expected results:
make statusshows all nodes onlinemake ping-testreports successful connectivity- No error messages in output
✅ Security Verification
1. ACL Policy Check
docker exec headscale-server headscale policy get
Expected results:
- Policy loaded successfully
- Shows rule allowing testuser@headscale to communicate
- No policy parsing errors
2. Encryption Verification
# Check that traffic is encrypted (this is implicit in Tailscale)
docker exec tailscale-client1 tailscale status --json | jq '.Peer[] | {Name: .HostName, Online: .Online, LastSeen: .LastSeen}'
Expected results:
- Peers show as online
- Recent LastSeen timestamps
- Secure connections established
3. Noise Protocol Verification
docker exec headscale-server ls -la /var/lib/headscale/noise_private.key
Expected results:
- Noise private key file exists
- File has appropriate permissions
- Non-zero file size
✅ Performance Testing
1. Latency Test
# Test latency through Tailscale
docker exec tailscale-client1 sh -c 'for i in {1..10}; do tailscale ping client2; done'
Expected results:
- All pings successful
- Consistent low latency (< 1s for local setup)
- No timeout errors
2. Throughput Test (Optional)
# Basic throughput test using nc (if available)
docker exec tailscale-client2 nc -l 8888 > /dev/null &
docker exec tailscale-client1 sh -c 'yes | head -c 1M | nc 100.64.0.2 8888'
Expected results:
- Data transfer completes successfully
- No connection refused errors
✅ Log Analysis
1. Check for Errors
# Check all container logs for errors
docker logs headscale-server 2>&1 | grep -i error
docker logs tailscale-client1 2>&1 | grep -i error
docker logs tailscale-client2 2>&1 | grep -i error
Expected results:
- No critical errors in Headscale logs
- No authentication failures
- No network connectivity errors
- Warning messages acceptable (non-blocking)
2. Successful Operations
# Look for success indicators
docker logs headscale-server 2>&1 | grep "listening and serving"
Expected results:
- Headscale shows "listening and serving" for all ports
- No startup failures
- Database operations successful
✅ Cleanup Verification
1. Controlled Shutdown
make down
Expected results:
- All containers stop gracefully
- No force-kill required
- Networks removed cleanly
2. Complete Cleanup
make clean
Expected results:
- All containers removed
- All volumes removed
- Networks removed
- .env file cleaned up
🔧 Troubleshooting Failed Checks
If any checks fail, refer to:
- TROUBLESHOOTING.md - Common issues and solutions
- Container logs -
docker logs <container-name> - Network inspection -
docker network inspect <network-name> - Headscale CLI -
docker exec headscale-server headscale --help
📊 Test Results Summary
Create a test report with:
- Test execution date/time
- All checklist items marked as pass/fail
- Any failures documented with error messages
- Environment details (Docker version, OS, etc.)
- Performance measurements if collected
✅ All checks passed? Congratulations! Your Headscale environment is fully functional.