445 lines
10 KiB
Markdown
445 lines
10 KiB
Markdown
---
|
|
# Secure VPN Server - Ansible Collection
|
|
|
|
Production-grade Ansible collection for deploying secure VPN infrastructure with **two-tier architecture**: admin control plane (ValleyForge) managing user VPN endpoints (VPN1/VPN2/VPN3).
|
|
|
|
## Architecture
|
|
|
|
### Two-Tier VPN Infrastructure
|
|
|
|
```
|
|
Tier 1: Admin Control Plane (ValleyForge)
|
|
• WireGuard admin VPN (10.100.0.0/24)
|
|
• Ansible control node
|
|
• GitHub Actions runner (future)
|
|
• 2-5 admin users
|
|
|
|
Tier 2: User Data Plane (VPN1/VPN2/VPN3)
|
|
• User-facing VPN endpoints
|
|
• 50-70 users per endpoint (200 total)
|
|
• Separate VPN networks (10.200.x.0/24)
|
|
• Gateway to collaboration tools
|
|
```
|
|
|
|
**Management Flow**: Admin → ValleyForge admin VPN → ValleyForge → Ansible → VPN1/VPN2/VPN3
|
|
|
|
**User Flow**: User → VPN1/VPN2/VPN3 → Collaboration Server
|
|
|
|
---
|
|
|
|
## Features
|
|
|
|
### System Hardening
|
|
- SSH hardening (key-only auth, strong ciphers, rate limiting)
|
|
- Kernel parameter hardening (sysctl)
|
|
- Automatic security updates
|
|
- Fail2ban intrusion prevention
|
|
- Auditd logging
|
|
- Minimal package installation
|
|
|
|
### WireGuard VPN
|
|
- Modern VPN with forward secrecy
|
|
- Per-user key management
|
|
- Automatic client config generation
|
|
- QR codes for mobile devices
|
|
- DNS encryption
|
|
|
|
### Secure Firewall
|
|
- **Management access restricted to ValleyForge**
|
|
- User VPN port accessible from internet
|
|
- SSH/management ports blocked from public
|
|
- Rate limiting
|
|
- Connection tracking
|
|
|
|
---
|
|
|
|
## Quick Start
|
|
|
|
### Prerequisites
|
|
|
|
- **ValleyForge deployed** with WireGuard admin VPN
|
|
- **Ansible installed** on ValleyForge
|
|
- **SSH access** from ValleyForge to VPN endpoints
|
|
- **Ubuntu 24.04** on all servers
|
|
|
|
### 1. Configure Inventory
|
|
|
|
On ValleyForge:
|
|
|
|
```bash
|
|
cd /root/ansible/secure_vpn_server
|
|
nano inventory/hosts.yml
|
|
```
|
|
|
|
Set your VPN endpoint IPs:
|
|
|
|
```yaml
|
|
vpn_servers:
|
|
hosts:
|
|
vpn1:
|
|
ansible_host: 203.0.113.10 # Your VPN1 public IP
|
|
vpn2:
|
|
ansible_host: 203.0.113.11 # Your VPN2 public IP
|
|
vpn3:
|
|
ansible_host: 203.0.113.12 # Your VPN3 public IP
|
|
|
|
vars:
|
|
valleyforge_public_ip: "185.112.147.205" # Your ValleyForge public IP
|
|
```
|
|
|
|
### 2. Configure Variables
|
|
|
|
```bash
|
|
nano inventory/group_vars/vpn_servers.yml
|
|
```
|
|
|
|
**CRITICAL**: Set management access sources:
|
|
|
|
```yaml
|
|
# Allow management from ValleyForge
|
|
management_allowed_sources:
|
|
- "185.112.147.205" # Your ValleyForge public IP
|
|
|
|
# Configure users
|
|
wg_peers:
|
|
- name: user1
|
|
- name: user2
|
|
- name: user3
|
|
```
|
|
|
|
### 3. Validate Configuration
|
|
|
|
```bash
|
|
ansible-playbook -i inventory/hosts.yml playbooks/validate.yml
|
|
```
|
|
|
|
### 4. Deploy
|
|
|
|
```bash
|
|
# Test deployment
|
|
ansible-playbook -i inventory/hosts.yml playbooks/site.yml --check
|
|
|
|
# Deploy to single endpoint (test)
|
|
ansible-playbook -i inventory/hosts.yml playbooks/site.yml --limit vpn1
|
|
|
|
# Deploy to all endpoints
|
|
ansible-playbook -i inventory/hosts.yml playbooks/site.yml
|
|
```
|
|
|
|
### 5. Retrieve Configs
|
|
|
|
```bash
|
|
scp -r root@203.0.113.10:/root/wireguard-client-configs/ /root/vpn1-configs/
|
|
scp -r root@203.0.113.11:/root/wireguard-client-configs/ /root/vpn2-configs/
|
|
scp -r root@203.0.113.12:/root/wireguard-client-configs/ /root/vpn3-configs/
|
|
```
|
|
|
|
---
|
|
|
|
## Documentation
|
|
|
|
- **[TWO_TIER_DEPLOYMENT.md](docs/TWO_TIER_DEPLOYMENT.md)** - Complete two-tier architecture deployment guide
|
|
- **[USAGE.md](docs/USAGE.md)** - Detailed usage guide
|
|
- **[VALLEYFORGE_BOOTSTRAP.md](../VALLEYFORGE_BOOTSTRAP.md)** - ValleyForge setup guide
|
|
- **[TWO_TIER_VPN_ARCHITECTURE.md](../TWO_TIER_VPN_ARCHITECTURE.md)** - Architecture overview
|
|
|
|
---
|
|
|
|
## Firewall Configuration
|
|
|
|
### Management Access
|
|
|
|
**Restricted to ValleyForge only**:
|
|
|
|
```yaml
|
|
management_allowed_sources:
|
|
- "185.112.147.205" # ValleyForge public IP
|
|
# - "10.100.0.0/24" # Or ValleyForge admin VPN (if routing configured)
|
|
```
|
|
|
|
**Management ports** (SSH, HTTP, HTTPS, etc.):
|
|
- ✅ Accessible from ValleyForge
|
|
- ❌ Blocked from internet
|
|
|
|
**User VPN port** (51820):
|
|
- ✅ Accessible from internet
|
|
|
|
### Access Matrix
|
|
|
|
| Source | Destination | Port | Result |
|
|
|--------|-------------|------|--------|
|
|
| Internet | VPN1/2/3 | 51820 (user VPN) | ✅ ALLOWED |
|
|
| ValleyForge | VPN1/2/3 | 22 (SSH) | ✅ ALLOWED |
|
|
| Internet | VPN1/2/3 | 22 (SSH) | ❌ BLOCKED |
|
|
| Internet | VPN1/2/3 | 80/443 | ❌ BLOCKED |
|
|
|
|
---
|
|
|
|
## Directory Structure
|
|
|
|
```
|
|
secure_vpn_server/
|
|
├── galaxy.yml # Collection metadata
|
|
├── README.md # This file
|
|
├── requirements.txt # Python dependencies
|
|
├── requirements.yml # Ansible collections
|
|
├── playbooks/
|
|
│ ├── site.yml # Full deployment
|
|
│ ├── hardening.yml # Hardening only
|
|
│ ├── wireguard.yml # WireGuard only
|
|
│ ├── firewall.yml # Firewall only
|
|
│ └── validate.yml # Configuration validation
|
|
├── roles/
|
|
│ ├── system_hardening/ # SSH, sysctl, fail2ban, auditd
|
|
│ ├── wireguard_server/ # WireGuard VPN
|
|
│ └── secure_firewall/ # UFW firewall + management access control
|
|
├── inventory/
|
|
│ ├── hosts.yml # Server inventory
|
|
│ ├── group_vars/
|
|
│ │ └── vpn_servers.yml # VPN endpoint configuration
|
|
│ └── host_vars/
|
|
│ ├── vpn1.yml # VPN1 specific config
|
|
│ ├── vpn2.yml # VPN2 specific config
|
|
│ └── vpn3.yml # VPN3 specific config
|
|
└── docs/
|
|
├── TWO_TIER_DEPLOYMENT.md # Two-tier deployment guide
|
|
└── USAGE.md # Detailed usage guide
|
|
```
|
|
|
|
---
|
|
|
|
## Configuration Examples
|
|
|
|
### Minimal Configuration
|
|
|
|
```yaml
|
|
# inventory/group_vars/vpn_servers.yml
|
|
|
|
# REQUIRED: Management access sources
|
|
management_allowed_sources:
|
|
- "185.112.147.205" # ValleyForge public IP
|
|
|
|
# Users
|
|
wg_peers:
|
|
- name: user1
|
|
- name: user2
|
|
|
|
# VPN settings (defaults are fine)
|
|
wg_network: "10.200.0.0/24" # Overridden per host
|
|
vpn_only_mode: true
|
|
```
|
|
|
|
### Advanced Configuration
|
|
|
|
```yaml
|
|
# System settings
|
|
system_timezone: "UTC"
|
|
ssh_port: 2222 # Custom SSH port
|
|
|
|
# WireGuard settings
|
|
wg_port: 51820
|
|
|
|
# Users with manual IPs
|
|
wg_peers:
|
|
- name: alice
|
|
ip: 10.200.0.10
|
|
- name: bob
|
|
ip: 10.200.0.11
|
|
|
|
# Management access
|
|
management_allowed_sources:
|
|
- "185.112.147.205" # ValleyForge public IP
|
|
- "10.100.0.0/24" # ValleyForge admin VPN (if routing configured)
|
|
|
|
# Additional management ports
|
|
management_ports:
|
|
- port: 2222
|
|
proto: tcp
|
|
comment: "SSH"
|
|
- port: 8080
|
|
proto: tcp
|
|
comment: "Outline Manager"
|
|
|
|
# Security features
|
|
fail2ban_enabled: true
|
|
auditd_enabled: true
|
|
unattended_upgrades_enabled: true
|
|
ssh_rate_limit: true
|
|
```
|
|
|
|
---
|
|
|
|
## Usage
|
|
|
|
### Deploy to All Endpoints
|
|
|
|
```bash
|
|
ansible-playbook -i inventory/hosts.yml playbooks/site.yml
|
|
```
|
|
|
|
### Deploy to Single Endpoint
|
|
|
|
```bash
|
|
ansible-playbook -i inventory/hosts.yml playbooks/site.yml --limit vpn1
|
|
```
|
|
|
|
### Deploy Specific Components
|
|
|
|
```bash
|
|
# Only hardening
|
|
ansible-playbook -i inventory/hosts.yml playbooks/hardening.yml
|
|
|
|
# Only WireGuard
|
|
ansible-playbook -i inventory/hosts.yml playbooks/wireguard.yml
|
|
|
|
# Only firewall
|
|
ansible-playbook -i inventory/hosts.yml playbooks/firewall.yml
|
|
```
|
|
|
|
### Add Users
|
|
|
|
```bash
|
|
# Edit variables
|
|
nano inventory/group_vars/vpn_servers.yml
|
|
|
|
# Add user
|
|
wg_peers:
|
|
- name: user1
|
|
- name: user2
|
|
- name: new_user3 # Add this
|
|
|
|
# Re-deploy WireGuard
|
|
ansible-playbook -i inventory/hosts.yml playbooks/wireguard.yml --limit vpn1
|
|
|
|
# Retrieve new config
|
|
scp root@vpn1-ip:/root/wireguard-client-configs/new_user3.conf /root/
|
|
```
|
|
|
|
### Monitor Endpoints
|
|
|
|
```bash
|
|
# Check WireGuard status
|
|
ansible vpn_servers -i inventory/hosts.yml -m shell -a "wg show"
|
|
|
|
# Check firewall status
|
|
ansible vpn_servers -i inventory/hosts.yml -m shell -a "ufw status"
|
|
|
|
# Check services
|
|
ansible vpn_servers -i inventory/hosts.yml -m shell -a "systemctl status wg-quick@wg0"
|
|
```
|
|
|
|
---
|
|
|
|
## Troubleshooting
|
|
|
|
### Can't SSH from ValleyForge After Deployment
|
|
|
|
**Use VPS console/VNC**:
|
|
|
|
```bash
|
|
# Check firewall
|
|
sudo ufw status verbose
|
|
|
|
# Temporarily allow your IP
|
|
sudo ufw allow from YOUR_VALLEYFORGE_IP to any port 22
|
|
|
|
# Or disable firewall temporarily
|
|
sudo ufw disable
|
|
```
|
|
|
|
### Wrong ValleyForge IP in Firewall
|
|
|
|
```bash
|
|
# On ValleyForge, update group_vars
|
|
nano inventory/group_vars/vpn_servers.yml
|
|
|
|
# Fix the IP
|
|
management_allowed_sources:
|
|
- "CORRECT.IP.ADDRESS.HERE"
|
|
|
|
# Re-deploy firewall
|
|
ansible-playbook -i inventory/hosts.yml playbooks/firewall.yml
|
|
```
|
|
|
|
### Validation Fails
|
|
|
|
```bash
|
|
# Check that management_allowed_sources is set
|
|
cat inventory/group_vars/vpn_servers.yml | grep management_allowed_sources
|
|
|
|
# Should show:
|
|
# management_allowed_sources:
|
|
# - "185.112.147.205"
|
|
```
|
|
|
|
---
|
|
|
|
## Security Best Practices
|
|
|
|
### ✅ What This Collection Does
|
|
|
|
- **SSH Hardening**: Key-only auth, strong ciphers, rate limiting
|
|
- **Kernel Hardening**: Secure sysctl parameters
|
|
- **Automatic Updates**: Security patches applied automatically
|
|
- **Intrusion Prevention**: Fail2ban blocks brute force
|
|
- **Audit Logging**: Track security-relevant events
|
|
- **Management Access Control**: Only from ValleyForge
|
|
- **Forward Secrecy**: VPN traffic protected even if keys compromised
|
|
|
|
### ⚠️ Important Notes
|
|
|
|
**Management Access**: Once deployed, management ports are ONLY accessible from ValleyForge. Test SSH access before deploying!
|
|
|
|
**ValleyForge IP**: Ensure `management_allowed_sources` contains your actual ValleyForge IP.
|
|
|
|
**Idempotent**: Safe to re-run playbooks anytime.
|
|
|
|
---
|
|
|
|
## Requirements
|
|
|
|
- **Control Machine**: ValleyForge with Ansible 2.15+
|
|
- **Target Servers**: Ubuntu 24.04 LTS (or 22.04)
|
|
- **SSH Access**: Root or sudo user with SSH key authentication
|
|
- **Python**: Python 3.8+ on target servers
|
|
|
|
---
|
|
|
|
## Installation
|
|
|
|
### On ValleyForge
|
|
|
|
```bash
|
|
# Install Ansible
|
|
pip3 install -r requirements.txt
|
|
|
|
# Install Ansible collections
|
|
ansible-galaxy collection install -r requirements.yml
|
|
```
|
|
|
|
---
|
|
|
|
## Support
|
|
|
|
- **Documentation**: See `docs/` directory
|
|
- **Issues**: GitHub issues
|
|
- **Security**: Report security issues privately
|
|
|
|
---
|
|
|
|
## License
|
|
|
|
MIT License
|
|
|
|
---
|
|
|
|
## Version
|
|
|
|
1.1.0 - Two-Tier Architecture Support
|
|
|
|
---
|
|
|
|
## Author
|
|
|
|
Security Infrastructure Team
|