From f93dd15e52140d8e2fb5462ed009a954f1885572 Mon Sep 17 00:00:00 2001 From: Ahmed Abdelhalim Date: Wed, 20 Aug 2025 23:37:21 +0200 Subject: Add wireguard role and fix testing The testing was failing because the use of the example files with the same domain names, resulted in the files and the molecule variable were being merged and therefore running tasks that would fail on test (example, setting a fake VPN connection that wouldn't start). --- .github/workflows/ci.yml | 7 ++-- group_vars/all.yml | Bin 443 -> 1661 bytes group_vars/all.yml.example | 13 ++++++++ host_vars/rpi5.local.yml | Bin 212 -> 264 bytes molecule/default/converge.yml | 31 ++++++++++++------ roles/network/templates/resolved.conf.j2 | 2 ++ roles/wireguard/defaults/main.yml | 3 ++ roles/wireguard/meta/argument_specs.yml | 18 +++++++++++ roles/wireguard/meta/main.yml | 19 +++++++++++ roles/wireguard/tasks/main.yml | 54 +++++++++++++++++++++++++++++++ roles/wireguard/vars/archlinux.yml | 4 +++ roles/wireguard/vars/debian.yml | 4 +++ site.yml | 2 ++ 13 files changed, 143 insertions(+), 14 deletions(-) create mode 100644 roles/wireguard/defaults/main.yml create mode 100644 roles/wireguard/meta/argument_specs.yml create mode 100644 roles/wireguard/meta/main.yml create mode 100644 roles/wireguard/tasks/main.yml create mode 100644 roles/wireguard/vars/archlinux.yml create mode 100644 roles/wireguard/vars/debian.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 773a8f76..5dd1c651 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -43,11 +43,10 @@ jobs: python-version: "3.x" - name: Install dependencies run: pip3 install ansible molecule molecule-plugins[docker] - - name: Copy example files + - name: Remove encrypted var files run: | - # Copy host_vars (from the .example files) - for f in group_vars/*.example; do cp "$f" "$(echo "$f" | sed s/\.example//)"; done - for f in host_vars/*.example; do cp "$f" "$(echo "$f" | sed s/\.example//)"; done + rm host_vars/*.yml + rm group_vars/*.yml - name: Run env: PY_COLORS: 1 diff --git a/group_vars/all.yml b/group_vars/all.yml index 88aec57b..f72ba941 100644 Binary files a/group_vars/all.yml and b/group_vars/all.yml differ diff --git a/group_vars/all.yml.example b/group_vars/all.yml.example index f7802c0d..8e556313 100644 --- a/group_vars/all.yml.example +++ b/group_vars/all.yml.example @@ -33,3 +33,16 @@ python_global_version: "system" python_versions: - "3.11" - "3.13" + +wireguard_autostart_connection: "protonvpn-us-1" +wireguard_connections: + protonvpn-us-1: | + [Interface] + PrivateKey = your_private_key_here + Address = 10.2.0.2/32 + DNS = 10.2.0.1 + + [Peer] + PublicKey = server_public_key + AllowedIPs = 0.0.0.0/0 + Endpoint = us-1.protonvpn.com:51820 diff --git a/host_vars/rpi5.local.yml b/host_vars/rpi5.local.yml index d8c28a2b..b285358d 100644 Binary files a/host_vars/rpi5.local.yml and b/host_vars/rpi5.local.yml differ diff --git a/molecule/default/converge.yml b/molecule/default/converge.yml index b83ecfe6..300360d4 100644 --- a/molecule/default/converge.yml +++ b/molecule/default/converge.yml @@ -15,19 +15,30 @@ python_global_version: "3.13" python_versions: - "3.13" - - "3.12" pihole_interface: "eth0" pihole_domain: "pi.hole" + wireguard_connections: + protonvpn-example: | + [Interface] + PrivateKey = your_private_key_here + Address = 10.2.0.2/32 + DNS = 10.2.0.1 + + [Peer] + PublicKey = server_public_key + AllowedIPs = 0.0.0.0/0 + Endpoint = example.protonvpn.com:51820 roles: - - role: network - - role: user - - role: ssh - - role: password_policy - - role: locales - - role: timezone - - role: homebrew - - role: python - - role: pihole + - role: "network" + - role: "user" + - role: "ssh" + - role: "password_policy" + - role: "locales" + - role: "timezone" + - role: "homebrew" + - role: "python" + - role: "wireguard" + - role: "pihole" when: - lookup('ansible.builtin.env', 'MOLECULE_DISTRO') == 'ubuntu' or lookup('ansible.builtin.env', 'MOLECULE_DISTRO') == 'raspberrypi' diff --git a/roles/network/templates/resolved.conf.j2 b/roles/network/templates/resolved.conf.j2 index c94e9c1a..c083a214 100644 --- a/roles/network/templates/resolved.conf.j2 +++ b/roles/network/templates/resolved.conf.j2 @@ -3,6 +3,8 @@ DNS=9.9.9.9 2620:fe::fe#quad9.net FallbackDNS=1.1.1.1 2606:4700:4700::1111#cloudflare-dns.com 8.8.8.8 2001:4860:4860::8888#dns.google DNSSEC=yes DNSOverTLS=yes +# use interface-specific DNS when available but fall back to global (required for VPN DNS to work) +Domains=~. # Enable multicast DNS for .local domain resolution (replaces avahi functionality) MulticastDNS=yes diff --git a/roles/wireguard/defaults/main.yml b/roles/wireguard/defaults/main.yml new file mode 100644 index 00000000..7b1d98b9 --- /dev/null +++ b/roles/wireguard/defaults/main.yml @@ -0,0 +1,3 @@ +--- +wireguard_connections: {} +wireguard_autostart_connection: "" diff --git a/roles/wireguard/meta/argument_specs.yml b/roles/wireguard/meta/argument_specs.yml new file mode 100644 index 00000000..68e0e821 --- /dev/null +++ b/roles/wireguard/meta/argument_specs.yml @@ -0,0 +1,18 @@ +--- +argument_specs: + main: + short_description: "Install and configure WireGuard VPN connections" + description: + - "Installs WireGuard package and tools" + - "Deploys WireGuard configuration files from dictionary" + - "Optionally auto-starts a specific connection on boot" + author: "a14m" + options: + wireguard_connections: + description: "Dictionary of WireGuard connection configurations" + type: "dict" + default: {} + wireguard_autostart_connection: + description: "Name of connection to automatically start on boot" + type: "str" + default: "" diff --git a/roles/wireguard/meta/main.yml b/roles/wireguard/meta/main.yml new file mode 100644 index 00000000..22da6ddd --- /dev/null +++ b/roles/wireguard/meta/main.yml @@ -0,0 +1,19 @@ +--- +dependencies: [] + +galaxy_info: + author: "a14m" + description: "Install and configure WireGuard VPN connections" + company: "kartoffeln.work GmbH." + license: "MIT" + min_ansible_version: "2.18" + platforms: + - name: "ArchLinux" + versions: + - "all" + - name: "Ubuntu" + versions: + - "noble" + - name: "Debian" + versions: + - "bookworm" diff --git a/roles/wireguard/tasks/main.yml b/roles/wireguard/tasks/main.yml new file mode 100644 index 00000000..45011ea1 --- /dev/null +++ b/roles/wireguard/tasks/main.yml @@ -0,0 +1,54 @@ +--- +- name: "Include OS-specific variables" + ansible.builtin.include_vars: "{{ ansible_os_family | lower }}.yml" + +- name: "Ensure wireguard is installed" + become: true + ansible.builtin.package: + name: "{{ wireguard_pkgs }}" + state: "present" + +- name: "Create wireguard configuration directory" + become: true + ansible.builtin.file: + path: "/etc/wireguard" + state: "directory" + owner: "root" + group: "root" + mode: "0700" + +- name: "Deploy WireGuard configurations" + become: true + ansible.builtin.copy: + content: "{{ wireguard_connections[item] }}" + dest: "/etc/wireguard/{{ item }}.conf" + owner: "root" + group: "root" + mode: "0600" + backup: true + with_items: "{{ wireguard_connections }}" + when: wireguard_connections | length > 0 + +- name: "Configure autostart connection" + become: true + block: + - name: "Ensure all wireguard connections are stopped" + ansible.builtin.systemd: + name: "wg-quick@{{ item }}" + enabled: false + state: "stopped" + with_items: "{{ wireguard_connections.keys() | list }}" + + - name: "Ensure all wireguard interfaces are down" + ansible.builtin.command: + cmd: "wg-quick down {{ item }}" + with_items: "{{ wireguard_connections.keys() | list }}" + changed_when: true + failed_when: false + + - name: "Enable and start wg-quick service for connection {{ wireguard_autostart_connection }}" + ansible.builtin.systemd: + name: "wg-quick@{{ wireguard_autostart_connection }}" + enabled: true + state: "started" + when: wireguard_autostart_connection != "" diff --git a/roles/wireguard/vars/archlinux.yml b/roles/wireguard/vars/archlinux.yml new file mode 100644 index 00000000..9afa94e4 --- /dev/null +++ b/roles/wireguard/vars/archlinux.yml @@ -0,0 +1,4 @@ +--- +wireguard_pkgs: + - "wireguard-tools" + - "systemd-resolvconf" diff --git a/roles/wireguard/vars/debian.yml b/roles/wireguard/vars/debian.yml new file mode 100644 index 00000000..f9c5f5f7 --- /dev/null +++ b/roles/wireguard/vars/debian.yml @@ -0,0 +1,4 @@ +--- +wireguard_pkgs: + - "wireguard" + - "resolvconf" diff --git a/site.yml b/site.yml index 3321e889..2a11b581 100644 --- a/site.yml +++ b/site.yml @@ -17,6 +17,7 @@ become: true ansible.builtin.package: update_cache: true + failed_when: false - name: "Dev machines configure" gather_facts: true @@ -26,6 +27,7 @@ roles: - role: "locales" - role: "timezone" + - role: "wireguard" - role: "homebrew" - role: "python" -- cgit v1.2.3