From 7cefa0f387bc7ee70147931e9d81acb2146ca970 Mon Sep 17 00:00:00 2001 From: Nik Afiq Date: Wed, 18 Mar 2026 22:27:30 +0900 Subject: [PATCH] Add Wireguard for split tunnel VPN via Ansible --- ansible/playbooks/wireguard.yaml | 9 ++ ansible/roles/wireguard/handlers/main.yaml | 5 + ansible/roles/wireguard/tasks/main.yaml | 130 ++++++++++++++++++ ansible/roles/wireguard/templates/wg0.conf.j2 | 11 ++ 4 files changed, 155 insertions(+) create mode 100644 ansible/playbooks/wireguard.yaml create mode 100644 ansible/roles/wireguard/handlers/main.yaml create mode 100644 ansible/roles/wireguard/tasks/main.yaml create mode 100644 ansible/roles/wireguard/templates/wg0.conf.j2 diff --git a/ansible/playbooks/wireguard.yaml b/ansible/playbooks/wireguard.yaml new file mode 100644 index 0000000..703173b --- /dev/null +++ b/ansible/playbooks/wireguard.yaml @@ -0,0 +1,9 @@ +--- +- name: WireGuard VPN server + hosts: minisforum + become: true + vars: + wireguard_endpoint: home.nik4nao.com + wireguard_lan_interface: enp1s0 + roles: + - wireguard \ No newline at end of file diff --git a/ansible/roles/wireguard/handlers/main.yaml b/ansible/roles/wireguard/handlers/main.yaml new file mode 100644 index 0000000..1c56f4a --- /dev/null +++ b/ansible/roles/wireguard/handlers/main.yaml @@ -0,0 +1,5 @@ +--- +- name: Restart wg0 + systemd: + name: wg-quick@wg0 + state: restarted \ No newline at end of file diff --git a/ansible/roles/wireguard/tasks/main.yaml b/ansible/roles/wireguard/tasks/main.yaml new file mode 100644 index 0000000..f9d05dd --- /dev/null +++ b/ansible/roles/wireguard/tasks/main.yaml @@ -0,0 +1,130 @@ +--- +- name: Install WireGuard and tools + apt: + name: + - wireguard + - wireguard-tools + - qrencode + state: present + update_cache: true + +- name: Allow WireGuard port through UFW + ufw: + rule: allow + port: "51820" + proto: udp + +- name: Enable IP forwarding + sysctl: + name: net.ipv4.ip_forward + value: "1" + sysctl_set: true + state: present + reload: true + +- name: Create WireGuard config directory + file: + path: /etc/wireguard + state: directory + mode: "0700" + owner: root + group: root + +# --- Server keypair --- +- name: Check if server private key exists + stat: + path: /etc/wireguard/server.key + register: server_key_stat + +- name: Generate server private key + shell: wg genkey > /etc/wireguard/server.key + when: not server_key_stat.stat.exists + +- name: Set permissions on server private key + file: + path: /etc/wireguard/server.key + mode: "0600" + owner: root + group: root + +- name: Read server private key + slurp: + src: /etc/wireguard/server.key + register: server_private_key + +- name: Derive server public key + shell: wg pubkey < /etc/wireguard/server.key + register: server_public_key + changed_when: false + +# --- Phone keypair --- +- name: Check if phone private key exists + stat: + path: /etc/wireguard/phone.key + register: phone_key_stat + +- name: Generate phone private key + shell: wg genkey > /etc/wireguard/phone.key + when: not phone_key_stat.stat.exists + +- name: Set permissions on phone private key + file: + path: /etc/wireguard/phone.key + mode: "0600" + owner: root + group: root + +- name: Read phone private key + slurp: + src: /etc/wireguard/phone.key + register: phone_private_key + +- name: Derive phone public key + shell: wg pubkey < /etc/wireguard/phone.key + register: phone_public_key + changed_when: false + +# --- Server config --- +- name: Write wg0.conf + template: + src: wg0.conf.j2 + dest: /etc/wireguard/wg0.conf + mode: "0600" + owner: root + group: root + notify: Restart wg0 + +# --- Service --- +- name: Enable and start wg-quick@wg0 + systemd: + name: wg-quick@wg0 + enabled: true + state: started + +# --- Phone client config + QR --- +- name: Write phone client config + copy: + dest: /etc/wireguard/phone-client.conf + mode: "0600" + owner: root + group: root + content: | + [Interface] + PrivateKey = {{ phone_private_key.content | b64decode | trim }} + Address = 10.10.0.2/32 + DNS = 192.168.7.77 + + [Peer] + PublicKey = {{ server_public_key.stdout }} + Endpoint = {{ wireguard_endpoint }}:51820 + AllowedIPs = 192.168.7.0/24, 10.10.0.0/24 + PersistentKeepalive = 25 + +- name: Generate QR code for phone + shell: qrencode -t ansiutf8 < /etc/wireguard/phone-client.conf + register: phone_qr + changed_when: false + +- name: Display phone QR code + debug: + msg: "{{ phone_qr.stdout_lines }}" \ No newline at end of file diff --git a/ansible/roles/wireguard/templates/wg0.conf.j2 b/ansible/roles/wireguard/templates/wg0.conf.j2 new file mode 100644 index 0000000..dd05a0e --- /dev/null +++ b/ansible/roles/wireguard/templates/wg0.conf.j2 @@ -0,0 +1,11 @@ +[Interface] +Address = 10.10.0.1/24 +ListenPort = 51820 +PrivateKey = {{ server_private_key.content | b64decode | trim }} +PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -A FORWARD -o wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -s 10.10.0.0/24 -o {{ wireguard_lan_interface }} -j MASQUERADE +PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -D FORWARD -o wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -s 10.10.0.0/24 -o {{ wireguard_lan_interface }} -j MASQUERADE + +[Peer] +# Phone +PublicKey = {{ phone_public_key.stdout }} +AllowedIPs = 10.10.0.2/32 \ No newline at end of file