Security Best Practices
Security recommendations and best practices for Wiretastix deployments.
Security is fundamental to any VPN solution. This guide covers security best practices for deploying and operating Wiretastix in production environments.
Security Architecture Overview
Wiretastix implements a defense-in-depth security model with multiple layers:
- Authentication: OIDC integration delegates authentication to your Identity Provider
- Authorization: Group-based access control via OIDC claims
- Network Security: WireGuard encryption + nftables firewall
- Transport Security: TLS for API and Web UI
- Data Security: Encrypted database connections, secure token storage
- Operational Security: Regular updates, monitoring, audit logs
TLS/HTTPS Configuration
Why TLS is Mandatory
HTTPS is not optional for Wiretastix in production:
- OIDC Requirement: Most Identity Providers (IdPs) refuse to redirect to HTTP URLs
- Credential Protection: Login tokens, API keys, session cookies must be encrypted
- MITM Prevention: Prevents man-in-the-middle attacks on authentication flows
- Compliance: Many security standards require encryption in transit
- Browser Security: Modern browsers block mixed content and flag HTTP as insecure
TLS Implementation Options
Option 1: Reverse Proxy with Let’s Encrypt (Recommended)
Use a reverse proxy (Nginx, Caddy, Apache, Traefik) to handle TLS:
Advantages:
- Automatic certificate renewal
- Free certificates from Let’s Encrypt
- Centralized certificate management
- Proven, battle-tested implementations
See the Reverse Proxy Setup Guide for complete configuration.
Option 2: Wiretastix Built-in ACME
Wiretastix can obtain Let’s Encrypt certificates automatically:
webserver:
binding: :443 # HTTPS port
acme-host:
- vpn.example.com
cert-dir: /etc/wiretastix/certs/
base: /
Requirements:
- Ports 80 and 443 accessible from internet
- Domain resolves to server
- No reverse proxy
Option 3: Custom Certificates
Use your own certificates (corporate CA, purchased certificates):
webserver:
binding: :443
tls-cert: /etc/wiretastix/certs/vpn.example.com.crt
tls-key: /etc/wiretastix/certs/vpn.example.com.key
base: /
Remember to:
- Protect private key (chmod 600)
- Renew before expiration
- Use strong key size (2048-bit minimum, 4096-bit recommended)
TLS Best Practices
- Use TLS 1.2 or newer only - Disable SSLv3, TLS 1.0, TLS 1.1
- Strong cipher suites - Prefer ECDHE with AES-GCM
- Enable HSTS - Force browsers to always use HTTPS
- Certificate monitoring - Alert before expiration
- Regular updates - Keep TLS libraries updated
Testing TLS Configuration
# Test SSL/TLS
openssl s_client -connect vpn.example.com:443 -servername vpn.example.com
# Check certificate expiration
echo | openssl s_client -connect vpn.example.com:443 2>/dev/null | openssl x509 -noout -dates
# Use SSL Labs (online)
# https://www.ssllabs.com/ssltest/analyze.html?d=vpn.example.com
Database Security
PostgreSQL Security
Connection Security:
db:
type: postgres
# Use SSL connection
dsn: postgresql://wiretastix:password@db-host:5432/wiretastix?sslmode=require
# Or with certificate validation
# dsn: postgresql://wiretastix:password@db-host:5432/wiretastix?sslmode=verify-full&sslrootcert=/etc/ssl/certs/ca.pem
Best Practices:
- Strong passwords: Use generated passwords (32+ characters)
- SSL/TLS connections: Always use
sslmode=requireminimum - Network isolation: Database only accessible from Wiretastix server
- Separate user: Dedicated database user, not superuser
- Regular backups: Encrypted, off-site backups
- Access logs: Enable and monitor PostgreSQL logs
PostgreSQL Configuration (postgresql.conf):
# Force SSL
ssl = on
ssl_cert_file = '/etc/ssl/certs/server.crt'
ssl_key_file = '/etc/ssl/private/server.key'
# Only allow SSL connections
ssl_min_protocol_version = 'TLSv1.2'
# Logging
logging_collector = on
log_connections = on
log_disconnections = on
log_statement = 'mod' # Log INSERT, UPDATE, DELETE
Access Control (pg_hba.conf):
# Only allow SSL connections
hostssl wiretastix wiretastix 10.0.0.0/8 md5
hostssl wiretastix wiretastix 127.0.0.1/32 md5
# Reject non-SSL
hostnossl all all 0.0.0.0/0 reject
SQLite Security
File Permissions:
Wiretastix hardens this itself: the daemon sets a process-wide 0077 umask at startup and chmods the SQLite database file to 0600 right after opening it (covering the DB file itself and, via the umask, any journal/WAL/shm sibling files it creates alongside it). You don’t need to chmod the database file by hand on a current version – but the containing directory and its ownership are still yours to set up:
# Directory
sudo chmod 755 /var/lib/wiretastix
sudo chown wiretastix:wiretastix /var/lib/wiretastix
Best Practices:
- Proper permissions: Database file only readable by Wiretastix user (enforced automatically; verify with
ls -lif you want to double-check rather than relying on it blindly) - Encrypted filesystem: Use LUKS or similar for data-at-rest encryption
- WAL mode: Enabled by default, provides better concurrency and crash recovery
- Regular backups: Automated, tested restore procedures
- Monitoring: File integrity monitoring (AIDE, Tripwire)
Secrets in Configuration
Never commit secrets to version control:
# Bad - hardcoded secret
oidc:
client-secret: "supersecretvalue123"
# Good - environment variable
oidc:
client-secret: "${OIDC_CLIENT_SECRET}"
# Good - separate file
oidc:
client-secret-file: /etc/wiretastix/secrets/oidc-client-secret
Protect configuration files:
sudo chmod 600 /etc/wiretastix/wiretastix.yaml
sudo chmod 600 /etc/default/wiretastix
sudo chown root:root /etc/wiretastix/wiretastix.yaml
API Token Security
Token Generation
Generate strong tokens:
# Generate initial token
sudo wiretastix-daemon --initialize -c /etc/wiretastix/wiretastix.yaml
# Save token immediately - cannot be retrieved later
Store securely:
- Use environment variables, not command history
- Store in secrets manager (Vault, AWS Secrets Manager)
- Never commit to version control
- Limit token distribution
Token Rotation
Regular token rotation reduces exposure window:
# Generate new token (invalidates old)
sudo wiretastix-daemon --initialize --wipe -c /etc/wiretastix/wiretastix.yaml
# Update all clients with new token
export WIRETASTIX_TOKEN="new-token-value"
Rotation schedule:
- Every 90 days for routine rotation
- Immediately if compromised
- After employee departures
- Before security audits
Token Usage
Secure token transmission:
# Good - HTTPS
curl -H "Authorization: Bearer ${TOKEN}" https://vpn.example.com/api/v1/peers
# Bad - HTTP (token visible in network traffic)
curl -H "Authorization: Bearer ${TOKEN}" http://vpn.example.com/api/v1/peers
Environment variables:
# Set in shell profile
export WIRETASTIX_API="https://vpn.example.com/api/v1/"
export WIRETASTIX_TOKEN="your-token-here"
# wiretastix-cli picks up both from the environment, so you never need
# --token on the command line (visible in shell history/process lists).
# It's still an interactive shell -- run the command at the prompt:
wiretastix-cli
> peer list
API Access Control
Restrict API binding:
apiserver:
# Localhost only - access via SSH tunnel
binding: 127.0.0.1:8095
# Or specific interface
binding: 10.0.1.10:8095
Firewall rules:
# Only allow API access from specific IPs
sudo ufw allow from 10.0.0.0/8 to any port 8095
# Or via reverse proxy with IP whitelisting
OIDC Security
Identity Provider Responsibility
The IdP is your security perimeter for authentication:
- Authentication: IdP validates user credentials (password, MFA, biometrics)
- Authorization: IdP provides group memberships via OIDC claims
- Session management: IdP handles session lifetime and logout
- Security policies: IdP enforces password policies, MFA requirements, rate limiting
Wiretastix trusts the IdP - secure your IdP properly:
- Enable MFA: Require multi-factor authentication for all users
- Strong password policies: Minimum length, complexity requirements
- Account lockout: Protect against brute force attacks
- Audit logging: Monitor authentication attempts
- Regular updates: Keep IdP software current
- Backup admins: Multiple administrators, avoid single points of failure
OIDC Configuration Security
Secure OIDC settings:
oidc:
name: "Production IdP"
client-id: "wiretastix-prod"
client-secret: "${OIDC_CLIENT_SECRET}" # Never hardcode
# Must be HTTPS
redirect-url: https://vpn.example.com/callback
# IdP endpoint
config-issuer: https://auth.example.com/.well-known/openid-configuration
# Strong cookie secret (32+ bytes)
cookie-secret: "${COOKIE_SECRET}" # Generate with: openssl rand -base64 32
# Require explicit approval
force-approval: true # Users must click "Allow" each time
# Token refresh
refresh-min-interval-sec: 300 # 5 minutes minimum
# Request necessary scopes only
scopes:
- openid
- email
- profile
- groups
- offline_access
# Group constraints
constraints:
groups:
- vpn-users # Only members of this group can access
Group-Based Authorization
Use groups for access control:
oidc:
constraints:
groups:
- vpn-full-access # Full network access
- vpn-limited # Restricted access
Benefits:
- Centralized management in IdP
- Automatic provisioning/deprovisioning
- Audit trail in IdP
- Consistent with other applications
Best practices:
- Use descriptive group names
- Document group purposes
- Regular group membership audits
- Remove users immediately on termination
Token Refresh Security
Wiretastix automatically refreshes OIDC tokens:
oidc:
# Minimum interval between refreshes
refresh-min-interval-sec: 300 # 5 minutes
# Require offline_access scope for refresh tokens
scopes:
- offline_access
Token refresh benefits:
- Users stay authenticated
- Group membership changes reflected quickly
- Revoked users disconnected within refresh interval
Security considerations:
- Shorter refresh interval = quicker revocation propagation
- Longer refresh interval = less IdP load
- Balance based on security requirements
OIDC Security Checklist
- HTTPS enabled for Wiretastix (IdP requirement)
- redirect-url matches exactly in IdP
- client-secret stored securely (environment variable)
- cookie-secret is strong random value
- MFA enabled in IdP
- Only necessary scopes requested
- Group constraints configured
- Token refresh enabled (offline_access scope)
- IdP audit logs monitored
- Regular access reviews conducted
Network Security
Firewall Configuration
Essential firewall rules:
# Allow WireGuard
sudo ufw allow 51820/udp
# Allow HTTPS (if exposed directly)
sudo ufw allow 443/tcp
# Allow HTTP (for Let's Encrypt only)
sudo ufw allow 80/tcp
# Deny everything else by default
sudo ufw default deny incoming
sudo ufw default allow outgoing
# Enable firewall
sudo ufw enable
WireGuard Security
Built-in security features:
- Encryption: ChaCha20-Poly1305 or AES-GCM
- Authentication: Curve25519 for key exchange
- Perfect forward secrecy: New keys for each session
- Identity hiding: IP addresses not exposed before authentication
WireGuard best practices:
Protect private key:
chmod 600 /etc/wiretastix/wg-private.keyRegular key rotation: Regenerate if compromised
Peer isolation: Use nftables rules to restrict peer-to-peer traffic
IP allocation: Use non-routable ranges (10.0.0.0/8, etc.)
Disable IP forwarding if not needed
nftables Security
Wiretastix uses nftables for group-based firewall rules:
Default deny policy:
chain forward {
type filter hook forward priority 0; policy drop;
# Only explicitly allowed traffic passes
}
Group-based rules:
- Each group has dedicated chain
- Rules applied per peer based on group membership
- Automatic updates when users join/leave groups
See NFTables Integration Guide for details.
Network Segmentation
Separate networks:
- Management network (SSH, API)
- VPN network (WireGuard clients)
- Internal resources (protected networks)
Example with multiple interfaces:
wireguard:
ifname: wg0
binding: ens192 # External interface
DDoS Protection
Rate limiting in nftables:
# Limit new connections
limit rate 10/minute burst 5 packets
Connection tracking:
# Drop invalid packets
ct state invalid drop
# Allow established connections
ct state {established,related} accept
Operational Security
Principle of Least Privilege
Service user:
# Run as dedicated user, not root
User=wiretastix
Group=wiretastix
File permissions:
# Configuration
chmod 600 /etc/wiretastix/wiretastix.yaml
# Logs
chmod 640 /var/log/wiretastix/wiretastix.log
The SQLite database file doesn’t need a manual chmod – Wiretastix sets it (and a process-wide 0077 umask) to 0600 itself on startup. wiretastix.yaml and the log directory are still your responsibility to lock down.
Capability-based security (Docker):
cap_add:
- NET_ADMIN # Only what's needed
- SYS_MODULE
cap_drop:
- ALL # Drop everything else
Regular Updates
Update schedule:
- Security patches: Within 24 hours
- Minor updates: Monthly
- Major updates: Quarterly (test first)
Update process:
# Backup first
sudo systemctl stop wiretastix
sudo tar czf /backup/wiretastix-backup-$(date +%Y%m%d).tar.gz /etc/wiretastix /var/lib/wiretastix
# Update
sudo apt update
sudo apt upgrade wiretastix
# Test
sudo systemctl start wiretastix
curl -k https://localhost:8085
# Verify
wiretastix-daemon -V
Monitoring and Alerting
Monitor these metrics:
- Failed authentication attempts
- Unusual peer connections
- High bandwidth usage
- Certificate expiration dates
- Service availability
- Database size growth
Set up alerts:
# Example: Certificate expiration
CHECK_CERT=$(echo | openssl s_client -connect vpn.example.com:443 2>/dev/null | openssl x509 -noout -checkend 604800)
if [ $? -eq 1 ]; then
echo "Certificate expires within 7 days!" | mail -s "ALERT: SSL Certificate Expiring" admin@example.com
fi
See Prometheus Metrics Guide for detailed monitoring.
Audit Logging
Enable audit logs:
# Log all API requests
log-level: info
# Database audit trail
# Wiretastix logs all peer additions, deletions, rule changes
Review logs regularly:
# Authentication failures
sudo journalctl -u wiretastix | grep -i "auth fail"
# Peer changes
sudo journalctl -u wiretastix | grep -i "peer"
# Rule changes
sudo journalctl -u wiretastix | grep -i "rule"
Log retention:
- Keep logs for compliance period (typically 90 days minimum)
- Archive to secure, immutable storage
- Protect log files (chmod 640)
Incident Response
Preparation:
- Document runbook for security incidents
- Identify response team members
- Establish communication channels
- Test recovery procedures
Response steps:
- Detect: Monitoring alerts, user reports
- Contain: Disable compromised accounts, block IPs
- Investigate: Review logs, identify scope
- Eradicate: Remove malicious access, patch vulnerabilities
- Recover: Restore from backups if needed
- Learn: Document lessons, update procedures
Compromise recovery:
There’s no bulk “disable all peers” command, and individual peers can’t be disabled either – only deleted. The effective kill switch is at the user level: disabling a user immediately removes every peer belonging to them from the live WireGuard interface (without deleting any records), and re-enabling brings them back.
wiretastix-cli
# Immediately cut off a compromised user's VPN access
> user disable jdoe
# Review their peers while you investigate
> user show jdoe
# Once confident, either restore access...
> user enable jdoe
# ...or remove the user (and all their peers) entirely
> user delete jdoe
Unmanaged/standalone peers created with peer create (see Managing
Peers) have no associated user to disable –
for those, revoking access means deleting the peer outright:
> peer list
> peer delete 42
If the server’s own WireGuard key may be compromised, rotate it and restart:
wg genkey | sudo tee /etc/wiretastix/wg-private.key
sudo systemctl restart wiretastix
Data Handling for Your Own Compliance Assessment
Wiretastix is infrastructure, not a compliance program. Whether a deployment satisfies GDPR, HIPAA, PCI DSS, SOC 2, ISO 27001, or any other framework depends on how your organization operates, documents, and audits itself – not on which VPN daemon it runs. Nothing here is a compliance claim, and Wiretastix has not been audited or certified against any of these frameworks.
If you’re doing your own assessment, here’s the personal data Wiretastix actually handles:
- User email addresses (from OIDC)
- User names/nicknames
- IP address assignments
- Connection logs
- Authentication events
Relevant technical controls covered elsewhere in this guide: TLS in transit, group-based access control via nftables, OIDC-backed authentication, and audit logging. One thing to be aware of: data at rest is not encrypted by default. The one exception is the OIDC JWT tokens, which can optionally be encrypted with a configured key (see the Configuration Reference) – without one, they’re stored in plaintext. Everything else (peer keys, user records, connection logs) is stored unencrypted in the database. If your assessment requires encryption at rest, plan for it at the infrastructure level (disk/volume encryption, PostgreSQL TDE, etc.).
Security Checklist
Use this checklist for security reviews:
Authentication & Authorization
- OIDC configured with production IdP
- MFA enabled in IdP
- Group-based access control configured
- Only necessary groups have access
- Regular access reviews scheduled
Network Security
- Firewall configured (ufw/nftables)
- Only necessary ports open
- WireGuard private key protected
- nftables rules applied per group
- Network segmentation implemented
Transport Security
- HTTPS enabled for Web UI
- HTTPS enabled for API
- Valid TLS certificates installed
- Certificate expiration monitoring
- TLS 1.2+ only, strong ciphers
Data Security
- Database connection encrypted (PostgreSQL SSL)
- Database file permissions correct (SQLite – set automatically to
0600on startup; verify rather than assume) - Configuration files protected (chmod 600)
- Secrets not in version control
- Backups encrypted and tested
API Security
- Strong API tokens generated
- Tokens stored securely
- Token rotation schedule defined
- API binding restricted (localhost or internal)
- Rate limiting implemented
Operational Security
- Running as non-root user
- Regular update schedule defined
- Monitoring and alerting configured
- Audit logs enabled and reviewed
- Incident response plan documented
Compliance
- Data retention policy defined
- Privacy policy published
- User consent obtained where required
- Audit trail maintained
- Regular security assessments scheduled
Additional Resources
- Reverse Proxy Setup - TLS configuration
- OIDC Configuration - Identity provider setup
- Backup and Recovery - Data protection
- NFTables Integration - Firewall rules
- Prometheus Metrics - Monitoring
- FAQ & Troubleshooting - Security questions
Security Contact
For security vulnerabilities, please contact the security team following responsible disclosure practices. Do not open public issues for security bugs.