From 9158fc8ff671707c686fcd40e13b06310112eada Mon Sep 17 00:00:00 2001 From: Trygve Laugstøl Date: Fri, 21 Aug 2020 13:44:50 +0200 Subject: wireguard2 --- ansible/ansible.cfg | 2 +- ansible/inventory | 1 + ansible/plays/files/wireguard/vs0/birgitte.pub | 1 + ansible/plays/files/wireguard/vs0/vimscore-1.pub | 1 + ansible/plays/files/wireguard/vs0/vimscore-2.pub | 1 + ansible/plays/files/wireguard/vs0/vimscore-3.pub | 1 + ansible/plays/wireguard-vs0.yml | 74 ++++++++++++++++++ ansible/roles/wireguard2/README.md | 21 +++++ ansible/roles/wireguard2/defaults/main.yml | 14 ++++ ansible/roles/wireguard2/handlers/main.yml | 5 ++ ansible/roles/wireguard2/tasks/absent.yml | 18 +++++ ansible/roles/wireguard2/tasks/install.yml | 6 ++ ansible/roles/wireguard2/tasks/main.yml | 13 ++++ ansible/roles/wireguard2/tasks/present.yml | 99 ++++++++++++++++++++++++ 14 files changed, 256 insertions(+), 1 deletion(-) create mode 100644 ansible/plays/files/wireguard/vs0/birgitte.pub create mode 100644 ansible/plays/files/wireguard/vs0/vimscore-1.pub create mode 100644 ansible/plays/files/wireguard/vs0/vimscore-2.pub create mode 100644 ansible/plays/files/wireguard/vs0/vimscore-3.pub create mode 100644 ansible/plays/wireguard-vs0.yml create mode 100644 ansible/roles/wireguard2/README.md create mode 100644 ansible/roles/wireguard2/defaults/main.yml create mode 100644 ansible/roles/wireguard2/handlers/main.yml create mode 100644 ansible/roles/wireguard2/tasks/absent.yml create mode 100644 ansible/roles/wireguard2/tasks/install.yml create mode 100644 ansible/roles/wireguard2/tasks/main.yml create mode 100644 ansible/roles/wireguard2/tasks/present.yml diff --git a/ansible/ansible.cfg b/ansible/ansible.cfg index 5f7f40b..b98026d 100644 --- a/ansible/ansible.cfg +++ b/ansible/ansible.cfg @@ -8,5 +8,5 @@ vault_password_file = vault-password roles_path = roles:thirdparty retry_files_enabled = False -strategy_plugins = env/lib/python3.7/site-packages/ansible_mitogen/plugins/strategy +strategy_plugins = env/lib/python3.8/site-packages/ansible_mitogen/plugins/strategy strategy = mitogen_linear diff --git a/ansible/inventory b/ansible/inventory index 2e6d0cd..5c7c086 100644 --- a/ansible/inventory +++ b/ansible/inventory @@ -6,6 +6,7 @@ all: ansible_host: numquam.trygvis.io birgitte: ansible_host: birgitte.vpn.trygvis.io + ansible_python_interpreter: /usr/bin/python3 arius: ansible_host: arius.trygvis.io mw: diff --git a/ansible/plays/files/wireguard/vs0/birgitte.pub b/ansible/plays/files/wireguard/vs0/birgitte.pub new file mode 100644 index 0000000..fcc93c3 --- /dev/null +++ b/ansible/plays/files/wireguard/vs0/birgitte.pub @@ -0,0 +1 @@ +NBTz38oefUN5Thj7kwcL91fV7HL+xf6iju5/AgR2bC0= diff --git a/ansible/plays/files/wireguard/vs0/vimscore-1.pub b/ansible/plays/files/wireguard/vs0/vimscore-1.pub new file mode 100644 index 0000000..ed7da6a --- /dev/null +++ b/ansible/plays/files/wireguard/vs0/vimscore-1.pub @@ -0,0 +1 @@ +5upofMGG4o7GO1fMYIUye/QImQwEJBXIlAMaH8QzzBk= diff --git a/ansible/plays/files/wireguard/vs0/vimscore-2.pub b/ansible/plays/files/wireguard/vs0/vimscore-2.pub new file mode 100644 index 0000000..45d1586 --- /dev/null +++ b/ansible/plays/files/wireguard/vs0/vimscore-2.pub @@ -0,0 +1 @@ +rDEwWC433PMoQtyORPrXD4bHiuTobvbqjYYUtATiWgY= diff --git a/ansible/plays/files/wireguard/vs0/vimscore-3.pub b/ansible/plays/files/wireguard/vs0/vimscore-3.pub new file mode 100644 index 0000000..f1503a5 --- /dev/null +++ b/ansible/plays/files/wireguard/vs0/vimscore-3.pub @@ -0,0 +1 @@ +gnbNb32q7t9oFU801ASfx7hi3IzbPYP/b/jpNYmiuHg= diff --git a/ansible/plays/wireguard-vs0.yml b/ansible/plays/wireguard-vs0.yml new file mode 100644 index 0000000..04eee72 --- /dev/null +++ b/ansible/plays/wireguard-vs0.yml @@ -0,0 +1,74 @@ +- hosts: + - akili + - birgitte + roles: + - role: wireguard2 + wireguard_if: vs0 + wireguard_listen_port: 45364 + wireguard_address4: "{{ networks[ansible_hostname].address }}" + + networks: + vimscore-1: + address: 192.168.137.1/24 + network: 10.137.1.0 + prefix: 24 + vimscore-2: + address: 192.168.137.2/24 + network: 10.137.2.0 + prefix: 24 + vimscore-3: + address: 192.168.137.3/24 + network: 10.137.3.0 + prefix: 24 + akili: + address: 192.168.137.4/24 + network: 10.137.4.0 + prefix: 24 + birgitte: + address: 192.168.137.5/24 + network: 10.137.5.0 + prefix: 24 + + wireguard_routers: + - gateway: "{{ networks['vimscore-1'].address }}" + network: "{{ networks['vimscore-1'].network }}/{{ networks['vimscore-1'].prefix }}" + state: "{{ 'absent' if ansible_hostname == 'vimscore-1' else 'present' }}" + - gateway: "{{ networks['vimscore-2'].address }}" + network: "{{ networks['vimscore-2'].network }}/{{ networks['vimscore-2'].prefix }}" + state: "{{ 'absent' if ansible_hostname == 'vimscore-2' else 'present' }}" + - gateway: "{{ networks['vimscore-3'].address }}" + network: "{{ networks['vimscore-3'].network }}/{{ networks['vimscore-3'].prefix }}" + state: "{{ 'absent' if ansible_hostname == 'vimscore-3' else 'present' }}" + - gateway: "{{ networks['akili'].address }}" + network: "{{ networks['akili'].network }}/{{ networks['akili'].prefix }}" + state: "{{ 'absent' if ansible_hostname == 'akili' else 'present' }}" + - gateway: "{{ networks['birgitte'].address }}" + network: "{{ networks['birgitte'].network }}/{{ networks['birgitte'].prefix }}" + state: "{{ 'absent' if ansible_hostname == 'birgitte' else 'present' }}" + + wireguard_peers: + vimscore-1: + endpoint: vimscore-1.vimscore.com + allowed_ips: + - "{{ networks['vimscore-1'].address | ipaddr('address') }}/32" + - "{{ networks['vimscore-1'].network }}/{{ networks['vimscore-1'].prefix }}" + vimscore-2: + endpoint: vimscore-2.vimscore.com + allowed_ips: + - "{{ networks['vimscore-2'].address | ipaddr('address') }}/32" + - "{{ networks['vimscore-2'].network }}/{{ networks['vimscore-2'].prefix }}" + vimscore-3: + endpoint: vimscore-3.vimscore.com + allowed_ips: + - "{{ networks['vimscore-3'].address | ipaddr('address') }}/32" + - "{{ networks['vimscore-3'].network }}/{{ networks['vimscore-3'].prefix }}" + akili: + public_key: UZc6XKf9ULUbBc4CI01DdCdyuj+lHvc1NQRhGJH/TE4= + allowed_ips: + - "{{ networks['akili'].address | ipaddr('address') }}/32" + - "{{ networks['akili'].network }}/{{ networks['akili'].prefix }}" + birgitte: + public_key: NBTz38oefUN5Thj7kwcL91fV7HL+xf6iju5/AgR2bC0= + allowed_ips: + - "{{ networks['birgitte'].address | ipaddr('address') }}/32" + - "{{ networks['birgitte'].network }}/{{ networks['birgitte'].prefix }}" diff --git a/ansible/roles/wireguard2/README.md b/ansible/roles/wireguard2/README.md new file mode 100644 index 0000000..d154546 --- /dev/null +++ b/ansible/roles/wireguard2/README.md @@ -0,0 +1,21 @@ +# Iptables configuration + +This is required: + + iptables -P FORWARD ACCEPT + +It can possibly be modified to not accept by default, and only allow +to/from our networks but I don't know how to do that. + +# Useful commands + +Cleaning everything and restarting. + + ip link del dev wg0 + systemctl restart systemd-networkd + +# References + + * https://www.eisfunke.com/article/docker-wireguard-systemd.html - Notice that this is not using the "alternate routing table" technique. + * https://nickb.dev/blog/routing-select-docker-containers-through-wireguard-vpn + * https://docs.docker.com/network/bridge/#enable-forwarding-from-docker-containers-to-the-outside-world diff --git a/ansible/roles/wireguard2/defaults/main.yml b/ansible/roles/wireguard2/defaults/main.yml new file mode 100644 index 0000000..43bc7c6 --- /dev/null +++ b/ansible/roles/wireguard2/defaults/main.yml @@ -0,0 +1,14 @@ +wireguard_state: present +wireguard_if: wg0 +public_keys_path: wireguard/{{ wireguard_if }} +wireguard_routing_table: 242 + +# Set this to something random. Make sure you open it in your firewall. +# wireguard_listen_port: + +file_index: 60 +path_prefix: "/etc/systemd/network/{{ file_index }}" +netdev_path: "{{ path_prefix }}-{{ wireguard_if}}.netdev" +network_path: "{{ path_prefix }}-{{ wireguard_if}}.network" +public_key_path: "{{ path_prefix }}-{{ wireguard_if}}.key" +private_key_path: "{{ path_prefix }}-{{ wireguard_if}}.pub" diff --git a/ansible/roles/wireguard2/handlers/main.yml b/ansible/roles/wireguard2/handlers/main.yml new file mode 100644 index 0000000..f0170dd --- /dev/null +++ b/ansible/roles/wireguard2/handlers/main.yml @@ -0,0 +1,5 @@ +- name: systemctl restart systemd-networkd + become: yes + systemd: + name: systemd-networkd + state: restarted diff --git a/ansible/roles/wireguard2/tasks/absent.yml b/ansible/roles/wireguard2/tasks/absent.yml new file mode 100644 index 0000000..82bfeb1 --- /dev/null +++ b/ansible/roles/wireguard2/tasks/absent.yml @@ -0,0 +1,18 @@ +- name: Clean old files + become: yes + file: + path: "{{ item }}" + state: absent + loop: + - "{{ netdev_path}}" + - "{{ network_path}}" + - "{{ private_key_path }}" + - "{{ public_key_path }}" + notify: systemctl restart systemd-networkd + +- name: remove interface + become: yes + shell: "ip l del dev {{ wireguard_if }}" + register: if_del + changed_when: if_del.rc == 0 + failed_when: false diff --git a/ansible/roles/wireguard2/tasks/install.yml b/ansible/roles/wireguard2/tasks/install.yml new file mode 100644 index 0000000..61c152d --- /dev/null +++ b/ansible/roles/wireguard2/tasks/install.yml @@ -0,0 +1,6 @@ +- name: apt install wireguard + become: yes + apt: + install_recommends: no + name: + - wireguard diff --git a/ansible/roles/wireguard2/tasks/main.yml b/ansible/roles/wireguard2/tasks/main.yml new file mode 100644 index 0000000..0985b01 --- /dev/null +++ b/ansible/roles/wireguard2/tasks/main.yml @@ -0,0 +1,13 @@ +- include_tasks: + file: install.yml + apply: + tags: never,install + tags: always + +- debug: var=wireguard_state + +- import_tasks: present.yml + when: wireguard_state == "present" + +- import_tasks: absent.yml + when: wireguard_state == "absent" diff --git a/ansible/roles/wireguard2/tasks/present.yml b/ansible/roles/wireguard2/tasks/present.yml new file mode 100644 index 0000000..967ec7d --- /dev/null +++ b/ansible/roles/wireguard2/tasks/present.yml @@ -0,0 +1,99 @@ +- name: "wg genkey {{ private_key_path }}" + become: yes + shell: "wg genkey | tee {{ private_key_path }} | wg pubkey > {{ public_key_path }}" + args: + creates: "{{ private_key_path }}" + register: wg_private_key_gen + +- name: chmod/chown keys + become: yes + file: + owner: systemd-network + group: adm + mode: 0640 + path: "{{ item }}" + loop: + - "{{ private_key_path }}" + - "{{ public_key_path }}" + +- when: wg_private_key_gen.changed + become: yes + fetch: + src: "{{ public_key_path }}" + dest: "files/{{ public_keys_path }}/{{ ansible_hostname }}.pub" + flat: true + +- become: yes + slurp: + src: "{{ private_key_path }}" + register: wg_private_key + +- name: "Create {{ netdev_path }}" + become: yes + notify: systemctl restart systemd-networkd + copy: + owner: systemd-network + group: adm + mode: 0640 + dest: "{{ netdev_path }}" + content: | + [NetDev] + Name={{ wireguard_if }} + Kind=wireguard + Description=Wireguard VPN ({{ wireguard_if }}) + + [WireGuard] + PrivateKey={{ wg_private_key['content'] | b64decode }} + {%- if wireguard_listen_port is defined %} + ListenPort={{ wireguard_listen_port }} + {% endif %} + {% for peer, data in wireguard_peers|dictsort %} + {% if peer != ansible_hostname %} + + # {{ peer }} + [WireGuardPeer] + PublicKey={{ data.public_key if data.public_key is defined else lookup('file', public_keys_path + "/" + peer + ".pub") }} + {% if data.endpoint is defined %} + {% if data.endpoint == "auto" %} + Endpoint={{ hostvars[peer]['ansible_host'] }}:{{ data.listen_port if data.listen_port is defined else wireguard_listen_port }} + {% else %} + Endpoint={{ data.endpoint }}:{{ data.listen_port if data.listen_port is defined else wireguard_listen_port }} + {% endif %} + {% endif %} + {% for ip in data.allowed_ips|default([]) %} + AllowedIPs={{ ip }} + {% endfor %} + PersistentKeepalive={{ data.keepalive if data.keepalive is defined else "60" }} + {% endif %}{# skip this host #} + {% endfor %} + +- name: "Create {{ network_path }}" + become: yes + notify: systemctl restart systemd-networkd + copy: + owner: systemd-network + group: adm + mode: 0640 + dest: "{{ network_path }}" + content: | + [Match] + Name={{ wireguard_if }} + + [Address] + Address={{ wireguard_address4 }} + + # Routers + {% for router in wireguard_routers %} + {% if router.state|default("absent") == "present" %} + + [Route] + Gateway={{ router.gateway|ipaddr('address') }} + Destination={{ router.network }} + {% endif %}{# state #} + {% endfor %} + +- become: yes + systemd: + unit: systemd-networkd + state: started + enabled: yes -- cgit v1.2.3