From a895214d8fe4b515fbef15a7f919c5177543ac56 Mon Sep 17 00:00:00 2001 From: Christian Pointner Date: Sat, 29 Feb 2020 03:29:26 +0100 Subject: wireguard gateway works now (it is quite ugly though) --- dan/ele-media.yml | 2 + inventory/host_vars/ele-gwhetzner.yml | 8 ++++ inventory/host_vars/ele-media.yml | 17 +++++++- .../templates/firewall/elevate-festival.sh.j2 | 5 ++- .../templates/netplan/elevate-festival.yaml.j2 | 10 +---- roles/wireguard/gateway/defaults/main.yml | 1 + roles/wireguard/gateway/tasks/main.yml | 48 ++++++++++++++++++++++ .../gateway/tasks/systemd-iptables.service.j2 | 42 +++++++++++++++++++ .../templates/systemd-fix-default-gw.service.j2 | 12 ++++++ .../wireguard/gateway/templates/systemd.network.j2 | 13 ++++++ 10 files changed, 147 insertions(+), 11 deletions(-) create mode 100644 roles/wireguard/gateway/tasks/systemd-iptables.service.j2 create mode 100644 roles/wireguard/gateway/templates/systemd-fix-default-gw.service.j2 diff --git a/dan/ele-media.yml b/dan/ele-media.yml index 3e274155..e9c36495 100644 --- a/dan/ele-media.yml +++ b/dan/ele-media.yml @@ -13,3 +13,5 @@ - role: docker - role: nginx/base - role: elevate/media + - role: wireguard/base + - role: wireguard/gateway diff --git a/inventory/host_vars/ele-gwhetzner.yml b/inventory/host_vars/ele-gwhetzner.yml index aeaa936f..f68ff783 100644 --- a/inventory/host_vars/ele-gwhetzner.yml +++ b/inventory/host_vars/ele-gwhetzner.yml @@ -44,6 +44,14 @@ wireguard_gateway_tunnels: priv_key: "{{ wireguard_keys.elemedia.priv }}" addresses: - 192.168.254.1/30 + ip_snat: + interface: "{{ network.primary.interface }}" + to: "{{ network.primary.overlay }}" + port_forwardings: + - dest: "{{ network.primary.overlay }}" + tcp_ports: + 80: 192.168.254.2:80 + 443: 192.168.254.2:443 peers: - pub_key: "{{ hostvars['ele-media'].wireguard_keys.gwhetzner.pub }}" allowed_ips: diff --git a/inventory/host_vars/ele-media.yml b/inventory/host_vars/ele-media.yml index a0a388e9..ea298088 100644 --- a/inventory/host_vars/ele-media.yml +++ b/inventory/host_vars/ele-media.yml @@ -12,7 +12,7 @@ network: mask: "{{ network_zones.lan.prefix | ipaddr('netmask') }}" gateway: "{{ network_zones.lan.gateway }}" -network_setup: r3-with-lan # elevate-festival +network_setup: elevate-festival dyndns: @@ -72,3 +72,18 @@ wireguard_keys: gwhetzner: pub: "YO78lnFJdlGnKxBrtVZF4QXF7bpF8rAP7yF97klWLzg=" priv: "{{ vault_wireguard_priv_keys.gwhetzner }}" + +wireguard_gateway_tunnels: + wg-gwhetzner: + priv_key: "{{ wireguard_keys.gwhetzner.priv }}" + addresses: + - 192.168.254.2/30 + default_gateway: + outer: 178.63.180.138 + inner: 192.168.254.1 + peers: + - pub_key: "{{ hostvars['ele-gwhetzner'].wireguard_keys.elemedia.pub }}" + endpoint: 178.63.180.138:51820 # TODO: fix this variable "{{ hostvars['ele-gwhetzner'].external_ip }}" + keepalive_interval: 15 + allowed_ips: + - 0.0.0.0/0 diff --git a/roles/elevate/media/templates/firewall/elevate-festival.sh.j2 b/roles/elevate/media/templates/firewall/elevate-festival.sh.j2 index 987117c8..fea33cc2 100644 --- a/roles/elevate/media/templates/firewall/elevate-festival.sh.j2 +++ b/roles/elevate/media/templates/firewall/elevate-festival.sh.j2 @@ -19,8 +19,8 @@ LAN_IF="{{ network.primary.interface }}" LAN_IPADDR="{{ network.primary.ip }}" LAN_NETMASK="{{ network.primary.mask }}" -EXT_IF="{{ network.primary.interface }}.{{ network_zones.ccinet.vlan }}" -EXT_IPADDR="{{ network_zones.ccinet.prefix | ipaddr(network_zones.ccinet.offsets[inventory_hostname]) | ipaddr('address') }}" +EXT_IF="wg-gwhetzner" +EXT_IPADDR="192.168.254.2" EXT_SERVICES_TCP="80 443 22000" EXT_SERVICES_UDP="" @@ -34,6 +34,7 @@ ipv4_up() { $FILTER -A INPUT -i lo -j ACCEPT $FILTER -A INPUT -i "$LAN_IF" -d "$LAN_IPADDR" -s "$LAN_IPADDR/$LAN_NETMASK" -j ACCEPT + $FILTER -A INPUT -i "$LAN_IF" -d "$LAN_IPADDR" -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT $FILTER -A INPUT -i "$EXT_IF" -d "$EXT_IPADDR" -p icmp -j ACCEPT for port in $EXT_SERVICES_TCP; do diff --git a/roles/elevate/media/templates/netplan/elevate-festival.yaml.j2 b/roles/elevate/media/templates/netplan/elevate-festival.yaml.j2 index 3c2bbb78..3bd97cb6 100644 --- a/roles/elevate/media/templates/netplan/elevate-festival.yaml.j2 +++ b/roles/elevate/media/templates/netplan/elevate-festival.yaml.j2 @@ -4,14 +4,8 @@ network: ethernets: {{ network.primary.interface }}: addresses: [ {{ (network.primary.ip + '/' + network.primary.mask) | ipaddr('address/prefix') }} ] - accept-ra: false - vlans: - {{ network.primary.interface }}.{{ network_zones.ccinet.vlan }}: - id: {{ network_zones.ccinet.vlan }} - link: {{ network.primary.interface }} - addresses: [ {{ network_zones.ccinet.prefix | ipaddr(network_zones.ccinet.offsets[inventory_hostname]) | ipaddr('address/prefix') }} ] - gateway4: {{ network_zones.ccinet.gateway }} + gateway4: {{ network.primary.gateway }} accept-ra: false nameservers: search: [ {{ network.domain }} ] - addresses: {{ network_zones.ccinet.dns | to_json }} + addresses: {{ network.nameservers | to_json }} diff --git a/roles/wireguard/gateway/defaults/main.yml b/roles/wireguard/gateway/defaults/main.yml index 9ee0523c..8b1ab7f6 100644 --- a/roles/wireguard/gateway/defaults/main.yml +++ b/roles/wireguard/gateway/defaults/main.yml @@ -6,6 +6,7 @@ # listen_port: 1234 # addresses: # - 192.168.255.254/24 +# ip_masq: yes # peers: # - pub_key: public_key_of_peer # keepalive_interval: 10 diff --git a/roles/wireguard/gateway/tasks/main.yml b/roles/wireguard/gateway/tasks/main.yml index 906ee640..bc14db1b 100644 --- a/roles/wireguard/gateway/tasks/main.yml +++ b/roles/wireguard/gateway/tasks/main.yml @@ -18,3 +18,51 @@ src: systemd.network.j2 dest: "/etc/systemd/network/{{ item.key }}.network" notify: restart systemd-networkd + +- name: enable systemd-networkd + systemd: + name: systemd-networkd + enabled: yes + state: started + + +- name: create iptables service unit + loop: "{{ wireguard_gateway_tunnels | dict2items }}" + loop_control: + label: "{{ item.key }}" + when: "'ip_snat' in item.value or 'port_forwardings' in item.value" + template: + src: systemd-iptables.service.j2 + dest: "/etc/systemd/system/wireguard-gateway-{{ item.key }}-iptables.service" + +- name: enable/start iptables service unit + loop: "{{ wireguard_gateway_tunnels | dict2items }}" + loop_control: + label: "{{ item.key }}" + when: "'ip_snat' in item.value or 'port_forwardings' in item.value" + systemd: + daemon_reload: yes + name: "wireguard-gateway-{{ item.key }}-iptables.service" + enabled: yes + state: started + + +- name: install workaround for default-gateway handling + loop: "{{ wireguard_gateway_tunnels | dict2items }}" + loop_control: + label: "{{ item.key }}" + when: "'default_gateway' in item.value" + template: + src: systemd-fix-default-gw.service.j2 + dest: "/etc/systemd/system/wireguard-gateway-{{ item.key }}-fix-default-gw.service" + +- name: enable/start workaround for default-gateway handling + loop: "{{ wireguard_gateway_tunnels | dict2items }}" + loop_control: + label: "{{ item.key }}" + when: "'default_gateway' in item.value" + systemd: + daemon_reload: yes + name: "wireguard-gateway-{{ item.key }}-fix-default-gw.service" + enabled: yes + state: started diff --git a/roles/wireguard/gateway/tasks/systemd-iptables.service.j2 b/roles/wireguard/gateway/tasks/systemd-iptables.service.j2 new file mode 100644 index 00000000..11cf4b8a --- /dev/null +++ b/roles/wireguard/gateway/tasks/systemd-iptables.service.j2 @@ -0,0 +1,42 @@ +[Unit] +Wants=network-online.target +After=network-online.target + + +[Service] +Type=oneshot + +{% if 'ip_snat' in item.value %} +ExecStart=/usr/sbin/sysctl net.ipv4.ip_forward=1 +{% for addr in item.value.addresses %} +ExecStart=/sbin/iptables -t nat -A POSTROUTING -s {{ addr | ipaddr('network/prefix') }} -o {{ item.value.ip_snat.interface }} -j SNAT --to {{ item.value.ip_snat.to }} +{% endfor %} +{% endif %} +{% for forward in item.value.port_forwardings | default([]) %} +{% for port in forward.tcp_ports | default([]) %} +ExecStart=/sbin/iptables -t nat -A PREROUTING -d {{ forward.dest }} -p tcp --dport {{ port }} -j DNAT --to {{ forward.tcp_ports[port] }} +{% endfor %} +{% for port in forward.udp_ports | default([]) %} +ExecStart=/sbin/iptables -t nat -A PREROUTING -d {{ forward.dest }} -p udp --dport {{ port }} -j DNAT --to {{ forward.udp_ports[port] }} +{% endfor %} +{% endfor %} + +{% if 'ip_snat' in item.value %} +{% for addr in item.value.addresses %} +ExecStop=/sbin/iptables -t nat -D POSTROUTING -s {{ addr | ipaddr('network/prefix') }} -o {{ item.value.ip_snat.interface }} -j SNAT --to {{ item.value.ip_snat.to }} +{% endfor %} +{% endif %} +{% for forward in item.value.port_forwardings | default([]) %} +{% for port in forward.tcp_ports | default([]) %} +ExecStop=/sbin/iptables -t nat -D PREROUTING -d {{ forward.dest }} -p tcp --dport {{ port }} -j DNAT --to {{ forward.tcp_ports[port] }} +{% endfor %} +{% for port in forward.udp_ports | default([]) %} +ExecStop=/sbin/iptables -t nat -D PREROUTING -d {{ forward.dest }} -p udp --dport {{ port }} -j DNAT --to {{ forward.udp_ports[port] }} +{% endfor %} +{% endfor %} + +RemainAfterExit=yes + + +[Install] +WantedBy=multi-user.target diff --git a/roles/wireguard/gateway/templates/systemd-fix-default-gw.service.j2 b/roles/wireguard/gateway/templates/systemd-fix-default-gw.service.j2 new file mode 100644 index 00000000..d2d8a470 --- /dev/null +++ b/roles/wireguard/gateway/templates/systemd-fix-default-gw.service.j2 @@ -0,0 +1,12 @@ +[Unit] +Wants=network-online.target +After=network-online.target + +[Service] +Type=oneshot +ExecStart=/sbin/ip route add {{ item.value.default_gateway.outer }} via {{ ansible_default_ipv4.gateway }} +ExecStop=/sbin/ip route del {{ item.value.default_gateway.outer }} via {{ ansible_default_ipv4.gateway }} +RemainAfterExit=yes + +[Install] +WantedBy=multi-user.target diff --git a/roles/wireguard/gateway/templates/systemd.network.j2 b/roles/wireguard/gateway/templates/systemd.network.j2 index 8d8af966..6847aa6a 100644 --- a/roles/wireguard/gateway/templates/systemd.network.j2 +++ b/roles/wireguard/gateway/templates/systemd.network.j2 @@ -5,3 +5,16 @@ Name={{ item.key }} {% for addr in item.value.addresses %} Address={{ addr }} {% endfor %} +{% if 'ip_masq' in item.value and item.value.ip_masq %} +IPMasquerade=yes +{% endif %} +{% if 'default_gateway' in item.value %} + +[Route] +Destination=0.0.0.0/1 +Gateway={{ item.value.default_gateway.inner }} + +[Route] +Destination=128.0.0.0/1 +Gateway={{ item.value.default_gateway.inner }} +{% endif %} -- cgit v1.2.3