BEFORE deploying to production, you MUST change the default database password:
-
Generate a strong password:
openssl rand -base64 32
-
Update
.envfile:POSTGRES_PASSWORD=your_strong_password_here
-
Update
config/config.yaml:database: postgres: pass: your_strong_password_here # Must match .env
The following files are excluded by .gitignore and should NEVER be committed:
.env- Contains your actual passwords and configurationdata/- Contains Headscale state and keysbackups/- Contains database backups
Before exposing to the internet:
- Changed default PostgreSQL password
- Updated
server_urlin config.yaml to your actual domain - Configured proper DNS records
- Configured SSL/TLS in nginx.conf (for production)
- Reviewed and configured ACL policies
- Set up regular backups
- Limited pre-auth key lifetime
- Reviewed and secured open ports
- Use short expiration times (24h recommended)
- Use
--ephemeralfor temporary devices - Regularly audit and expire unused keys:
./scripts/headscale.sh keys list default
- The metrics endpoint (port 8080) is bound to localhost only
- PostgreSQL is NOT exposed outside the Docker network
- Use firewall rules to restrict access to nginx ports
# Regular security updates
docker compose pull
docker compose up -d
# Monitor logs for suspicious activity
docker compose logs -f headscale
# Regular backups
./scripts/backup.shIf you discover a security vulnerability:
- Do NOT open a public issue
- Contact the maintainer privately
- Provide detailed information about the vulnerability
- Allow reasonable time for a fix before public disclosure
Implement least-privilege access control:
{
"acls": [
{
"action": "accept",
"src": ["group:admin"],
"dst": ["*:*"]
},
{
"action": "accept",
"src": ["group:users"],
"dst": ["tag:services:80,443"]
}
]
}Encrypt backups if storing remotely:
# Backup and encrypt
./scripts/backup.sh
gpg --symmetric --cipher-algo AES256 backups/database_*.sqlEnable metrics collection and monitor for:
- Unusual connection patterns
- Failed authentication attempts
- Unexpected node registrations
curl http://localhost:8080/metricsThis repository contains example configurations with default/weak passwords for development purposes only. These MUST be changed before any production use.
Default values that MUST be changed:
- PostgreSQL password:
changeme - Server URL:
http://localhost:8000