Files
michaelschiemer/deployment/ansible/playbooks/setup-wireguard.yml
Michael Schiemer 16d586ecdf chore: Update deployment configuration and documentation
- Update Gitea configuration (remove DEFAULT_ACTIONS_URL)
- Fix deployment documentation
- Update Ansible playbooks
- Clean up deprecated files
- Add new deployment scripts and templates
2025-10-31 21:11:11 +01:00

287 lines
8.9 KiB
YAML
Executable File

---
- name: Setup WireGuard VPN Server
hosts: production
become: yes
gather_facts: yes
vars:
# WireGuard variables are defined in group_vars/production.yml
# Can be overridden via -e flag if needed
wireguard_port: "{{ wireguard_port | default(wireguard_port_default) }}"
wireguard_network: "{{ wireguard_network | default(wireguard_network_default) }}"
wireguard_server_ip: "{{ wireguard_server_ip | default(wireguard_server_ip_default) }}"
pre_tasks:
- name: Optionally load wireguard secrets from vault
include_vars:
file: "{{ playbook_dir }}/../secrets/production.vault.yml"
no_log: yes
ignore_errors: yes
delegate_to: localhost
become: no
tasks:
- name: Check if WireGuard is already installed
command: which wg
register: wireguard_installed
changed_when: false
failed_when: false
- name: Update package cache
apt:
update_cache: yes
cache_valid_time: 3600
when: not wireguard_installed.rc == 0
- name: Install WireGuard
apt:
name:
- wireguard
- wireguard-tools
- qrencode
state: present
when: not wireguard_installed.rc == 0
notify: restart wireguard
- name: Ensure WireGuard config directory exists
file:
path: "{{ wireguard_config_path }}"
state: directory
mode: '0700'
owner: root
group: root
- name: Ensure WireGuard client configs directory exists
file:
path: "{{ wireguard_client_configs_path }}"
state: directory
mode: '0700'
owner: root
group: root
- name: Check if WireGuard server keys exist
stat:
path: "{{ wireguard_private_key_file }}"
register: server_private_key_exists
- name: Generate WireGuard server private key
command: "wg genkey"
register: server_private_key
changed_when: true
when: not server_private_key_exists.stat.exists
no_log: yes
- name: Save WireGuard server private key
copy:
content: "{{ server_private_key.stdout }}"
dest: "{{ wireguard_private_key_file }}"
mode: '0600'
owner: root
group: root
when: not server_private_key_exists.stat.exists
no_log: yes
- name: Read WireGuard server private key
slurp:
src: "{{ wireguard_private_key_file }}"
register: server_private_key_content
when: server_private_key_exists.stat.exists
- name: Generate WireGuard server public key
command: "wg pubkey"
args:
stdin: "{{ server_private_key.stdout if not server_private_key_exists.stat.exists else server_private_key_content.content | b64decode | trim }}"
register: server_public_key
changed_when: false
when: not server_private_key_exists.stat.exists
no_log: yes
- name: Get existing server public key
shell: "cat {{ wireguard_private_key_file }} | wg pubkey"
register: existing_server_public_key
changed_when: false
when: server_private_key_exists.stat.exists
no_log: yes
failed_when: false
- name: Set server public key fact
set_fact:
server_public_key_value: "{{ server_public_key.stdout if not server_private_key_exists.stat.exists else existing_server_public_key.stdout }}"
- name: Save WireGuard server public key
copy:
content: "{{ server_public_key_value }}"
dest: "{{ wireguard_public_key_file }}"
mode: '0644'
owner: root
group: root
- name: Enable IP forwarding
sysctl:
name: net.ipv4.ip_forward
value: '1'
state: present
sysctl_set: yes
reload: yes
when: wireguard_enable_ip_forwarding
- name: Make IP forwarding persistent
lineinfile:
path: /etc/sysctl.conf
regexp: '^net\.ipv4\.ip_forward'
line: 'net.ipv4.ip_forward=1'
state: present
when: wireguard_enable_ip_forwarding
- name: Get server external IP address
uri:
url: https://api.ipify.org
return_content: yes
register: server_external_ip
changed_when: false
failed_when: false
- name: Set server external IP from inventory if API fails
set_fact:
server_external_ip_content: "{{ ansible_host | default(server_external_ip.content | default('')) }}"
when: server_external_ip.content is defined
- name: Get server external IP from ansible_host
set_fact:
server_external_ip_content: "{{ ansible_host }}"
when: server_external_ip.content is not defined
- name: Read server private key for config
slurp:
src: "{{ wireguard_private_key_file }}"
register: server_private_key_file_content
when: server_private_key_exists.stat.exists
- name: Set server private key for template (new key)
set_fact:
server_private_key_for_config: "{{ server_private_key.stdout }}"
when: not server_private_key_exists.stat.exists
- name: Set server private key for template (existing key)
set_fact:
server_private_key_for_config: "{{ server_private_key_file_content.content | b64decode | trim }}"
when: server_private_key_exists.stat.exists
- name: Get network interface name
shell: "ip route | grep default | awk '{print $5}' | head -1"
register: default_interface
changed_when: false
failed_when: false
- name: Set default interface
set_fact:
wireguard_interface_name: "{{ default_interface.stdout | default('eth0') }}"
- name: Check if WireGuard config exists
stat:
path: "{{ wireguard_config_file }}"
register: wireguard_config_exists
- name: Create WireGuard server configuration
template:
src: "{{ playbook_dir }}/../templates/wireguard-server.conf.j2"
dest: "{{ wireguard_config_file }}"
mode: '0600'
owner: root
group: root
notify: restart wireguard
- name: Check if WireGuard service is enabled
systemd:
name: "wg-quick@{{ wireguard_interface }}"
register: wireguard_service_status
failed_when: false
changed_when: false
- name: Enable WireGuard service
systemd:
name: "wg-quick@{{ wireguard_interface }}"
enabled: yes
daemon_reload: yes
when: not wireguard_service_status.status.ActiveState is defined or wireguard_service_status.status.ActiveState != 'active'
- name: Start WireGuard service
systemd:
name: "wg-quick@{{ wireguard_interface }}"
state: started
notify: restart wireguard
- name: Check if UFW firewall is installed
command: which ufw
register: ufw_installed
changed_when: false
failed_when: false
- name: Verify SSH access is allowed in UFW
command: "ufw status | grep -q '22/tcp' || echo 'SSH not found'"
register: ssh_ufw_check
changed_when: false
failed_when: false
when: ufw_installed.rc == 0
- name: Warn if SSH is not explicitly allowed
debug:
msg: |
?? WARNING: SSH (port 22) might not be explicitly allowed in UFW!
Please ensure SSH access is configured before proceeding.
Run: sudo ufw allow 22/tcp
when: ufw_installed.rc == 0 and 'SSH not found' in ssh_ufw_check.stdout
- name: Allow WireGuard port in UFW firewall
ufw:
rule: allow
port: "{{ wireguard_port }}"
proto: udp
comment: "WireGuard VPN"
when: ufw_installed.rc == 0
- name: Allow WireGuard port in UFW firewall (alternative)
shell: "ufw allow {{ wireguard_port }}/udp comment 'WireGuard VPN'"
when: ufw_installed.rc == 0
failed_when: false
changed_when: false
- name: Check WireGuard status
command: "wg show {{ wireguard_interface }}"
register: wireguard_status
changed_when: false
failed_when: false
- name: Display WireGuard status
debug:
msg: |
WireGuard Status:
{{ wireguard_status.stdout if wireguard_status.rc == 0 else 'WireGuard interface not active' }}
- name: Display server public key
debug:
msg: |
========================================
WireGuard Server Setup Complete!
========================================
Server Public Key:
{{ server_public_key_value }}
Server IP: {{ wireguard_server_ip }}
Server Endpoint: {{ server_external_ip_content }}:{{ wireguard_port }}
Network: {{ wireguard_network }}
To add a client, run:
ansible-playbook -i inventory/production.yml playbooks/add-wireguard-client.yml -e "client_name=myclient"
Client configs are stored in:
{{ wireguard_client_configs_path }}/
========================================
handlers:
- name: restart wireguard
systemd:
name: "wg-quick@{{ wireguard_interface }}"
state: restarted