--- # The home-server project produces a multi-purpose setup using Ansible. # Copyright © 2018–2023 Y. Gablin, under the GPL-3.0-or-later license. # Full licensing information in the LICENSE file, or gnu.org/licences/gpl-3.0.txt if the file is missing. ### UPSTREAM BEGIN ⇒ ### - name: pull prerequisites from upstream include_role: name=etckeeper.inc allow_duplicates=true tasks_from=upstream.yml vars: msg: OpenVPN ### ⇐ UPSTREAM BEGIN ### - name: install software package: name: {{item}} with_items: - iproute2 - openvpn # jq is needed by no-VPN network-namespace script - jq ### UPSTREAM END ⇒ ### - name: merge upstream include_role: name=etckeeper.inc allow_duplicates=true tasks_from=merge.yml vars: msg: OpenVPN ### ⇐ UPSTREAM END ### - name: VPN configuration template: src: templates/vpn.conf.j2 dest: /etc/openvpn/client/{{vpn_name}}.conf owner: openvpn group: network mode: 0600 notify: - restart openvpn-client.service - name: VPN TLS auth key copy: content: | {{vpn_tls_auth_key}} dest: /etc/openvpn/client/{{vpn_name}}-ta.key owner: openvpn group: network mode: 0600 notify: - restart openvpn-client.service - name: VPN credentials copy: content: | {{vpn_login}} {{vpn_password}} dest: /etc/openvpn/client/{{vpn_name}}.userpass owner: openvpn group: network mode: 0400 notify: - restart openvpn-client.service - name: prepare to override OpenVPN security file: path: /etc/systemd/system/openvpn-client@{{vpn_name}}.service.d state: directory mode: 0755 notify: - restart openvpn-client.service - name: override OpenVPN security with systemd copy: content: | [Service] ExecStart= ExecStart=/usr/bin/openvpn --suppress-timestamps --nobind --config %i.conf --auth-user-pass /etc/openvpn/client/%i.userpass dest: /etc/systemd/system/openvpn-client@{{vpn_name}}.service.d/auth-user-pass.conf mode: 0644 notify: - restart openvpn-client.service - name: store DMZ IP (front) set_fact: current_IP: "{{DMZ_IP}}" when: - (inventory_hostname in groups['front']) - name: store SafeZone IP (back) set_fact: current_IP: "{{SafeZone_IP}}" when: - (inventory_hostname in groups['back']) - name: creation script for no-VPN network namespace copy: content: | #!/bin/bash # https://www.baeldung.com/linux/different-network-interfaces-processes set -e # find network settings associated with known IP address host_if=$(ip -j -4 address | jq -r '.[] | select(any(.addr_info[]; .local == "{{current_IP}}")) | .ifname') gateway=$(ip -j -4 route | jq -r '.[] | select(.dst == "default") | .gateway') # create namespace if it does not exist if ! ip netns list | grep -Fxq no-vpn; then ip netns add no-vpn fi # configure namespace if not done # $1: interface name; $2: CIDR function setup() { if ! ip -n no-vpn link show up dev $1 | grep -q .; then ip -n no-vpn link set $1 up fi if [ -z "$(ip -n no-vpn -4 address show dev $1)" ]; then ip -n no-vpn address add $2 dev $1 fi } if ! ip -n no-vpn link show dev if_isp &>/dev/null; then ip link add link $host_if if_isp netns no-vpn type ipvlan mode l2 fi setup if_isp {{vpn_avoiding_ip_cidr}} setup lo 127.0.0.1/8 # set gateway if not set if ! ip -n no-vpn -4 route | grep -q ^default; then ip -n no-vpn route add default via $gateway dev if_isp fi dest: /usr/local/bin/create-no-vpn-namespace.sh mode: 0700 notify: - restart no-vpn network namespace - name: removal script for no-VPN network namespace copy: content: | #!/bin/sh ip netns delete no-vpn dest: /usr/local/bin/delete-no-vpn-namespace.sh mode: 0700 notify: - restart no-vpn network namespace - name: no-VPN network namespace firewall template: src: templates/nftables.conf.j2 dest: /etc/netns/no-vpn/nftables.conf mode: 0600 notify: - restart no-vpn network namespace # https://github.com/mqus/nft-rules/blob/master/files/SSDP_client.md - name: systemctl service for no-VPN network namespace copy: content: | [Unit] Description=No-VPN network namespace After=network-online.target openvpn.service Wants=network-online.target openvpn.service [Service] Type=oneshot RemainAfterExit=true ExecStart=/usr/local/bin/create-no-vpn-namespace.sh ExecStartPost=/usr/bin/ip netns exec no-vpn /usr/bin/nft -f /etc/nftables.conf ExecStop=/usr/local/bin/delete-no-vpn-namespace.sh [Install] WantedBy=multi-user.target dest: /etc/systemd/system/no-vpn-network-namespace.service mode: 0644 notify: - restart no-vpn network namespace - name: enable service for no-VPN network namespace systemd: daemon_reload: true name: no-vpn-network-namespace.service enabled: true - name: enable OpenVPN client service systemd: daemon_reload: true name: openvpn-client@{{vpn_name}}.service enabled: true - name: register the fact that a VPN is enabled set_fact: is_vpn_used: true ### LOCAL COMMIT ⇒ ### - name: commit local changes include_role: name=etckeeper.inc allow_duplicates=true tasks_from=local.yml vars: msg: OpenVPN ### ⇐ LOCAL COMMIT ### - meta: flush_handlers