CIS + inital

This commit is contained in:
2026-01-26 21:22:41 -05:00
parent 5b6e1567f9
commit 28db1d2104
65 changed files with 4555 additions and 2 deletions
+491
View File
@@ -0,0 +1,491 @@
---
# Two-Tier VPN Architecture Deployment Guide
## Architecture Overview
This Ansible collection is designed for a **two-tier VPN architecture**:
### 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** (Algo/Outline)
- **50-70 users per endpoint** (200 total)
- **Separate VPN networks**:
- VPN1: 10.200.0.0/24
- VPN2: 10.201.0.0/24
- VPN3: 10.202.0.0/24
---
## Prerequisites
### Before You Start
1. **ValleyForge deployed** with WireGuard admin VPN
2. **Ansible installed** on ValleyForge
3. **SSH access** from ValleyForge to VPN1/VPN2/VPN3
4. **ValleyForge public IP** known
---
## Step 1: Configure Inventory
### Edit hosts.yml
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
```
---
## Step 2: Configure Variables
### Edit group_vars/vpn_servers.yml
```bash
nano inventory/group_vars/vpn_servers.yml
```
**CRITICAL: Set management_allowed_sources**:
```yaml
# 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**:
```yaml
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:
```bash
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**:
```bash
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_sources` is set in `group_vars/vpn_servers.yml`
- Check that `valleyforge_public_ip` is set in `inventory/hosts.yml`
- Check that each host has unique `wg_network` in `host_vars/`
---
## Step 4: Test SSH Access
**From ValleyForge, test SSH to each endpoint**:
```bash
ssh root@203.0.113.10 # VPN1
ssh root@203.0.113.11 # VPN2
ssh root@203.0.113.12 # VPN3
```
**If SSH fails**:
```bash
# 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**:
```bash
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**:
```bash
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
```bash
# 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**:
```bash
# SSH should work (you're from allowed source)
ssh root@203.0.113.10
# Connected!
```
**From your local machine** (NOT ValleyForge):
```bash
# 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**:
```bash
# 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**:
```bash
# 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
```bash
# 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
1. **User VPN access**: Port 51820 is open to internet for end users
2. **Management access**: SSH only from ValleyForge public IP
3. **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**:
```bash
# 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**:
```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 only
ansible-playbook -i inventory/hosts.yml playbooks/firewall.yml
```
### Users Can't Connect to VPN
**Problem**: User VPN port not accessible
**Solution**:
```bash
# 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**:
```bash
# 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
```bash
# 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
```bash
# 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**:
1. ✅ All VPN endpoints deployed (VPN1/VPN2/VPN3)
2. ✅ Firewall restricts management to ValleyForge
3. ✅ User VPN ports open to internet
4. ✅ User configs retrieved
5. ✅ 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)
+467
View File
@@ -0,0 +1,467 @@
# Usage Guide
## Installation
### Prerequisites
**Control Machine** (your laptop/desktop):
- Linux or macOS
- Python 3.8+
- Ansible 2.15+
- SSH client
**Target Servers**:
- Ubuntu 24.04 LTS (or 22.04)
- Root or sudo access
- SSH key authentication configured
- Minimum 1GB RAM, 10GB disk
### Step 1: Install Ansible
```bash
# Using pip
pip3 install ansible
# Or using your package manager
# Ubuntu/Debian
sudo apt install ansible
# macOS
brew install ansible
```
### Step 2: Clone/Download Collection
```bash
# If from Git
git clone https://github.com/your-org/secure-vpn-server.git
cd secure-vpn-server
# Install dependencies
pip3 install -r requirements.txt
ansible-galaxy collection install -r requirements.yml
```
### Step 3: Configure SSH Access
```bash
# Generate SSH key if you don't have one
ssh-keygen -t ed25519
# Copy to server
ssh-copy-id root@185.112.147.205
# Test access
ssh root@185.112.147.205 "echo Connected"
```
## Configuration
### Inventory Setup
Create your inventory file:
```bash
cp inventory/hosts.yml inventory/production.yml
nano inventory/production.yml
```
**Single server**:
```yaml
all:
children:
vpn_servers:
hosts:
vpn-node1:
ansible_host: 185.112.147.205
ansible_user: root
```
**Multiple servers**:
```yaml
all:
children:
vpn_servers:
hosts:
vpn-node1:
ansible_host: 185.112.147.205
ansible_user: root
vpn-node2:
ansible_host: 203.0.113.11
ansible_user: root
vpn-node3:
ansible_host: 203.0.113.12
ansible_user: root
```
### Variable Configuration
Edit group variables:
```bash
nano inventory/group_vars/vpn_servers.yml
```
**Minimal configuration**:
```yaml
# WireGuard users
wg_peers:
- name: alice
- name: bob
- name: charlie
# VPN network
wg_network: "10.100.0.0/24"
# Enable VPN-only access
vpn_only_mode: true
```
**Advanced configuration**:
```yaml
# System settings
system_timezone: "America/New_York"
ssh_port: 2222 # Custom SSH port
# WireGuard settings
wg_network: "10.100.0.0/24"
wg_server_ip: "10.100.0.1"
wg_port: 51820
# WireGuard users with manual IPs
wg_peers:
- name: alice
ip: 10.100.0.10
- name: bob
ip: 10.100.0.11
- name: charlie
ip: 10.100.0.12
# Firewall settings
vpn_only_mode: true
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
```
## Deployment
### Full Deployment
Deploy everything (hardening + VPN + firewall):
```bash
ansible-playbook -i inventory/production.yml playbooks/site.yml
```
### Partial Deployment
Deploy specific components:
```bash
# Only hardening
ansible-playbook -i inventory/production.yml playbooks/hardening.yml
# Only WireGuard
ansible-playbook -i inventory/production.yml playbooks/wireguard.yml
# Only firewall
ansible-playbook -i inventory/production.yml playbooks/firewall.yml
```
### Targeted Deployment
Deploy to specific servers:
```bash
# Single server
ansible-playbook -i inventory/production.yml playbooks/site.yml --limit vpn-node1
# Multiple servers
ansible-playbook -i inventory/production.yml playbooks/site.yml --limit vpn-node1,vpn-node2
```
### Dry Run
Test without making changes:
```bash
ansible-playbook -i inventory/production.yml playbooks/site.yml --check --diff
```
## Post-Deployment
### Retrieve Client Configs
```bash
# Download all configs
scp -r root@185.112.147.205:/root/wireguard-client-configs/ ./
# View configs
ls wireguard-client-configs/
# alice.conf alice_qr.txt
# bob.conf bob_qr.txt
# charlie.conf charlie_qr.txt
```
### Distribute to Users
**Desktop users** (Linux/macOS/Windows):
- Send `.conf` file
- Install WireGuard: https://www.wireguard.com/install/
- Import config
**Mobile users** (iOS/Android):
- Send QR code text file
- Install WireGuard app
- Scan QR code: `cat alice_qr.txt`
### Verify Deployment
```bash
# Check services on server
ssh root@185.112.147.205
# WireGuard status
sudo wg show
# Firewall status
sudo ufw status verbose
# Service status
systemctl status wg-quick@wg0
systemctl status fail2ban
systemctl status auditd
```
## User Management
### Add New Users
1. Edit variables:
```bash
nano inventory/group_vars/vpn_servers.yml
```
2. Add user to `wg_peers`:
```yaml
wg_peers:
- name: alice
- name: bob
- name: charlie
- name: dave # New user
```
3. Re-run playbook:
```bash
ansible-playbook -i inventory/production.yml playbooks/wireguard.yml
```
4. Retrieve new config:
```bash
scp root@185.112.147.205:/root/wireguard-client-configs/dave.conf ./
```
### Remove Users
1. Remove from `wg_peers` list
2. Re-run playbook
3. Manually remove keys from server:
```bash
ssh root@185.112.147.205
rm /etc/wireguard/keys/dave_*
```
### Rotate Keys
```bash
# Backup old keys
ssh root@185.112.147.205
cp -r /etc/wireguard/keys /root/wireguard-keys-backup-$(date +%Y%m%d)
# Remove old keys
rm -rf /etc/wireguard/keys/*
# Re-run playbook to generate new keys
ansible-playbook -i inventory/production.yml playbooks/wireguard.yml
# Distribute new configs to all users
```
## Maintenance
### Update System Packages
```bash
# Automatic updates are enabled by default
# Manual update:
ssh root@185.112.147.205
apt update && apt upgrade -y
```
### Monitor Logs
```bash
# WireGuard logs
journalctl -u wg-quick@wg0 -f
# SSH attempts
journalctl -u sshd -f
# Fail2ban
journalctl -u fail2ban -f
# Audit logs
ausearch -ts recent
```
### Backup Configuration
```bash
# Backup from server
ssh root@185.112.147.205
tar czf /root/vpn-backup-$(date +%Y%m%d).tar.gz \
/etc/wireguard/ \
/root/wireguard-client-configs/ \
/etc/ssh/sshd_config \
/etc/ufw/
# Download backup
scp root@185.112.147.205:/root/vpn-backup-*.tar.gz ./
```
### Re-run Playbook
Safe to re-run anytime (idempotent):
```bash
ansible-playbook -i inventory/production.yml playbooks/site.yml
```
## Advanced Usage
### Custom SSH Port
```yaml
# In group_vars/vpn_servers.yml
ssh_port: 2222
management_ports:
- port: 2222 # Update firewall rule
proto: tcp
comment: "SSH"
```
### Multiple VPN Networks
Deploy separate VPN servers with different networks:
```yaml
# vpn-node1 (group_vars or host_vars)
wg_network: "10.100.0.0/24"
# vpn-node2
wg_network: "10.101.0.0/24"
```
### Disable VPN-Only Mode
Allow management access from internet:
```yaml
vpn_only_mode: false
```
⚠️ **Not recommended for production!**
### Custom Firewall Rules
```yaml
management_ports:
- port: 22
proto: tcp
comment: "SSH"
- port: 8080
proto: tcp
comment: "Outline Manager"
- port: 8065
proto: tcp
comment: "Mattermost"
- port: 443
proto: tcp
comment: "HTTPS"
public_ports:
- port: 51820
proto: udp
comment: "WireGuard"
- port: 80
proto: tcp
comment: "HTTP (public website)"
```
## Testing
### Test VPN Connection
**Desktop**:
```bash
# Import config
sudo wg-quick up alice
# Check connection
curl https://ifconfig.me
# Should show server IP
# Disconnect
sudo wg-quick down alice
```
**Mobile**:
1. Import config via QR code
2. Connect
3. Visit https://ifconfig.me
4. Verify server IP
### Test VPN-Only Access
```bash
# Before VPN: SSH should fail (if vpn_only_mode enabled)
ssh root@185.112.147.205
# Connection refused or timeout
# Connect to VPN
sudo wg-quick up alice
# After VPN: SSH should work
ssh root@10.100.0.1
# Connected!
```
### Test Firewall
```bash
# Check open ports from outside
nmap -p 22,51820 185.112.147.205
# Should show:
# 22/tcp closed (if vpn_only_mode)
# 51820/udp open
```
## Next Steps
- Read [SECURITY.md](SECURITY.md) for security best practices
- Read [TROUBLESHOOTING.md](TROUBLESHOOTING.md) for common issues
- Set up monitoring and alerting
- Configure backups
- Document your deployment