- tags: - wireguard become: yes when: wireguard__state == 'present' vars: wg_net: "{{ hostvars[ansible_hostname][wireguard__name] }}" wg_host: "{{ wg_net.hosts[ansible_hostname] }}" all_peers: "{{ wg_host.peers is defined and wg_host.peers == 'all' }}" netdev_path: "/etc/systemd/network/60-{{ wg_net.if }}.netdev" network_path: "/etc/systemd/network/61-{{ wg_net.if }}.network" block: - name: Install packages tags: packages apt: name: "{{ items }}" install_recommends: no vars: items: - wireguard - "{{ 'linux-headers-amd64' if ansible_architecture == 'x86_64' else 'linux-headers-686-pae' }}" - name: systemctl enable systemd-networkd systemd: name: systemd-networkd enabled: yes state: started - name: mkdir /etc/wireguard file: path: /etc/wireguard state: directory - name: "wg genkey /etc/wireguard/private-{{ wg_net.if }}.key" tags: wireguard-config shell: wg genkey | tee /etc/wireguard/private-{{ wg_net.if }}.key | wg pubkey > /etc/wireguard/public-{{ wg_net.if }}.key args: creates: /etc/wireguard/private-{{ wg_net.if }}.key register: wg_private_key_gen - when: wg_private_key_gen.changed tags: wireguard-config fetch: src: "/etc/wireguard/public-{{ wg_net.if }}.key" dest: "files" - tags: wireguard-config slurp: src: "/etc/wireguard/private-{{ wg_net.if }}.key" register: wg_private_key - name: "Make {{ netdev_path }}" notify: systemctl restart systemd-networkd tags: wireguard-config copy: dest: "{{ netdev_path }}" content: | [NetDev] Name={{ wg_net.if }} Kind=wireguard Description=Wireguard VPN [WireGuard] PrivateKey={{ wg_private_key['content'] | b64decode }} {% if wg_host.listen_port is defined %} ListenPort={{ wg_host.listen_port }} {% endif %} {% for hostname in wg_net.hosts|sort %} {% set host = wg_net.hosts[hostname] %} {% set present = not (host.state is defined) or host.state == 'present' %} {% if present and (all_peers or host.endpoint is defined) %} # {{ hostname }} [WireGuardPeer] PublicKey={{ host.public_key if host.public_key is defined else lookup('file', hostname + '/etc/wireguard/public-{{ wg_net.if }}.key') }} {% if host.endpoint is defined %} AllowedIPs={{ "0.0.0.0/0" }} {% elif host.ipv4 is defined %} AllowedIPs={{ host.ipv4 }} {% endif %} {% if host.endpoint is defined %} AllowedIPs={{ "::/0" }} {% elif host.ipv6 is defined %} AllowedIPs={{ host.ipv6 }} {% endif %} {% if host.endpoint is defined %} Endpoint={{ host.endpoint }}:{{ host.listen_port }} {% endif %} PersistentKeepalive=60 {% endif %} {% endfor %} - name: "Make {{ network_path }}" tags: wireguard-config notify: systemctl restart systemd-networkd copy: dest: "{{ network_path }}" content: | [Match] Name={{ wg_net.if }} [Network] {% if wg_net.hosts[ansible_hostname].ipv4 is defined %} Address={{ wg_net.hosts[ansible_hostname].ipv4 }}/{{ wg_net.ipv4_prefix }} {% endif %} {% if wg_net.hosts[ansible_hostname].ipv6 is defined %} Address={{ wg_net.hosts[ansible_hostname].ipv6 }}/{{ wg_net.ipv6_prefix }} {% endif %} {% if wg_net.shared_routes is defined %} {% for route in wg_net.shared_routes %} [Route] Gateway={{ route.gateway }} Destination={{ route.net }}/{{ route.prefix }} {% endfor %} {% endif %} - name: UFW allow port when: wg_host.listen_port is defined tags: wireguard-config ufw: rule: allow port: "{{ wg_host.listen_port }}" proto: udp - tags: - wireguard become: yes when: wireguard__state == 'absent' vars: wg_net: "{{ hostvars[ansible_hostname][wireguard__name] }}" netdev_path: "/etc/systemd/network/60-{{ wg_net.if }}.netdev" network_path: "/etc/systemd/network/61-{{ wg_net.if }}.network" block: - name: Remove old files file: path: "{{ item }}" state: absent notify: systemctl restart systemd-networkd with_items: - /etc/wireguard/private-{{ wg_net.if }}.key - /etc/wireguard/public-{{ wg_net.if }}.key - "{{ netdev_path }}" - "{{ network_path }}" - name: Checking for interface shell: "ip -j link show" changed_when: False register: ip_link - name: Removing interface shell: "ip -j link delete {{ wg_net.if }}" when: links[wg_net.if] is defined vars: links: "{{ ip_link.stdout | from_json | items2dict(key_name='ifname', value_name='ifname') }}" - name: generate dns records tags: # - wireguard # - wireguard-dns-records - never local_action: module: copy content: | wireguard_dns_records_{{ wg_net.if }}: {% for c in wireguard__clients|sort %} {% set client = wireguard__clients[c] %} - type: A name: {{ c }} value: {{ client.ipv4 }} state: {{ client.state }} - type: AAAA name: {{ c }} value: {{ client.ipv6 }} state: {{ client.state }} {% endfor %} dest: "files/wireguard-dns-records-{{ wg_net.if }}.yml"