From cc14147e805432bca1007285c6fc08df17782b51 Mon Sep 17 00:00:00 2001 From: Sparticus Date: Mon, 26 Jan 2026 22:33:14 -0500 Subject: [PATCH] Moar playbooks --- inventory/group_vars/admin_control_plane.yml | 64 ++++++ inventory/hosts.yml | 63 ++++-- playbooks/deploy_all.yml | 106 +++++++++ playbooks/valleyforge.yml | 216 +++++++++++++++++++ 4 files changed, 428 insertions(+), 21 deletions(-) create mode 100644 inventory/group_vars/admin_control_plane.yml create mode 100644 playbooks/deploy_all.yml create mode 100644 playbooks/valleyforge.yml diff --git a/inventory/group_vars/admin_control_plane.yml b/inventory/group_vars/admin_control_plane.yml new file mode 100644 index 0000000..1df3c95 --- /dev/null +++ b/inventory/group_vars/admin_control_plane.yml @@ -0,0 +1,64 @@ +--- +# ValleyForge Admin Control Plane Configuration + +# Admin Users (for infrastructure management) +# These users will have SSH access and sudo privileges on ValleyForge +admin_users: + - username: alice + comment: "Alice - Infrastructure Lead" + groups: ["sudo"] + generate_keys: true + + - username: bob + comment: "Bob - Security Admin" + groups: ["sudo"] + generate_keys: true + +# WireGuard Admin VPN Configuration +# This VPN is for your admin team to securely access ValleyForge +wg_network: "10.100.0.0/24" +wg_server_address: "10.100.0.1/24" +wg_port: 51820 + +# Admin VPN peers (your infrastructure team) +wg_peers: + - name: admin1 + # ip: 10.100.0.10 # Auto-assigned + - name: admin2 + # ip: 10.100.0.11 # Auto-assigned + - name: admin3 + # ip: 10.100.0.12 # Auto-assigned + +# Firewall Configuration +# IMPORTANT: Set vpn_only_mode to false initially to allow SSH access +# After admin VPN is working, set to true and redeploy +vpn_only_mode: false # Change to true after admin VPN is configured + +management_allowed_sources: + - "0.0.0.0/0" # Allow from anywhere initially + # After admin VPN is working, change to: + # - "10.100.0.0/24" # Admin VPN network only + +management_ports: + - port: 22 + proto: tcp + comment: "SSH" + - port: 51820 + proto: udp + comment: "WireGuard Admin VPN" + +# SSH Hardening +# Keep root login enabled initially for bootstrapping +ssh_permit_root_login: "yes" # Change to "no" after admin users are working +ssh_password_authentication: "no" +ssh_max_auth_tries: 3 + +# Security Settings +enable_apparmor: true +enable_auditd: true +enable_fail2ban: true +enable_unattended_upgrades: true + +# Ansible Control Node Settings +valleyforge_repo_url: "https://git.hacker.supply/valleyforge/resist-vpn-infra.git" +valleyforge_clone_repo: true diff --git a/inventory/hosts.yml b/inventory/hosts.yml index a5d6dd7..5b3ec58 100644 --- a/inventory/hosts.yml +++ b/inventory/hosts.yml @@ -1,30 +1,55 @@ --- # Inventory File for Two-Tier VPN Architecture # -# This inventory is for managing VPN1, VPN2, VPN3 (user-facing VPN endpoints) -# from ValleyForge (admin control plane) -# -# Deploy this FROM ValleyForge server after: -# 1. ValleyForge is set up with WireGuard admin VPN -# 2. Ansible is installed on ValleyForge -# 3. SSH keys are configured from ValleyForge to VPN endpoints +# This inventory includes: +# 1. ValleyForge - Admin control plane (deploy first from local machine) +# 2. VPN1, VPN2, VPN3 - User-facing VPN endpoints (deploy from ValleyForge) all: children: - # User-facing VPN endpoints + # Admin Control Plane + # Deploy ValleyForge FIRST from your local machine + admin_control_plane: + hosts: + valleyforge: + ansible_host: 185.112.147.186 # ValleyForge public IP + ansible_user: root + + vars: + # ValleyForge-specific variables + # Admin VPN network for infrastructure management + wg_network: "10.100.0.0/24" + wg_server_address: "10.100.0.1/24" + + # Admin VPN users (your infrastructure team) + wg_peers: + - name: gozer + - name: admin2 + - name: admin3 + + # Firewall: Initially allow SSH from anywhere, then restrict to admin VPN + vpn_only_mode: false # Set to true after admin VPN is working + + # Repository to clone on ValleyForge + valleyforge_repo_url: "https://git.hacker.supply/valleyforge/resist-vpn-infra.git" + valleyforge_clone_repo: true + + # User-facing VPN Endpoints + # Deploy AFTER ValleyForge is set up + # Deploy FROM ValleyForge server vpn_servers: hosts: vpn1: - ansible_host: 203.0.113.10 # VPN1 public IP (CHANGE THIS!) + ansible_host: 185.112.147.205 # VPN1 public IP ansible_user: root - vpn2: - ansible_host: 203.0.113.11 # VPN2 public IP (CHANGE THIS!) - ansible_user: root - - vpn3: - ansible_host: 203.0.113.12 # VPN3 public IP (CHANGE THIS!) - ansible_user: root + # vpn2: + # ansible_host: 203.0.113.11 # VPN2 public IP (CHANGE THIS!) + # ansible_user: root + # + # vpn3: + # ansible_host: 203.0.113.12 # VPN3 public IP (CHANGE THIS!) + # ansible_user: root vars: # Common variables for all VPN servers @@ -32,8 +57,4 @@ all: # ValleyForge public IP (for firewall rules) # IMPORTANT: Change this to your actual ValleyForge IP! - valleyforge_public_ip: "185.112.147.205" - -# Note: ValleyForge itself is NOT in this inventory -# ValleyForge is the control plane where you run Ansible FROM -# It should be configured separately with its own WireGuard admin VPN + valleyforge_public_ip: "185.112.147.186" # (CHANGE THIS!) diff --git a/playbooks/deploy_all.yml b/playbooks/deploy_all.yml new file mode 100644 index 0000000..1298e08 --- /dev/null +++ b/playbooks/deploy_all.yml @@ -0,0 +1,106 @@ +--- +# Complete Two-Tier VPN Infrastructure Deployment +# +# This playbook deploys the entire infrastructure in the correct order: +# 1. ValleyForge (admin control plane) +# 2. VPN1, VPN2, VPN3 (user-facing VPN endpoints) +# +# Usage: +# # Deploy everything from your local machine: +# ansible-playbook -i inventory/hosts.yml playbooks/deploy_all.yml +# +# # Or deploy in phases: +# ansible-playbook -i inventory/hosts.yml playbooks/deploy_all.yml --tags valleyforge +# ansible-playbook -i inventory/hosts.yml playbooks/deploy_all.yml --tags vpn-endpoints + +- name: Phase 1 - Deploy ValleyForge Admin Control Plane + import_playbook: valleyforge.yml + tags: ['valleyforge', 'phase1'] + +- name: Phase 1 Complete - Pause for Manual Steps + hosts: localhost + gather_facts: no + tags: ['valleyforge', 'phase1'] + + tasks: + - name: Display next steps + ansible.builtin.debug: + msg: + - "=========================================" + - "Phase 1 Complete: ValleyForge Deployed" + - "=========================================" + - "" + - "Before proceeding to Phase 2, you must:" + - "" + - "1. Download admin VPN configs from ValleyForge:" + - " scp root@VALLEYFORGE-IP:/root/wireguard-client-configs/* ./" + - "" + - "2. Install WireGuard client on your machine" + - "" + - "3. Import admin VPN config and connect" + - "" + - "4. Test admin VPN connection:" + - " ping 10.100.0.1" + - "" + - "5. Copy Ansible SSH key to VPN endpoints:" + - " ssh root@VALLEYFORGE-IP" + - " ssh-copy-id -i /root/.ssh/ansible_ed25519 root@VPN1-IP" + - " ssh-copy-id -i /root/.ssh/ansible_ed25519 root@VPN2-IP" + - " ssh-copy-id -i /root/.ssh/ansible_ed25519 root@VPN3-IP" + - "" + - "6. Update inventory/hosts.yml on ValleyForge:" + - " - Set ansible_ssh_private_key_file: /root/.ssh/ansible_ed25519" + - " - Verify VPN endpoint IPs are correct" + - "" + - "7. Run Phase 2 FROM ValleyForge:" + - " cd /root/resist-vpn-infra" + - " ansible-playbook -i inventory/hosts.yml playbooks/site.yml" + - "" + - "=========================================" + + - name: Pause for manual steps + ansible.builtin.pause: + prompt: | + + Complete the manual steps above, then press ENTER to continue to Phase 2. + + Or press Ctrl+C to stop here and run Phase 2 manually later. + when: not (skip_pause | default(false)) + +- name: Phase 2 - Deploy VPN Endpoints + import_playbook: site.yml + tags: ['vpn-endpoints', 'phase2'] + when: deploy_vpn_endpoints | default(false) + +- name: Deployment Complete + hosts: localhost + gather_facts: no + tags: ['always'] + + tasks: + - name: Display final summary + ansible.builtin.debug: + msg: + - "=========================================" + - "Complete Infrastructure Deployment" + - "=========================================" + - "" + - "Phase 1: ValleyForge (Admin Control Plane)" + - " ✓ System hardening (CIS Level 1)" + - " ✓ Admin users created" + - " ✓ WireGuard admin VPN deployed" + - " ✓ Ansible control node configured" + - "" + - "Phase 2: VPN Endpoints (User VPN)" + - " {{ '✓' if deploy_vpn_endpoints | default(false) else '⏸' }} VPN1, VPN2, VPN3 deployment" + - " {{ '✓' if deploy_vpn_endpoints | default(false) else '⏸' }} User VPN configured" + - " {{ '✓' if deploy_vpn_endpoints | default(false) else '⏸' }} Firewall lockdown complete" + - "" + - "{% if not (deploy_vpn_endpoints | default(false)) %}" + - "To complete Phase 2, run from ValleyForge:" + - " cd /root/resist-vpn-infra" + - " ansible-playbook -i inventory/hosts.yml playbooks/site.yml" + - "{% endif %}" + - "" + - "Infrastructure ready for 200+ users!" + - "=========================================" diff --git a/playbooks/valleyforge.yml b/playbooks/valleyforge.yml new file mode 100644 index 0000000..9f223e6 --- /dev/null +++ b/playbooks/valleyforge.yml @@ -0,0 +1,216 @@ +--- +# ValleyForge Admin Control Plane Deployment +# +# This playbook deploys ValleyForge server with: +# - System hardening (CIS Level 1) +# - Admin users for infrastructure management +# - WireGuard admin VPN (for admin team access) +# - Ansible control node setup +# - Firewall (allows admin VPN, restricts SSH to admin VPN) + +- name: Deploy ValleyForge Admin Control Plane + hosts: valleyforge + become: yes + gather_facts: yes + + pre_tasks: + - name: Display deployment information + ansible.builtin.debug: + msg: + - "Deploying ValleyForge admin control plane to: {{ inventory_hostname }}" + - "IP Address: {{ ansible_default_ipv4.address }}" + - "OS: {{ ansible_distribution }} {{ ansible_distribution_version }}" + - "Admin VPN Network: {{ wg_network | default('10.100.0.0/24') }}" + + - name: Verify Ubuntu 24.04 + ansible.builtin.assert: + that: + - ansible_distribution == "Ubuntu" + - ansible_distribution_version is version('22.04', '>=') + fail_msg: "This playbook requires Ubuntu 22.04 or newer" + success_msg: "OS version check passed" + + roles: + - role: system_hardening + tags: ['hardening', 'security', 'cis'] + + - role: ssh_users + tags: ['users', 'ssh', 'security'] + when: admin_users is defined and admin_users | length > 0 + + - role: wireguard_server + tags: ['wireguard', 'vpn', 'admin-vpn'] + + - role: secure_firewall + tags: ['firewall', 'security'] + + post_tasks: + - name: Install Ansible and control node dependencies + ansible.builtin.apt: + name: + - ansible + - git + - python3-pip + - python3-venv + - jq + state: present + update_cache: yes + tags: ['ansible', 'control-node'] + + - name: Install Ansible collections for control node + ansible.builtin.command: + cmd: ansible-galaxy collection install {{ item }} + loop: + - community.general + - community.crypto + tags: ['ansible', 'control-node'] + register: galaxy_install + changed_when: "'was installed successfully' in galaxy_install.stdout" + + - name: Clone resist-vpn-infra repository + ansible.builtin.git: + repo: "{{ valleyforge_repo_url | default('https://git.hacker.supply/valleyforge/resist-vpn-infra.git') }}" + dest: /root/resist-vpn-infra + version: master + force: yes + tags: ['ansible', 'control-node', 'repo'] + when: valleyforge_clone_repo | default(true) + + - name: Generate SSH key for Ansible management + ansible.builtin.user: + name: root + generate_ssh_key: yes + ssh_key_type: ed25519 + ssh_key_file: .ssh/ansible_ed25519 + ssh_key_comment: "ansible@valleyforge" + tags: ['ansible', 'control-node', 'ssh'] + + - name: Display ValleyForge public key + ansible.builtin.slurp: + src: /root/.ssh/ansible_ed25519.pub + register: valleyforge_pubkey + tags: ['ansible', 'control-node', 'ssh'] + + - name: Save ValleyForge public key to file + ansible.builtin.copy: + content: "{{ valleyforge_pubkey.content | b64decode }}" + dest: /root/valleyforge_ansible_pubkey.txt + mode: '0644' + tags: ['ansible', 'control-node', 'ssh'] + + - name: Display deployment summary + ansible.builtin.debug: + msg: + - "=========================================" + - "ValleyForge Deployment Complete!" + - "=========================================" + - "" + - "Server: {{ inventory_hostname }}" + - "Public IP: {{ ansible_default_ipv4.address }}" + - "Admin VPN Network: {{ wg_network }}" + - "Admin Users: {{ admin_users | map(attribute='username') | list | join(', ') if admin_users is defined else 'none' }}" + - "" + - "Admin VPN Configs: /root/wireguard-client-configs/" + - "{% if admin_users is defined and admin_users | length > 0 %}SSH Keys: {{ ssh_keys_local_dir }}/{{ inventory_hostname }}/{% endif %}" + - "Ansible Public Key: /root/valleyforge_ansible_pubkey.txt" + - "Repository: /root/resist-vpn-infra" + - "" + - "Next steps:" + - "1. Download admin VPN configs from server" + - "2. Connect to admin VPN" + - "3. Copy Ansible public key to VPN endpoints:" + - " ssh-copy-id -i /root/.ssh/ansible_ed25519 root@VPN1-IP" + - "4. Configure /root/resist-vpn-infra/inventory/" + - "5. Deploy VPN endpoints: ansible-playbook -i inventory/hosts.yml playbooks/site.yml" + - "" + - "=========================================" + + - name: Save ValleyForge deployment summary + ansible.builtin.copy: + dest: /root/valleyforge-deployment-summary.txt + content: | + ValleyForge Admin Control Plane Deployment Summary + =================================================== + + Deployment Date: {{ ansible_date_time.iso8601 }} + Server: {{ inventory_hostname }} + Public IP: {{ ansible_default_ipv4.address }} + + Components Deployed: + - System Hardening (CIS Level 1 compliant) + - SSH User Management + - WireGuard Admin VPN Server + - Secure Firewall (Management access via admin VPN) + - Ansible Control Node + + Admin Users: + {% if admin_users is defined %} + {% for user in admin_users %} + - {{ user.username }} ({{ user.comment | default('') }}) + {% endfor %} + {% else %} + - None created (using root) + {% endif %} + + Admin VPN Configuration: + - Network: {{ wg_network }} + - Server IP: {{ wg_server_ip }} + - Port: {{ wg_port }} + - Admin Users: {{ wg_peers | length }} + + Ansible Control Node: + - Ansible version: {{ ansible_version.full }} + - Repository: /root/resist-vpn-infra + - SSH Key: /root/.ssh/ansible_ed25519 + - Public Key: /root/valleyforge_ansible_pubkey.txt + + Admin VPN Client Configurations: + {% for peer in wg_peers %} + - {{ peer.name }}: /root/wireguard-client-configs/{{ peer.name }}.conf + {% endfor %} + + Security Features (CIS Compliant): + - SSH hardened (key-only, strong ciphers) + - Root SSH login disabled (after admin users created) + - Password policies enforced + - AppArmor enabled and enforcing + - Comprehensive audit logging + - Automatic security updates enabled + - Fail2ban active + - Management ports restricted to admin VPN + + Next Steps: + ========== + + 1. Download Admin VPN Configs: + scp root@{{ ansible_default_ipv4.address }}:/root/wireguard-client-configs/* ./ + + 2. Install WireGuard client on your machine: + - Linux: sudo apt install wireguard + - macOS: brew install wireguard-tools + - Windows: https://www.wireguard.com/install/ + + 3. Import admin VPN config and connect + + 4. Copy Ansible SSH key to VPN endpoints: + ssh-copy-id -i /root/.ssh/ansible_ed25519 root@VPN1-IP + ssh-copy-id -i /root/.ssh/ansible_ed25519 root@VPN2-IP + ssh-copy-id -i /root/.ssh/ansible_ed25519 root@VPN3-IP + + 5. Configure inventory: + cd /root/resist-vpn-infra + nano inventory/hosts.yml + nano inventory/group_vars/vpn_servers.yml + + 6. Deploy VPN endpoints: + ansible-playbook -i inventory/hosts.yml playbooks/site.yml + + Important Files: + - Admin VPN configs: /root/wireguard-client-configs/ + - Ansible SSH key: /root/.ssh/ansible_ed25519 + - Ansible public key: /root/valleyforge_ansible_pubkey.txt + - Repository: /root/resist-vpn-infra + - Firewall config: /root/firewall-config.txt + - Sudo log: /var/log/sudo.log + - Audit logs: /var/log/audit/audit.log + mode: '0600'