A complete solution for deploying VPN servers using Ansible, Docker, and Sing-Box with automatic TLS certificate management via Caddy. Includes a Python-based configuration application for proxy rule processing and subscription management.
β οΈ Disclaimer: This configuration is provided for educational and personal use. Users are responsible for complying with local laws and regulations regarding internet usage and proxy services.
- Automated Deployment: One-command deployment using Ansible
- Docker-based: Containerized VPN services for easy management
- TLS Certificates: Automatic HTTPS certificate generation with Caddy
- User Management: JSON-based user configuration with secure password generation
- Subscription System: Multi-tier subscription management with proxy configuration
- CFG App: Python application for proxy rule processing and NETSET expansion
- Template Processing: Support for Clash, Shadowrocket, and custom templates
- QR Code Generation: Easy client configuration sharing
- Multi-Protocol Support: Hysteria2, VMess, VLESS, and Reality protocols
- IP Aggregation: Smart IP block management and deduplication
- Static File Serving: Priority serving of static files (HTML, CSS, JS, images) before proxying to CFG App
- JSON Configuration: Caddy configured via JSON for better automation and version control
make
- Build automation toolansible
- Configuration managementssh
- Secure shell clientjq
- JSON processorsha256sum
(coreutils) orshasum
- Hash utilityqrencode
- QR code generation (optional, formake cn
)poetry
- Python dependency management (for CFG App)
- Linux host with SSH access
- Docker and Docker Compose (installed automatically via
make install-docker
)
git clone <repository-url>
cd vpn
Copy the environment template and set your secrets:
cp env.example .env
Edit .env
file:
# VPN Configuration Secrets
SALT="your-secret-salt-here"
OBFS_PASSWORD="your-obfuscation-password"
# Port Configuration
HTTP_PORT="80"
HTTPS_PORT="443"
HYSTERIA2_PORT="47012"
# CFG App Configuration
CONFIG_HOST="your-config-host.com"
Important:
SALT
is used for password hashing - keep it secret and consistentOBFS_PASSWORD
is used for traffic obfuscation - use a strong passwordCONFIG_HOST
is the hostname for configuration URLs
Copy the server configuration template:
cp servers.cfg.example servers.cfg
Edit servers.cfg
with your server details:
[vpn]
de-1 ansible_host=your-server-ip-or-hostname
[vpn:vars]
ansible_user=root
ansible_python_interpreter=/usr/bin/python3
Copy the configuration template:
cp config.json.example config.json
Edit config.json
with your users and subscription configuration:
{
"users": [
"user1",
"user2",
"user3"
],
"subs": {
"default": {
"de_1_contabo": {"protocol": "hy2", "host": "de-1.your-domain.com"},
"us_1_vultr": {"protocol": "vmess", "host": "us-1.your-domain.com"}
},
"premium": {
"sg_1_linode": {"protocol": "vless", "host": "sg-1.your-domain.com"}
}
}
}
Supported Protocols:
hy2
: Hysteria2 protocolvmess
: VMess protocolvless
: VLESS protocolreality
: Reality protocol (with automatic key generation)
make install-docker
This command will:
- Install Docker and Docker Compose on all target servers
- Configure Docker service to start on boot
make deploy
This command will:
- Validate environment configuration
- Deploy Sing-Box VPN server
- Configure Caddy for TLS certificates
- Set up Docker Compose services
- Generate user configurations
make reality-keys
Generates Reality protocol keys for enhanced security and performance.
make cfgapp-dev
This runs the Python configuration application locally for development and testing.
make passwords
Output format:
user1: a1b2c3d4e5f6...
user2: f6e5d4c3b2a1...
make cn NAME=username
This requires qrencode
and will:
- Generate a QR code for the specified user
- Save it as
~/Downloads/username.png
- Add the user to the VPN configuration if not exists
# Upgrade Ubuntu stribution
make ubuntu-dist-upgrade
# Upgrade Ubuntu release
make ubuntu-release-upgrade
# Add new static HTML page
echo '<h1>New Page</h1>' > vpn/static/new-page.html
# Add new CSS file
echo 'body { color: red; }' > vpn/static/css/custom.css
# Add new image (replace with actual image)
# cp your-image.png vpn/static/images/
# Restart Caddy to pick up changes
docker-compose restart proxy
vpn/
βββ README.md # This documentation
βββ Makefile # Build automation
βββ deploy_vpn.yml # Ansible deployment playbook
βββ install_docker.yml # Docker installation playbook
βββ ubuntu_dist_upgrade.yml # Ubuntu distribution upgrade
βββ ubuntu_release_upgrade.yml # Ubuntu release upgrade
βββ servers.cfg # Server inventory (create from example)
βββ servers.cfg.example # Server inventory template
βββ config.json # User and subscription configuration
βββ config.json.example # Configuration template
βββ .env # Environment secrets (create from example)
βββ env.example # Environment template
βββ generate_reality_keys.py # Reality protocol key generator
βββ generate_singbox_keys.py # Sing-Box key generator
βββ vpn/ # VPN configuration templates
βββ docker-compose.yml.j2 # Docker services configuration
βββ sing-box.json.j2 # VPN server configuration
βββ hysteria.yaml.j2 # Hysteria2 configuration
βββ caddy.json.j2 # Web server and TLS configuration
βββ caddy/ # Caddy web server configuration
β βββ Dockerfile # Caddy container
βββ static/ # Static files (served with priority)
β βββ index.html # Site under construction page
β βββ robots.txt # Search engine directives (disallows all crawling)
β βββ test.html # Test page for verification
β βββ css/
β β βββ style.css # Main stylesheet
β βββ images/ # Image assets (create as needed)
β βββ js/ # JavaScript files (create as needed)
β βββ .gitkeep # Git tracking file
βββ json-exporter.yml # Prometheus metrics exporter
βββ cfgapp/ # Python configuration application
βββ src/ # Application source code
β βββ auth.py # Authentication system
β βββ clash_processor.py # Clash configuration processor
β βββ config.py # Configuration management
β βββ main.py # Main application entry point
β βββ processor.py # Template processor
β βββ proxy_config.py # Proxy configuration
β βββ utils.py # Utility functions
βββ tests/ # Test suite
βββ examples/ # Template examples
β βββ clash_with_auth.tpl # Clash with authentication
β βββ clash_with_proxies.tpl # Clash with proxy rules
β βββ shadowrocket.tpl # Shadowrocket template
βββ templates/ # HTML templates
β βββ subscription.html # Subscription page template
βββ pyproject.toml # Python dependencies
βββ poetry.lock # Locked dependencies
βββ Dockerfile # Container configuration
βββ docker-compose.yml # Local development setup
βββ Makefile # CFG App build automation
βββ README.md # CFG App documentation
The vpn/static/
directory contains static files that are served with priority by Caddy:
- Priority Serving: Static files are served first, before any requests are proxied to the CFG App
- File Types: HTML, CSS, JavaScript, images, and other static assets
- Use Cases: Landing pages, documentation, client downloads, and other static content
- Performance: Direct file serving without application processing overhead
- Main Page: The root path
/
now shows "Site is under construction" instead of the CFG App
vpn/static/
βββ index.html # Site under construction page
βββ 404.html # Custom error page for 404/500 errors
βββ robots.txt # Search engine directives (disallows all crawling)
βββ test.html # Test page for verification
βββ css/
β βββ style.css # Main stylesheet
βββ images/ # Image assets (create as needed)
βββ js/ # JavaScript files (create as needed)
βββ .gitkeep # Ensures directory is tracked in git
Simply place files in the vpn/static/
directory and they will be automatically served. The file server will:
- Serve exact file matches (e.g.,
/about.html
servesstatic/about.html
) - Serve directory indexes if
index.html
exists - Fall back to CFG App for unmatched requests
Note: The vpn/static/
directory is automatically deployed to all servers when you run make deploy
. Any files you add to this directory will be available on all deployed servers.
Caddy is configured via caddy.json.j2
to serve content in the following priority order:
-
Static Files (
/static/
directory) - Highest priority- Direct file serving for HTML, CSS, JS, images
- No application processing overhead
- Ideal for landing pages and static content
-
CFG App (Python application) - Fallback
- Handles dynamic requests and API calls
- Processes templates and configurations
- Manages subscriptions and user authentication
-
Metrics Endpoints - Special handling
/node/metrics
- Node exporter metrics/hy2/metrics
- Hysteria2 metrics- Protected with basic authentication
Request β Caddy β Static File Check β CFG App (if no static file found)
Important: Since index.html
exists in the static directory, the root path /
will always show "Site is under construction" and never reach the CFG App. To access the CFG App, use specific paths like /cfg/
, /subscription/
, etc.
The JSON configuration explicitly defines static file handling:
- Root path
/
: Servesindex.html
from/static
directory - Static assets:
/css/*
,/js/*
,/images/*
,/robots.txt
,/test.html
are served directly - Fallback: All other requests are proxied to the CFG App on port 8003
- Custom 404 Page: Beautiful error page served from
/static/404.html
by Caddy - CFG App 404: Returns simple 404 status codes when templates or paths are not found
- Caddy Interception: Uses
handle_response
to intercept 404 responses and serve custom HTML - Error Logging: Comprehensive logging of all 404 and error responses
Note: Caddy automatically intercepts 404 responses from CFG App and serves the beautiful custom error page, ensuring consistent error handling across all endpoints.
The CFG App (vpn/cfgapp/
) provides:
- Template Processing: Process templates with RULE-SET and NETSET expansion
- Authentication: Built-in authentication system with salt-based hashing
- Clash Support: Full Clash YAML configuration processing
- Proxy Configuration: Dynamic proxy generation from JSON configuration
- Subscription Support: Multiple subscription tiers with query parameter selection
- IP Aggregation: Smart IP block aggregation and deduplication
- Shadowrocket Support: iOS Shadowrocket configuration generation
- Custom Templates: Extensible template system for various clients
Create a .env
file in vpn/cfgapp/
based on vpn/cfgapp/env.example
:
# API Configuration
CONFIG_HOST=your-config-host.com
API_HOST=your-config-host.com
# Authentication
SALT=your-secret-salt-here
# IP Aggregation Settings
IPV4_BLOCK_PREFIX=18
IPV6_BLOCK_PREFIX=32
# Server Configuration
HOST=0.0.0.0
PORT=8000
# Proxy Configuration
PROXY_CONFIG=/path/to/proxy_config.json
OBFS_PASSWORD=your-obfs-password-here
HYSTERIA2_PORT=47012
# Logging
LOG_LEVEL=INFO
cd vpn/cfgapp
# Install dependencies
poetry install
# Run tests
poetry run pytest
# Run development server
poetry run python src/main.py
# Build Docker image
make build
# Run in Docker
make run
- TLS Certificates: Automatically generated and managed by Caddy
- Password Hashing: Uses SHA256 with salt for secure password generation
- Traffic Obfuscation: Configurable obfuscation to bypass restrictions
- Docker Isolation: Services run in isolated containers
- Port Configuration: All ports are configurable via environment variables
- Subscription Security: Multi-tier access control with query parameter validation
- Reality Protocol: Enhanced security with automatic key generation
- IP Filtering: Configurable IP block management and filtering
Variable | Description | Default | Required |
---|---|---|---|
SALT |
Secret salt for password hashing | - | Yes |
OBFS_PASSWORD |
Password for traffic obfuscation | - | Yes |
HTTP_PORT |
HTTP server port | 80 | No |
HTTPS_PORT |
HTTPS server port | 443 | No |
HYSTERIA2_PORT |
Hysteria2 VPN port | 47012 | No |
CONFIG_HOST |
Configuration hostname | - | Yes |
-
"SALT is not set" error
- Ensure
.env
file exists and containsSALT
value - Run
cp env.example .env
and edit the file
- Ensure
-
SSH connection issues
- Verify SSH key authentication is configured
- Check server accessibility and firewall settings
-
Do 8B88 cker installation fails
- Ensure target server has internet access
- Check if Docker is already installed
-
CFG App issues
- Ensure Poetry is installed:
curl -sSL https://install.python-poetry.org | python3 -
- Install dependencies:
cd vpn/cfgapp && poetry install
- Check environment variables in
vpn/cfgapp/.env
- Ensure Poetry is installed:
-
Reality protocol issues
- Run
make reality-keys
to generate new keys - Ensure keys are properly configured in templates
- Run
- VPN server logs:
docker-compose logs sing-box
- Web server logs:
docker-compose logs caddy
- CFG App logs: Check application output during
make cfgapp-dev
- Ansible verbose mode: Add
-v
flag to make commands
# Test Reality configuration
python test_reality.py
# Test Reality with real keys
python test_reality_real.py
# Test CFG App endpoints
cd vpn/cfgapp && poetry run pytest
# Test Docker builds
make test-docker-build
# Test static file serving (after deployment)
curl http://your-server-ip/
curl http://your-server-ip/css/style.css
curl http://your-server-ip/robots.txt
- Prometheus Metrics: JSON exporter for monitoring VPN server metrics
- Docker Health Checks: Built-in health monitoring for all services
- Log Aggregation: Centralized logging through Docker Compose
# Update system packages
make ubuntu-dist-upgrade
# Update Docker images
docker-compose pull
docker-compose up -d
# Regenerate Reality keys (if needed)
make reality-keys
- Configuration files:
config.json
,servers.cfg
,.env
- Docker volumes: VPN data and certificates
- User configurations: Generated client configs
[Add your license information here]
[Add contribution guidelines here]
- REALITY_SETUP.md - Reality protocol setup guide
- vpn/cfgapp/README.md - CFG App detailed documentation
- vpn/cfgapp/examples/ - Template examples and usage