Files
michaelschiemer/deployment/ansible/playbooks/add-wireguard-client.yml

169 lines
5.8 KiB
YAML
Executable File

---
- name: Add WireGuard Client
hosts: production
become: yes
gather_facts: yes
vars:
wireguard_interface: "wg0"
wireguard_config_path: "/etc/wireguard"
wireguard_config_file: "{{ wireguard_config_path }}/{{ wireguard_interface }}.conf"
wireguard_client_configs_path: "/etc/wireguard/clients"
pre_tasks:
- name: Set WireGuard network
set_fact:
wireguard_network: "{{ wireguard_network | default('10.8.0.0/24') }}"
- name: Set WireGuard other variables with defaults
set_fact:
wireguard_port: "{{ wireguard_port | default(51820) }}"
client_ip: "{{ client_ip | default('') }}"
# IMPORTANT: Default to VPN network only (not 0.0.0.0/0)
# This ensures SSH access via normal IP remains available
allowed_ips: "{{ allowed_ips | default(wireguard_network) }}"
tasks:
- name: Validate client name
fail:
msg: "client_name is required. Usage: ansible-playbook ... -e 'client_name=myclient'"
when: client_name is not defined or client_name == ""
- 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
set_fact:
server_external_ip_content: "{{ ansible_host | default(server_external_ip.content | default('')) }}"
- name: Check if WireGuard config exists
stat:
path: "{{ wireguard_config_file }}"
register: wireguard_config_exists
- name: Fail if WireGuard not configured
fail:
msg: "WireGuard server not configured. Please run setup-wireguard.yml first."
when: not wireguard_config_exists.stat.exists
- name: Read WireGuard server config
slurp:
src: "{{ wireguard_config_file }}"
register: wireguard_server_config_read
- name: Extract server IP from config
set_fact:
server_vpn_ip: "{{ (wireguard_server_config_read.content | b64decode | regex_search('Address = ([0-9.]+)', '\\1')) | first | default('10.8.0.1') }}"
- name: Count existing clients in config
set_fact:
existing_clients_count: "{{ (wireguard_server_config_read.content | b64decode | regex_findall('\\[Peer\\]') | length) }}"
when: client_ip == ""
- name: Calculate client IP if not provided
set_fact:
client_ip: "{{ server_vpn_ip | regex_replace('^(\\d+\\.\\d+\\.\\d+\\.)\\d+$', '\\1') }}{{ (server_vpn_ip | regex_replace('^(\\d+\\.\\d+\\.\\d+\\.)(\\d+)', '\\2') | int) + (existing_clients_count | default(1)) | int }}"
when: client_ip == ""
- name: Generate client private key
command: "wg genkey"
register: client_private_key
changed_when: true
no_log: yes
- name: Generate client public key
command: "wg pubkey"
args:
stdin: "{{ client_private_key.stdout }}"
register: client_public_key
changed_when: false
no_log: yes
- name: Check if client already exists in config
shell: "grep -q '{{ client_name }}' {{ wireguard_config_file }} || echo 'not found'"
register: client_exists_check
changed_when: false
failed_when: false
- name: Add client to WireGuard server config
blockinfile:
path: "{{ wireguard_config_file }}"
block: |
# Client: {{ client_name }}
[Peer]
PublicKey = {{ client_public_key.stdout }}
AllowedIPs = {{ client_ip }}/32
marker: "# {mark} ANSIBLE MANAGED BLOCK - Client: {{ client_name }}"
when: "'not found' in client_exists_check.stdout"
- name: Ensure client configs directory exists
file:
path: "{{ wireguard_client_configs_path }}"
state: directory
mode: '0700'
owner: root
group: root
- name: Get server public key
shell: "cat {{ wireguard_config_path }}/{{ wireguard_interface }}_private.key | wg pubkey"
register: server_public_key_cmd
changed_when: false
no_log: yes
failed_when: false
- name: Create client configuration file
template:
src: "{{ playbook_dir }}/../templates/wireguard-client.conf.j2"
dest: "{{ wireguard_client_configs_path }}/{{ client_name }}.conf"
mode: '0600'
owner: root
group: root
- name: Read WireGuard server config to find server IP
slurp:
src: "{{ wireguard_config_file }}"
register: wireguard_server_config_read
- name: Restart WireGuard service
systemd:
name: "wg-quick@{{ wireguard_interface }}"
state: restarted
when: "'not found' in client_exists_check.stdout"
- name: Display client configuration
debug:
msg: |
========================================
WireGuard Client Added: {{ client_name }}
========================================
Client Configuration File:
{{ wireguard_client_configs_path }}/{{ client_name }}.conf
Client IP: {{ client_ip }}
Server Endpoint: {{ server_external_ip_content }}:{{ wireguard_port }}
To use this configuration:
1. Copy the config file to your client machine
2. Install WireGuard client
3. Run: sudo wg-quick up {{ client_name }}
Or scan the QR code (if qrencode installed):
qrencode -t ansiutf8 < {{ wireguard_client_configs_path }}/{{ client_name }}.conf
========================================
- name: Generate QR code for client config
command: "qrencode -t ansiutf8 -r {{ wireguard_client_configs_path }}/{{ client_name }}.conf"
register: qr_code
changed_when: false
failed_when: false
- name: Display QR code
debug:
msg: "{{ qr_code.stdout }}"
when: qr_code.rc == 0