9.7 KiB
Prerequisites
Before You Start
- ValleyForge deployed with WireGuard admin VPN
- Ansible installed on ValleyForge
- SSH access from ValleyForge to VPN1/VPN2/VPN3
- ValleyForge public IP known
Step 1: Configure Inventory
Edit hosts.yml
On ValleyForge:
cd /root/ansible/secure_vpn_server
nano inventory/hosts.yml
Set your VPN endpoint IPs:
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
Step 2: Configure Variables
Edit group_vars/vpn_servers.yml
nano inventory/group_vars/vpn_servers.yml
CRITICAL: Set management_allowed_sources:
# Allow management from ValleyForge
management_allowed_sources:
- "185.112.147.205" # Your ValleyForge public IP
# Or if you have VPN routing configured:
# management_allowed_sources:
# - "10.100.0.0/24" # ValleyForge admin VPN network
Configure users:
wg_peers:
- name: user1
- name: user2
- name: user3
# Add up to 70 users per endpoint
Verify host_vars
Check that each VPN endpoint has unique networks:
cat inventory/host_vars/vpn1.yml
# wg_network: "10.200.0.0/24"
cat inventory/host_vars/vpn2.yml
# wg_network: "10.201.0.0/24"
cat inventory/host_vars/vpn3.yml
# wg_network: "10.202.0.0/24"
Step 3: Validate Configuration
Run validation playbook:
ansible-playbook -i inventory/hosts.yml playbooks/validate.yml
Expected output:
TASK [Validate management_allowed_sources is defined]
ok: [vpn1] => {
"msg": "✓ management_allowed_sources is configured"
}
TASK [Validate ValleyForge IP is set]
ok: [vpn1] => {
"msg": "✓ ValleyForge IP is configured: 185.112.147.205"
}
TASK [Display configuration summary]
ok: [vpn1] => {
"msg": [
"Host: vpn1",
"VPN Network: 10.200.0.0/24",
"Management allowed from: 185.112.147.205",
"Users configured: 3"
]
}
If validation fails:
- Check that
management_allowed_sourcesis set ingroup_vars/vpn_servers.yml - Check that
valleyforge_public_ipis set ininventory/hosts.yml - Check that each host has unique
wg_networkinhost_vars/
Step 4: Test SSH Access
From ValleyForge, test SSH to each endpoint:
ssh root@203.0.113.10 # VPN1
ssh root@203.0.113.11 # VPN2
ssh root@203.0.113.12 # VPN3
If SSH fails:
# Generate SSH key on ValleyForge
ssh-keygen -t ed25519
# Copy to VPN endpoints
ssh-copy-id root@203.0.113.10
ssh-copy-id root@203.0.113.11
ssh-copy-id root@203.0.113.12
Step 5: Deploy (Dry Run)
Test deployment without making changes:
ansible-playbook -i inventory/hosts.yml playbooks/site.yml --check --diff
Review output for errors:
- Syntax errors
- Missing variables
- Connection issues
Step 6: Deploy to Single Endpoint (Test)
Deploy to VPN1 only:
ansible-playbook -i inventory/hosts.yml playbooks/site.yml --limit vpn1
Monitor deployment (~10-15 minutes):
- System hardening
- WireGuard installation
- Firewall configuration
Expected final output:
TASK [Display deployment summary]
ok: [vpn1] => {
"msg": [
"=========================================",
"Deployment Complete!",
"=========================================",
"Server: vpn1",
"Public IP: 203.0.113.10",
"VPN Network: 10.200.0.0/24",
"Client configs: /root/wireguard-client-configs/",
"Firewall config: /root/firewall-config.txt"
]
}
Step 7: Verify VPN1 Deployment
Check Services
# SSH to VPN1 (should still work from ValleyForge)
ssh root@203.0.113.10
# Check WireGuard
sudo wg show
# Should show wg0 interface
# Check firewall
sudo ufw status verbose
# Should show:
# - Port 51820/udp ALLOW from Anywhere (user VPN)
# - Port 22/tcp ALLOW from 185.112.147.205 (ValleyForge)
# - Port 22/tcp DENY from Anywhere (default deny)
# Check services
systemctl status wg-quick@wg0
systemctl status fail2ban
systemctl status sshd
# Exit
exit
Test Management Access
From ValleyForge:
# SSH should work (you're from allowed source)
ssh root@203.0.113.10
# Connected!
From your local machine (NOT ValleyForge):
# SSH should be BLOCKED
ssh root@203.0.113.10
# Connection refused or timeout
This is correct! Management is restricted to ValleyForge.
Step 8: Retrieve User Configs
From ValleyForge:
# Download VPN1 user configs
scp -r root@203.0.113.10:/root/wireguard-client-configs/ /root/vpn1-configs/
# Check configs
ls /root/vpn1-configs/
# user1.conf user1_qr.txt
# user2.conf user2_qr.txt
# user3.conf user3_qr.txt
Step 9: Deploy to All Endpoints
If VPN1 test was successful:
# Deploy to VPN2 and VPN3
ansible-playbook -i inventory/hosts.yml playbooks/site.yml --limit vpn2,vpn3
# Or deploy to all at once
ansible-playbook -i inventory/hosts.yml playbooks/site.yml
Step 10: Retrieve All User Configs
# Download from all endpoints
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/
Firewall Rules Explained
What Gets Configured
On each VPN endpoint (VPN1/VPN2/VPN3):
# Public ports (user VPN)
Port 51820/udp → ALLOW from Anywhere
# Management ports (restricted to ValleyForge)
Port 22/tcp → ALLOW from 185.112.147.205
Port 22/tcp → DENY from Anywhere
# Default policy
Incoming → DENY
Outgoing → ALLOW
Why This Works
- User VPN access: Port 51820 is open to internet for end users
- Management access: SSH only from ValleyForge public IP
- Security: All other management blocked 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 |
Troubleshooting
Can't SSH from ValleyForge After Deployment
Problem: SSH connection refused from ValleyForge
Solution:
# Use VPS console/VNC to access VPN endpoint
# Check firewall rules
sudo ufw status verbose
# Check if ValleyForge IP is allowed
sudo ufw status | grep 185.112.147.205
# If not, add it
sudo ufw allow from 185.112.147.205 to any port 22
# Or temporarily disable firewall
sudo ufw disable
Wrong ValleyForge IP in Firewall
Problem: Set wrong IP in management_allowed_sources
Solution:
# 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 only
ansible-playbook -i inventory/hosts.yml playbooks/firewall.yml
Users Can't Connect to VPN
Problem: User VPN port not accessible
Solution:
# Check firewall on VPN endpoint
ssh root@vpn-ip # From ValleyForge
sudo ufw status | grep 51820
# Should show:
# 51820/udp ALLOW Anywhere
# If not, add it
sudo ufw allow 51820/udp
# Or re-deploy
ansible-playbook -i inventory/hosts.yml playbooks/firewall.yml
Validation Playbook Fails
Problem: management_allowed_sources not defined
Solution:
# Edit group_vars
nano inventory/group_vars/vpn_servers.yml
# Add this section
management_allowed_sources:
- "YOUR_VALLEYFORGE_IP"
# Re-run validation
ansible-playbook -i inventory/hosts.yml playbooks/validate.yml
Adding Users
Add Users to Existing Endpoint
# On ValleyForge
cd /root/ansible/secure_vpn_server
# Edit group_vars or host_vars
nano inventory/group_vars/vpn_servers.yml
# Add user
wg_peers:
- name: user1
- name: user2
- name: new_user4 # Add this
# Re-deploy WireGuard only
ansible-playbook -i inventory/hosts.yml playbooks/wireguard.yml --limit vpn1
# Retrieve new config
scp root@203.0.113.10:/root/wireguard-client-configs/new_user4.conf /root/
Monitoring
Check All Endpoints Status
# From ValleyForge
ansible vpn_servers -i inventory/hosts.yml -m shell -a "wg show"
ansible vpn_servers -i inventory/hosts.yml -m shell -a "ufw status"
ansible vpn_servers -i inventory/hosts.yml -m shell -a "systemctl status wg-quick@wg0"
Summary
Deployment complete when:
- ✅ All VPN endpoints deployed (VPN1/VPN2/VPN3)
- ✅ Firewall restricts management to ValleyForge
- ✅ User VPN ports open to internet
- ✅ User configs retrieved
- ✅ Services running (WireGuard, fail2ban, SSH)
Your infrastructure:
- Secure: Management only from ValleyForge
- Scalable: 200 users across 3 endpoints
- Manageable: Centralized Ansible control
- Resilient: Multiple endpoints for redundancy
Next steps:
- Distribute user configs
- Deploy collaboration server
- Set up monitoring
- Configure GitHub Actions (future)