Skip to content

Security Guide for VPN Exit Controller

This document outlines security considerations, best practices, and hardening procedures for the VPN Exit Controller system.

Table of Contents

  1. Network Security
  2. Authentication and Authorization
  3. Container Security
  4. SSL/TLS Security
  5. Data Protection
  6. Operational Security
  7. Compliance Considerations
  8. Security Hardening

Network Security

Firewall Configuration

The VPN Exit Controller requires specific firewall rules for secure operation:

# Allow SSH (change default port)
ufw allow 2222/tcp

# Allow web management interface (behind Traefik)
ufw allow 80/tcp
ufw allow 443/tcp

# Allow Tailscale mesh network
ufw allow 41641/udp

# Allow OpenVPN traffic for exit nodes
ufw allow 1194/udp
ufw allow 443/tcp

# Block all other incoming traffic by default
ufw default deny incoming
ufw default allow outgoing

# Enable firewall
ufw enable

Network Isolation

Proxmox LXC Security

  • Privileged Containers: The system requires privileged LXC containers for Docker operations
  • Container Isolation: Use lxc.apparmor.profile: unconfined carefully and only when necessary
  • Network Segmentation: Place the LXC container on an isolated VLAN (vmbr1)
# Example LXC configuration for security
cat >> /etc/pve/lxc/201.conf << EOF
# Security settings
lxc.apparmor.profile: generated
lxc.seccomp.profile: /usr/share/lxc/config/seccomp
# Only use unconfined when Docker requires it
EOF

Docker Network Security

  • Bridge Networks: Use custom Docker networks instead of default bridge
  • Network Policies: Implement container-to-container communication restrictions
  • Port Exposure: Only expose necessary ports (8080 for API, Redis port internally only)

VPN Tunnel Security

OpenVPN Configuration

  • Cipher Suite: Use AES-256-GCM or ChaCha20-Poly1305
  • Authentication: Use SHA-256 or stronger for HMAC
  • Perfect Forward Secrecy: Enable TLS-auth with rotating keys
  • Certificate Validation: Implement strict certificate checking

NordVPN Integration Security

  • Credential Storage: Store NordVPN credentials securely (see Data Protection section)
  • Server Verification: Verify NordVPN server certificates
  • Protocol Selection: Prefer OpenVPN over IKEv2 for better auditability

Tailscale Mesh Network Security

Authentication

  • Auth Keys: Use ephemeral auth keys when possible
  • ACL Policies: Implement strict Access Control Lists
  • Node Authorization: Require manual node approval
// Example Tailscale ACL
{
  "acls": [
    {
      "action": "accept",
      "src": ["group:admins"],
      "dst": ["vpn-exit-controller:8080"]
    }
  ],
  "groups": {
    "group:admins": ["[email protected]"]
  }
}

Authentication and Authorization

HTTP Basic Authentication

The system currently uses HTTP Basic Authentication with the following security considerations:

Current Implementation Issues

# SECURITY WARNING: Default credentials are exposed
ADMIN_USER = os.getenv("ADMIN_USER", "admin")
ADMIN_PASS = os.getenv("ADMIN_PASS", "changeme")

Security Recommendations

  1. Change Default Credentials Immediately

    # Set secure environment variables
    export ADMIN_USER="secure_admin_user"
    export ADMIN_PASS="$(openssl rand -base64 32)"
    

  2. Use Strong Password Policy

  3. Minimum 16 characters
  4. Include uppercase, lowercase, numbers, and symbols
  5. Avoid dictionary words
  6. Rotate passwords regularly (90 days)

  7. Implement Rate Limiting

    # Add to FastAPI middleware
    from slowapi import Limiter
    from slowapi.util import get_remote_address
    
    limiter = Limiter(key_func=get_remote_address)
    
    @app.post("/api/auth/login")
    @limiter.limit("5/minute")
    async def login(request: Request, ...):
        # Login logic
    

API Security

JWT Token Management

  • Secret Key: Use cryptographically secure random keys
  • Token Expiration: Set appropriate token lifetimes (24 hours max)
  • Refresh Tokens: Implement token refresh mechanism
# Generate secure secret key
openssl rand -hex 32

API Key Security

  • Rotation: Implement regular API key rotation
  • Scoping: Use least-privilege principle for API access
  • Monitoring: Log all API key usage

Service Credential Storage

NordVPN Credentials

Current storage in /opt/vpn-exit-controller/configs/auth.txt is insecure.

Secure Implementation:

# Use HashiCorp Vault or similar
vault kv put secret/nordvpn username="your_username" password="your_password"

# Or encrypt with gpg
echo "username:password" | gpg --symmetric --armor > /opt/vpn-exit-controller/configs/auth.txt.gpg

Tailscale Auth Keys

  • Ephemeral Keys: Use time-limited auth keys
  • Key Storage: Store in secure key management system
  • Access Logging: Monitor auth key usage

Cloudflare API Tokens

  • Scoped Tokens: Use DNS-only tokens with domain restrictions
  • Token Rotation: Regular rotation schedule
  • Environment Variables: Never hardcode in configuration files

Container Security

Docker Security Best Practices

Image Security

# Use specific, non-root base images
FROM ubuntu:22.04@sha256:specific-hash

# Create non-root user
RUN useradd -r -u 1001 -m -c "vpn user" -d /home/vpn -s /bin/bash vpn

# Use non-root user
USER vpn

# Verify signatures
RUN curl -fsSL https://tailscale.com/install.sh | sh

Runtime Security

# docker-compose.yml security settings
services:
  api:
    security_opt:
      - no-new-privileges:true
    read_only: true
    tmpfs:
      - /tmp
      - /var/tmp
    cap_drop:
      - ALL
    cap_add:
      - NET_ADMIN  # Only if required for VPN

Container Isolation

Network Isolation

# Create isolated networks
networks:
  vpn-internal:
    driver: bridge
    internal: true
  vpn-external:
    driver: bridge

Resource Limits

services:
  api:
    deploy:
      resources:
        limits:
          cpus: '1.0'
          memory: 512M
        reservations:
          cpus: '0.5'
          memory: 256M

Privileged Container Considerations

The VPN nodes require privileged access for network operations:

Risk Mitigation

  • Minimal Privileges: Only grant necessary capabilities
  • Network Namespaces: Use separate network namespaces
  • Monitoring: Enhanced monitoring for privileged containers
# Minimal privileged configuration
services:
  vpn-node:
    privileged: false
    cap_add:
      - NET_ADMIN
      - NET_RAW
    devices:
      - /dev/net/tun

SSL/TLS Security

Traefik SSL Configuration

Let's Encrypt Integration

# traefik.yml - Secure ACME configuration
certificatesResolvers:
  cf:
    acme:
      email: "[email protected]"
      storage: /letsencrypt/acme.json
      dnsChallenge:
        provider: cloudflare
        delayBeforeCheck: 60

SSL Security Headers

# security-headers.yml - Enhanced headers
http:
  middlewares:
    security-headers:
      headers:
        customResponseHeaders:
          X-Frame-Options: "DENY"
          X-Content-Type-Options: "nosniff"
          X-XSS-Protection: "1; mode=block"
          Strict-Transport-Security: "max-age=31536000; includeSubDomains; preload"
          Content-Security-Policy: "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'"
          Referrer-Policy: "strict-origin-when-cross-origin"
          Permissions-Policy: "geolocation=(), microphone=(), camera=()"

Certificate Management

Automatic Renewal

# Verify certificate renewal
docker exec traefik cat /letsencrypt/acme.json | jq '.cf.Certificates[0].certificate' | base64 -d | openssl x509 -text -noout

Certificate Monitoring

#!/bin/bash
# Certificate expiry monitoring script
CERT_PATH="/opt/vpn-exit-controller/traefik/letsencrypt/acme.json"
EXPIRY_DAYS=30

# Extract and check certificate expiry
# Add to cron for regular monitoring

Data Protection

Logging Security

Log Configuration

# Secure logging configuration
import logging
from logging.handlers import RotatingFileHandler

# Avoid logging sensitive data
class SensitiveDataFilter(logging.Filter):
    def filter(self, record):
        # Remove passwords, tokens, etc.
        record.msg = re.sub(r'password=[^&\s]+', 'password=***', str(record.msg))
        record.msg = re.sub(r'token=[^&\s]+', 'token=***', str(record.msg))
        return True

handler = RotatingFileHandler('/var/log/vpn-controller.log', maxBytes=10485760, backupCount=5)
handler.addFilter(SensitiveDataFilter())

Log Retention Policy

  • Retention Period: 90 days for operational logs
  • Security Logs: 1 year minimum
  • Compliance Logs: As required by regulations
  • Log Rotation: Daily rotation with compression

Sensitive Data Handling

Environment Variables

# Secure environment variable handling
cat > /opt/vpn-exit-controller/.env << EOF
# Never commit this file to version control
SECRET_KEY=$(openssl rand -hex 32)
ADMIN_USER=secure_admin
ADMIN_PASS=$(openssl rand -base64 32)
TAILSCALE_AUTHKEY=tskey-auth-***
NORDVPN_USER=***
NORDVPN_PASS=***
CLOUDFLARE_API_TOKEN=***
EOF

chmod 600 /opt/vpn-exit-controller/.env

Redis Security

# redis.conf security settings
requirepass "$(openssl rand -base64 32)"
bind 127.0.0.1
protected-mode yes
port 0  # Disable TCP port
unixsocket /var/run/redis/redis.sock
unixsocketperm 770

Backup and Recovery Security

Encrypted Backups

#!/bin/bash
# Secure backup script
BACKUP_DIR="/secure/backups"
DATE=$(date +%Y%m%d_%H%M%S)

# Create encrypted backup
tar -czf - /opt/vpn-exit-controller | gpg --symmetric --cipher-algo AES256 > "$BACKUP_DIR/vpn-controller-$DATE.tar.gz.gpg"

# Set secure permissions
chmod 600 "$BACKUP_DIR/vpn-controller-$DATE.tar.gz.gpg"

Operational Security

System Monitoring

Security Monitoring

# Install fail2ban for brute force protection
apt install fail2ban

# Configure jail for API endpoints
cat > /etc/fail2ban/jail.d/vpn-api.conf << EOF
[vpn-api]
enabled = true
port = 8080
filter = vpn-api
logpath = /var/log/vpn-controller.log
maxretry = 5
bantime = 3600
EOF

Performance Monitoring

  • Resource Usage: Monitor CPU, memory, disk usage
  • Network Traffic: Monitor unusual traffic patterns
  • Container Health: Monitor container status and resource usage

Security Updates

Update Schedule

  • Security Updates: Weekly automated security updates
  • System Updates: Monthly maintenance windows
  • Container Images: Monthly base image updates
# Automated security updates
cat > /etc/apt/apt.conf.d/50unattended-upgrades << EOF
Unattended-Upgrade::Allowed-Origins {
    "\${distro_id}:\${distro_codename}-security";
};
Unattended-Upgrade::AutoFixInterruptedDpkg "true";
Unattended-Upgrade::Remove-Unused-Dependencies "true";
EOF

Access Control

SSH Hardening

# /etc/ssh/sshd_config security settings
Port 2222
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
X11Forwarding no
MaxAuthTries 3
ClientAliveInterval 300
ClientAliveCountMax 2

User Management

  • Principle of Least Privilege: Grant minimum required permissions
  • Regular Audits: Monthly access reviews
  • Multi-Factor Authentication: Implement for privileged accounts

Incident Response

Response Plan

  1. Detection: Automated alerting for security events
  2. Containment: Immediate isolation procedures
  3. Investigation: Forensic data collection
  4. Recovery: Secure restoration procedures
  5. Lessons Learned: Post-incident review

Emergency Procedures

# Emergency shutdown script
#!/bin/bash
# Stop all VPN nodes
docker stop $(docker ps -q --filter "ancestor=vpn-exit-node:latest")

# Stop main services
systemctl stop vpn-controller
systemctl stop docker

# Block all traffic
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT DROP

Compliance Considerations

Privacy Regulations

GDPR Compliance

  • Data Minimization: Collect only necessary data
  • Retention Limits: Implement data retention policies
  • User Rights: Provide data access and deletion capabilities
  • Consent Management: Document legal basis for processing

Data Processing Records

{
  "processing_activity": "VPN Traffic Routing",
  "data_categories": ["IP addresses", "Connection timestamps", "Traffic volumes"],
  "legal_basis": "Legitimate interest",
  "retention_period": "30 days",
  "security_measures": ["Encryption", "Access controls", "Audit logging"]
}

VPN Service Terms

NordVPN Compliance

  • Terms of Service: Regular review of provider terms
  • Usage Monitoring: Ensure compliance with usage limits
  • Prohibited Activities: Monitor and prevent policy violations

Data Residency

Geographic Restrictions

  • Data Location: Understand where data is processed and stored
  • Cross-Border Transfers: Implement appropriate safeguards
  • Jurisdiction Requirements: Comply with local data protection laws

Audit Trail Maintenance

Comprehensive Logging

# Audit logging implementation
import structlog

audit_logger = structlog.get_logger("audit")

def log_admin_action(user, action, resource, result):
    audit_logger.info(
        "admin_action",
        user=user,
        action=action,
        resource=resource,
        result=result,
        timestamp=datetime.utcnow().isoformat()
    )

Security Hardening

System Hardening

Kernel Security

# /etc/sysctl.d/99-security.conf
# Network security
net.ipv4.ip_forward=1  # Required for VPN routing
net.ipv4.conf.all.send_redirects=0
net.ipv4.conf.default.send_redirects=0
net.ipv4.conf.all.accept_redirects=0
net.ipv4.conf.default.accept_redirects=0

# Memory protection
kernel.dmesg_restrict=1
kernel.kptr_restrict=1
kernel.yama.ptrace_scope=1

File System Security

# Secure mount options
# /etc/fstab
tmpfs /tmp tmpfs defaults,nodev,nosuid,noexec 0 0
tmpfs /var/tmp tmpfs defaults,nodev,nosuid,noexec 0 0

Service Configuration Security

Systemd Service Hardening

# /etc/systemd/system/vpn-controller.service
[Unit]
Description=VPN Exit Controller
After=docker.service

[Service]
Type=exec
User=vpn-controller
Group=vpn-controller
ExecStart=/opt/vpn-exit-controller/start.sh
Restart=always
RestartSec=10

# Security settings
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
PrivateTmp=true
PrivateDevices=true
ProtectKernelTunables=true
ProtectKernelModules=true
ProtectControlGroups=true
ReadWritePaths=/opt/vpn-exit-controller

Regular Security Assessments

Security Checklist

Monthly Checks: - [ ] Review access logs for anomalies - [ ] Update all container images - [ ] Check certificate expiry dates - [ ] Review firewall rules - [ ] Audit user access

Quarterly Checks: - [ ] Penetration testing of API endpoints - [ ] Review and update security policies - [ ] Audit third-party dependencies - [ ] Review backup and recovery procedures

Annual Checks: - [ ] Comprehensive security audit - [ ] Business continuity testing - [ ] Compliance assessment - [ ] Security training updates

Automated Security Scanning

# Container vulnerability scanning
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \
  aquasec/trivy image vpn-exit-node:latest

# System vulnerability scanning
lynis audit system

Vulnerability Management

Vulnerability Scanning

  • Automated Scans: Daily vulnerability scans
  • Patch Management: Prioritized patching based on severity
  • Zero-Day Response: Emergency response procedures

Security Tools

# Install security monitoring tools
apt install -y \
  aide \
  rkhunter \
  chkrootkit \
  lynis \
  fail2ban

Security Incident Contacts

Additional Resources


Last Updated: 2025-08-04
Version: 1.0
Review Schedule: Quarterly

Important: This security guide should be reviewed and updated regularly to address new threats and vulnerabilities. All security measures should be tested in a non-production environment before implementation.