From e4e8c0998f2f52bb90972155a6f66cc9ebd4ead0 Mon Sep 17 00:00:00 2001 From: Tobias Hachmer Date: Tue, 19 Mar 2019 15:23:12 +0100 Subject: [PATCH] Introduce p2p vpn link between all ffmwu servers via WireGuard for routing purpose. * add jinja2 extension 'jinja2.ext.do' to ansible.cfg * add host kichererbse.freifunk-mwu.de * add new server_type 'mesh-service' and new host group 'ffmwu-mesh-services' * use new loopback and anycast networks * add role wireguard * add role wireguard as dependency for roles network-routing + service-bird * add playbook 'mesh-services' --- ansible.cfg | 1 + inventory/ffmwu-mesh-services | 5 + inventory/group_vars/all | 233 +++++++++++++++++- inventory/group_vars/ffmwu-mesh-services | 12 + .../host_vars/kichererbse.freifunk-mwu.de | 4 + playbooks/gateways.yml | 1 + playbooks/mesh-services.yml | 20 ++ playbooks/monitoring.yml | 1 + roles/network-routing/meta/main.yml | 3 + roles/network-routing/tasks/main.yml | 2 +- .../templates/ffmwu-add-ip-rules.sh.j2 | 8 + .../templates/ffmwu-add-static-routes.sh.j2 | 17 +- .../templates/ffmwu-del-ip-rules.sh.j2 | 8 + .../templates/ffmwu-del-static-routes.sh.j2 | 15 +- roles/service-bird-lg/templates/lg.cfg.j2 | 2 +- .../service-bird-lg/templates/lgproxy.cfg.j2 | 4 +- roles/service-bird/meta/main.yml | 3 + roles/service-bird/templates/bird.conf.j2 | 23 +- roles/service-bird/templates/bird6.conf.j2 | 21 +- .../templates/mwu_ipv4_peers.conf.j2 | 22 +- .../templates/mwu_ipv6_peers.conf.j2 | 20 +- roles/wireguard/defaults/main.yml | 6 + roles/wireguard/handlers/main.yml | 5 + roles/wireguard/tasks/main.yml | 80 ++++++ roles/wireguard/templates/wg.conf.j2 | 12 + roles/wireguard/templates/wireguard.j2 | 19 ++ roles/wireguard/vars/main.yml | 5 + 27 files changed, 508 insertions(+), 44 deletions(-) create mode 100644 inventory/ffmwu-mesh-services create mode 100644 inventory/group_vars/ffmwu-mesh-services create mode 100644 inventory/host_vars/kichererbse.freifunk-mwu.de create mode 100755 playbooks/mesh-services.yml create mode 100644 roles/network-routing/meta/main.yml create mode 100644 roles/service-bird/meta/main.yml create mode 100644 roles/wireguard/defaults/main.yml create mode 100644 roles/wireguard/handlers/main.yml create mode 100644 roles/wireguard/tasks/main.yml create mode 100644 roles/wireguard/templates/wg.conf.j2 create mode 100644 roles/wireguard/templates/wireguard.j2 create mode 100644 roles/wireguard/vars/main.yml diff --git a/ansible.cfg b/ansible.cfg index e84d45a..566c884 100644 --- a/ansible.cfg +++ b/ansible.cfg @@ -7,6 +7,7 @@ ansible_managed = Ansible managed - don't edit this file! roles_path = ./roles stdout_callback = yaml bin_ansible_callbacks = True +jinja2_extensions = jinja2.ext.do [privilege_escalation] become = True diff --git a/inventory/ffmwu-mesh-services b/inventory/ffmwu-mesh-services new file mode 100644 index 0000000..5d69a08 --- /dev/null +++ b/inventory/ffmwu-mesh-services @@ -0,0 +1,5 @@ +[ffmwu-mesh-services:children] +dns-master-internal + +[dns-master-internal] +kichererbse.freifunk-mwu.de diff --git a/inventory/group_vars/all b/inventory/group_vars/all index a991d0d..78327bc 100644 --- a/inventory/group_vars/all +++ b/inventory/group_vars/all @@ -14,10 +14,10 @@ internet_exit_tcp_mss_ipv6: 1220 icvpn_ipv4_transfer_net: 10.207.0.0/16 icvpn_ipv6_transfer_net: fec0::a:cf:0:0/96 -loopback_net_ipv4: 10.37.255.0/24 -loopback_net_ipv6: fd37:b4dc:4b1e:ffff::/64 -anycast_ipv4: 10.37.255.255/32 -anycast_ipv6: fd37:b4dc:4b1e:ffff:ffff:ffff:ffff:ffff/128 +loopback_net_ipv4: 10.87.255.0/24 +loopback_net_ipv6: fd86:b4dc:4b1e:00ff::/64 +anycast_ipv4: 10.87.255.255/32 +anycast_ipv6: fd86:b4dc:4b1e:00ff:ffff:ffff:ffff:ffff/128 internal_prefixes: - ipv4: 10.37.0.0/16 @@ -31,19 +31,238 @@ public_prefixes: - ipv6: 2a03:2260:11a::/48 - ipv6: 2a03:2260:11b::/48 -bgp_loopback_net: 10.37.0.0/18 -bgp_ipv4_transfer_net: 10.37.0.0/18 -bgp_ipv6_transfer_net: fd37:b4dc:4b1e::/64 +bgp_ipv4_transfer_net_legacy: 10.37.0.0/18 +bgp_ipv6_transfer_net_legacy: fd37:b4dc:4b1e::/64 bgp_groups: - ffmwu-gateways + - ffmwu-mesh-services - ffmwu-monitoring +wireguard_networks: + - ipv4: 10.87.253.0/31 + ipv6: fd86:b4dc:4b1e:fd::/127 + peers: + - lotuswurzel + - spinat + port: 50000 + - ipv4: 10.87.253.2/31 + ipv6: fd86:b4dc:4b1e:fd::2/127 + peers: + - lotuswurzel + - wasserfloh + port: 50001 + - ipv4: 10.87.253.4/31 + ipv6: fd86:b4dc:4b1e:fd::4/127 + peers: + - lotuswurzel + - uffschnitt + port: 50002 + - ipv4: 10.87.253.6/31 + ipv6: fd86:b4dc:4b1e:fd::6/127 + peers: + - lotuswurzel + - ingwer + port: 50003 + - ipv4: 10.87.253.8/31 + ipv6: fd86:b4dc:4b1e:fd::8/127 + peers: + - spinat + - wasserfloh + port: 50004 + - ipv4: 10.87.253.10/31 + ipv6: fd86:b4dc:4b1e:fd::a/127 + peers: + - spinat + - uffschnitt + port: 50005 + - ipv4: 10.87.253.12/31 + ipv6: fd86:b4dc:4b1e:fd::c/127 + peers: + - spinat + - ingwer + port: 50006 + - ipv4: 10.87.253.14/31 + ipv6: fd86:b4dc:4b1e:fd::e/127 + peers: + - ingwer + - wasserfloh + port: 50007 + - ipv4: 10.87.253.16/31 + ipv6: fd86:b4dc:4b1e:fd::10/127 + peers: + - wasserfloh + - uffschnitt + port: 50008 + - ipv4: 10.87.253.18/31 + ipv6: fd86:b4dc:4b1e:fd::12/127 + peers: + - ingwer + - uffschnitt + port: 50009 + - ipv4: 10.87.253.20/31 + ipv6: fd86:b4dc:4b1e:fd::14/127 + peers: + - lotuswurzel + - kichererbse + port: 50010 +# - ipv4: 10.87.253.22/31 +# ipv6: fd86:b4dc:4b1e:fd::16/127 +# peers: +# - lotuswurzel +# - zuckerwatte +# port: 50011 +# - ipv4: 10.87.253.24/31 +# ipv6: fd86:b4dc:4b1e:fd::18/127 +# peers: +# - lotuswurzel +# - glueckskeks +# port: 50012 +# - ipv4: 10.87.253.26/31 +# ipv6: fd86:b4dc:4b1e:fd::1a/127 +# peers: +# - lotuswurzel +# - aubergine +# port: 50013 + - ipv4: 10.87.253.28/31 + ipv6: fd86:b4dc:4b1e:fd::1c/127 + peers: + - spinat + - kichererbse + port: 50014 +# - ipv4: 10.87.253.30/31 +# ipv6: fd86:b4dc:4b1e:fd::1e/127 +# peers: +# - spinat +# - zuckerwatte +# port: 50015 +# - ipv4: 10.87.253.32/31 +# ipv6: fd86:b4dc:4b1e:fd::20/127 +# peers: +# - spinat +# - glueckskeks +# port: 50016 +# - ipv4: 10.87.253.34/31 +# ipv6: fd86:b4dc:4b1e:fd::22/127 +# peers: +# - spinat +# - aubergine +# port: 50017 + - ipv4: 10.87.253.36/31 + ipv6: fd86:b4dc:4b1e:fd::24/127 + peers: + - wasserfloh + - kichererbse + port: 50018 +# - ipv4: 10.87.253.38/31 +# ipv6: fd86:b4dc:4b1e:fd::26/127 +# peers: +# - wasserfloh +# - zuckerwatte +# port: 50019 +# - ipv4: 10.87.253.40/31 +# ipv6: fd86:b4dc:4b1e:fd::28/127 +# peers: +# - wasserfloh +# - glueckskeks +# port: 50020 +# - ipv4: 10.87.253.42/31 +# ipv6: fd86:b4dc:4b1e:fd::2a/127 +# peers: +# - wasserfloh +# - aubergine +# port: 50021 + - ipv4: 10.87.253.44/31 + ipv6: fd86:b4dc:4b1e:fd::2c/127 + peers: + - uffschnitt + - kichererbse + port: 50022 +# - ipv4: 10.87.253.46/31 +# ipv6: fd86:b4dc:4b1e:fd::2e/127 +# peers: +# - uffschnitt +# - zuckerwatte +# port: 50023 +# - ipv4: 10.87.253.48/31 +# ipv6: fd86:b4dc:4b1e:fd::30/127 +# peers: +# - uffschnitt +# - glueckskeks +# port: 50024 +# - ipv4: 10.87.253.50/31 +# ipv6: fd86:b4dc:4b1e:fd::32/127 +# peers: +# - uffschnitt +# - aubergine +# port: 50025 + - ipv4: 10.87.253.52/31 + ipv6: fd86:b4dc:4b1e:fd::34/127 + peers: + - ingwer + - kichererbse + port: 50026 +# - ipv4: 10.87.253.54/31 +# ipv6: fd86:b4dc:4b1e:fd::36/127 +# peers: +# - ingwer +# - zuckerwatte +# port: 50027 +# - ipv4: 10.87.253.56/31 +# ipv6: fd86:b4dc:4b1e:fd::38/127 +# peers: +# - ingwer +# - glueckskeks +# port: 50028 +# - ipv4: 10.87.253.58/31 +# ipv6: fd86:b4dc:4b1e:fd::3a/127 +# peers: +# - ingwer +# - aubergine +# port: 50029 + - ipv4: 10.87.253.60/31 + ipv6: fd86:b4dc:4b1e:fd::34/127 + peers: + - lotuswurzel + - suesskartoffel + port: 50030 + - ipv4: 10.87.253.62/31 + ipv6: fd86:b4dc:4b1e:fd::36/127 + peers: + - spinat + - suesskartoffel + port: 50031 + - ipv4: 10.87.253.64/31 + ipv6: fd86:b4dc:4b1e:fd::38/127 + peers: + - ingwer + - suesskartoffel + port: 50032 + - ipv4: 10.87.253.66/31 + ipv6: fd86:b4dc:4b1e:fd::3a/127 + peers: + - wasserfloh + - suesskartoffel + port: 50033 + - ipv4: 10.87.253.68/31 + ipv6: fd86:b4dc:4b1e:fd::3c/127 + peers: + - uffschnitt + - suesskartoffel + port: 50034 + - ipv4: 10.87.253.70/31 + ipv6: fd86:b4dc:4b1e:fd::3e/127 + peers: + - kichererbse + - suesskartoffel + port: 50036 + fastd_groups: - ffmwu-gateways - ffmwu-monitoring prometheus_groups: - ffmwu-gateways + - ffmwu-mesh-services - ffmwu-monitoring node_exporter_opts: "--collector.systemd" diff --git a/inventory/group_vars/ffmwu-mesh-services b/inventory/group_vars/ffmwu-mesh-services new file mode 100644 index 0000000..33b425b --- /dev/null +++ b/inventory/group_vars/ffmwu-mesh-services @@ -0,0 +1,12 @@ +--- +routing_tables: + mwu: 41 + +common_repos: + backend-scripts: + repo_url: https://github.com/freifunk-mwu/backend-scripts.git + version: master + force: no + +prometheus_components: + - node_exporter diff --git a/inventory/host_vars/kichererbse.freifunk-mwu.de b/inventory/host_vars/kichererbse.freifunk-mwu.de new file mode 100644 index 0000000..4113fae --- /dev/null +++ b/inventory/host_vars/kichererbse.freifunk-mwu.de @@ -0,0 +1,4 @@ +--- +server_type: "mesh-service" + +magic: 67 diff --git a/playbooks/gateways.yml b/playbooks/gateways.yml index 716411e..85be599 100755 --- a/playbooks/gateways.yml +++ b/playbooks/gateways.yml @@ -14,6 +14,7 @@ - service-haveged - service-ntpd - kmod-batman + - wireguard - network-routetables - network-batman - network-meshbridge diff --git a/playbooks/mesh-services.yml b/playbooks/mesh-services.yml new file mode 100755 index 0000000..7f0049b --- /dev/null +++ b/playbooks/mesh-services.yml @@ -0,0 +1,20 @@ +#!/usr/bin/ansible-playbook + +- name: Manage Mesh Services Servers. + hosts: ffmwu-mesh-services + + roles: + - server-apt-repos + - server-basic + - network-loopback + - users + - system-sysctl + - git-repos + - service-haveged + - service-ntpd + - wireguard + - network-routetables + - network-routing + - service-bird + - service-nginx + - service-nullmailer diff --git a/playbooks/monitoring.yml b/playbooks/monitoring.yml index 7d93f17..b03d5e9 100755 --- a/playbooks/monitoring.yml +++ b/playbooks/monitoring.yml @@ -13,6 +13,7 @@ - service-haveged - service-ntpd - kmod-batman + - wireguard - network-routetables - network-batman - network-meshbridge diff --git a/roles/network-routing/meta/main.yml b/roles/network-routing/meta/main.yml new file mode 100644 index 0000000..884a904 --- /dev/null +++ b/roles/network-routing/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - wireguard diff --git a/roles/network-routing/tasks/main.yml b/roles/network-routing/tasks/main.yml index 002c918..f6c9ac5 100644 --- a/roles/network-routing/tasks/main.yml +++ b/roles/network-routing/tasks/main.yml @@ -61,7 +61,7 @@ loop: "{{ sysctl_settings_routing_basic }}" - name: set gateway sysctl settings for routing - when: server_type == "gateway" + when: server_type == "gateway" or server_type == "mesh-service" sysctl: name: "{{ item.name }}" value: "{{ item.value }}" diff --git a/roles/network-routing/templates/ffmwu-add-ip-rules.sh.j2 b/roles/network-routing/templates/ffmwu-add-ip-rules.sh.j2 index 38ba4b4..65efcd9 100644 --- a/roles/network-routing/templates/ffmwu-add-ip-rules.sh.j2 +++ b/roles/network-routing/templates/ffmwu-add-ip-rules.sh.j2 @@ -4,10 +4,18 @@ # # Priority 7 - lookup rt_table mwu for all incoming traffic of freifunk related interfaces +{% if server_type == 'gateway' or server_type == 'monitoring' %} {% for mesh in meshes %} ip -4 rule add from all oif {{ mesh.id }}br lookup mwu priority 7 ip -6 rule add from all oif {{ mesh.id }}br lookup mwu priority 7 {% endfor %} +{% endif %} +{% for network in my_wireguard_networks %} +ip -4 rule add from all iif wg-{{ network.remote[:11] }} lookup mwu priority 7 +ip -6 rule add from all iif wg-{{ network.remote[:11] }} lookup mwu priority 7 +ip -4 rule add from all oif wg-{{ network.remote[:11] }} lookup mwu priority 7 +ip -6 rule add from all oif wg-{{ network.remote[:11] }} lookup mwu priority 7 +{% endfor %} {% for prefix in internal_prefixes %} ip -4 rule add from {{ prefix.ipv4 }} lookup mwu priority 7 ip -4 rule add to {{ prefix.ipv4 }} lookup mwu priority 7 diff --git a/roles/network-routing/templates/ffmwu-add-static-routes.sh.j2 b/roles/network-routing/templates/ffmwu-add-static-routes.sh.j2 index 532edee..601db23 100644 --- a/roles/network-routing/templates/ffmwu-add-static-routes.sh.j2 +++ b/roles/network-routing/templates/ffmwu-add-static-routes.sh.j2 @@ -3,6 +3,16 @@ # {{ ansible_managed }} # +{% for network in my_wireguard_networks %} +{% if magic < network.remote_magic %} +/sbin/ip -4 route add {{ network.ipv4 | ipaddr('network/prefix') }} dev wg-{{ network.remote[:11] }} scope link src {{ network.ipv4 | ipaddr('address') }} table mwu +/sbin/ip -6 route add {{ network.ipv6 | ipaddr('network/prefix') }} dev wg-{{ network.remote[:11] }} scope link src {{ network.ipv6 | ipaddr('network') }} table mwu +{% else %} +/sbin/ip -4 route add {{ network.ipv4 | ipaddr('network/prefix') }} dev wg-{{ network.remote[:11] }} scope link src {{ network.ipv4 | ipaddr('1') | ipaddr('address') }} table mwu +/sbin/ip -6 route add {{ network.ipv6 | ipaddr('network/prefix') }} dev wg-{{ network.remote[:11] }} scope link src {{ network.ipv6 | ipaddr('1') | ipaddr('address') }} table mwu +{% endif %} +{% endfor %} +{% if server_type == 'gateway' or server_type == 'monitoring' %} {% for mesh in meshes %} # static {{ mesh.domain_name }} routes for rt_table mwu /sbin/ip -4 route add {{ mesh.ipv4_network }} proto static dev {{ mesh.id }}br table mwu @@ -21,6 +31,7 @@ {% endif %} {% endfor %} +{% endif %} {% if server_type == 'gateway' %} # static blackhole routes for rt_table internet @@ -69,10 +80,4 @@ /sbin/ip -6 route add blackhole ::/96 table main /sbin/ip -6 route add blackhole 0:0:0:0:0:ffff::/96 table main /sbin/ip -6 route add blackhole ::/0 table main -{% else %} -# static routes for icvpn -/sbin/ip -4 route add {{ icvpn_ipv4_transfer_net }}{% for host in groups['ffmwu-gateways'] %} nexthop via {{ bgp_ipv4_transfer_net | ipaddr('net') | ipaddr(hostvars[host]['magic']) | ipaddr('ip') }}{% endfor %} - -/sbin/ip -6 route add {{ icvpn_ipv6_transfer_net }}{% for host in groups['ffmwu-gateways'] %} nexthop via {{ bgp_ipv6_transfer_net | ipaddr('net') | ipsubnet(64, 0) | ipaddr(hostvars[host]['magic']) | ipaddr('ip') }}{% endfor %} - {% endif %} diff --git a/roles/network-routing/templates/ffmwu-del-ip-rules.sh.j2 b/roles/network-routing/templates/ffmwu-del-ip-rules.sh.j2 index d8913ce..cf4f95f 100644 --- a/roles/network-routing/templates/ffmwu-del-ip-rules.sh.j2 +++ b/roles/network-routing/templates/ffmwu-del-ip-rules.sh.j2 @@ -4,10 +4,18 @@ # # Priority 7 - lookup rt_table mwu for all incoming traffic of freifunk related interfaces +{% if server_type == 'gateway' or server_type == 'monitoring' %} {% for mesh in meshes %} ip -4 rule del from all oif {{ mesh.id }}br lookup mwu priority 7 ip -6 rule del from all oif {{ mesh.id }}br lookup mwu priority 7 {% endfor %} +{% endif %} +{% for network in my_wireguard_networks %} +ip -4 rule del from all iif wg-{{ network.remote[:11] }} lookup mwu priority 7 +ip -6 rule del from all iif wg-{{ network.remote[:11] }} lookup mwu priority 7 +ip -4 rule del from all oif wg-{{ network.remote[:11] }} lookup mwu priority 7 +ip -6 rule del from all oif wg-{{ network.remote[:11] }} lookup mwu priority 7 +{% endfor %} {% for prefix in internal_prefixes %} ip -4 rule del from {{ prefix.ipv4 }} lookup mwu priority 7 ip -4 rule del to {{ prefix.ipv4 }} lookup mwu priority 7 diff --git a/roles/network-routing/templates/ffmwu-del-static-routes.sh.j2 b/roles/network-routing/templates/ffmwu-del-static-routes.sh.j2 index 16a7a5e..eb653d2 100644 --- a/roles/network-routing/templates/ffmwu-del-static-routes.sh.j2 +++ b/roles/network-routing/templates/ffmwu-del-static-routes.sh.j2 @@ -3,6 +3,16 @@ # {{ ansible_managed }} # +{% for network in my_wireguard_networks %} +{% if magic < network.remote_magic %} +/sbin/ip -4 route del {{ network.ipv4 | ipaddr('network/prefix') }} dev wg-{{ network.remote[:11] }} scope link src {{ network.ipv4 | ipaddr('address') }} table mwu +/sbin/ip -6 route del {{ network.ipv6 | ipaddr('network/prefix') }} dev wg-{{ network.remote[:11] }} scope link src {{ network.ipv6 | ipaddr('network') }} table mwu +{% else %} +/sbin/ip -4 route del {{ network.ipv4 | ipaddr('network/prefix') }} dev wg-{{ network.remote[:11] }} scope link src {{ network.ipv4 | ipaddr('1') | ipaddr('address') }} table mwu +/sbin/ip -6 route del {{ network.ipv6 | ipaddr('network/prefix') }} dev wg-{{ network.remote[:11] }} scope link src {{ network.ipv6 | ipaddr('1') | ipaddr('address') }} table mwu +{% endif %} +{% endfor %} +{% if server_type == 'gateway' or server_type == 'monitoring' %} {% for mesh in meshes %} # static {{ mesh.domain_name }} routes for rt_table mwu /sbin/ip -4 route del {{ mesh.ipv4_network }} proto static dev {{ mesh.id }}br table mwu @@ -21,6 +31,7 @@ {% endif %} {% endfor %} +{% endif %} {% if server_type == 'gateway' %} # static blackhole routes for rt_table internet @@ -69,8 +80,4 @@ /sbin/ip -6 route del blackhole ::/96 table main /sbin/ip -6 route del blackhole 0:0:0:0:0:ffff::/96 table main /sbin/ip -6 route del blackhole ::/0 table main -{% else %} -# static routes for icvpn -/sbin/ip -4 route flush exact {{ icvpn_ipv4_transfer_net }} -/sbin/ip -6 route flush exact {{ icvpn_ipv6_transfer_net }} {% endif %} diff --git a/roles/service-bird-lg/templates/lg.cfg.j2 b/roles/service-bird-lg/templates/lg.cfg.j2 index 20eb42d..4df906d 100644 --- a/roles/service-bird-lg/templates/lg.cfg.j2 +++ b/roles/service-bird-lg/templates/lg.cfg.j2 @@ -16,7 +16,7 @@ PROXY = { # Used for bgpmap ROUTER_IP = { {% for host in groups["ffmwu-gateways"] %} - "{{ host.rsplit('.freifunk-mwu.de')[0] }}" : [ "{{ bgp_ipv4_transfer_net | ipaddr('net') | ipaddr(hostvars[host]['magic']) | ipaddr('ip') }}", "{{ bgp_ipv6_transfer_net | ipaddr('net') | ipsubnet(64, 0) | ipaddr(hostvars[host]['magic']) | ipaddr('ip') }}" ], + "{{ host.rsplit('.freifunk-mwu.de')[0] }}" : [ "{{ loopback_net_ipv4 | ipsubnet(32, hostvars[host]['magic']) | ipaddr('address') }}", "{{ loopback_net_ipv6 | ipaddr(hostvars[host]['magic']) | ipaddr('address') }}" ], {% endfor %} } diff --git a/roles/service-bird-lg/templates/lgproxy.cfg.j2 b/roles/service-bird-lg/templates/lgproxy.cfg.j2 index 028578a..0e18f52 100644 --- a/roles/service-bird-lg/templates/lgproxy.cfg.j2 +++ b/roles/service-bird-lg/templates/lgproxy.cfg.j2 @@ -3,10 +3,10 @@ DEBUG=False LOG_FILE="/var/log/bird-lg/lg-proxy.log" LOG_LEVEL="WARNING" -BIND_IP = "{{ bgp_ipv4_transfer_net | ipaddr('net') | ipaddr(magic) | ipaddr('ip') }}" +BIND_IP = "{{ loopback_net_ipv4 | ipsubnet(32, magic) | ipaddr('address') }}" BIND_PORT = 5000 -ACCESS_LIST = [ {% for host in groups["ffmwu-monitoring"] %}"{{ bgp_ipv4_transfer_net | ipaddr('net') | ipaddr(hostvars[host]['magic']) | ipaddr('ip') }}"{% if not loop.last %}, {% endif %}{% endfor %} ] +ACCESS_LIST = [ {% for host in groups["ffmwu-monitoring"] %}"{{ loopback_net_ipv4 | ipsubnet(32, hostvars[host]['magic']) | ipaddr('address') }}"{% if not loop.last %}, {% endif %}{% endfor %} ] # ??? IPV4_SOURCE = "10.207.0.37" diff --git a/roles/service-bird/meta/main.yml b/roles/service-bird/meta/main.yml new file mode 100644 index 0000000..884a904 --- /dev/null +++ b/roles/service-bird/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - wireguard diff --git a/roles/service-bird/templates/bird.conf.j2 b/roles/service-bird/templates/bird.conf.j2 index f559ec2..42d79b9 100644 --- a/roles/service-bird/templates/bird.conf.j2 +++ b/roles/service-bird/templates/bird.conf.j2 @@ -3,9 +3,9 @@ # # Variables -define mwu_address = {{ bgp_ipv4_transfer_net | ipaddr('net') | ipaddr(magic) | ipaddr('address') }}; +define mwu_address_legacy = {{ bgp_ipv4_transfer_net_legacy | ipaddr('net') | ipaddr(magic) | ipaddr('address') }}; define mwu_as = {{ as_private }}; -define router_id = {{ bgp_loopback_net | ipaddr('net') | ipaddr(magic) | ipaddr('address') }}; +define router_id = {{ loopback_net_ipv4 | ipaddr('net') | ipaddr(magic) | ipaddr('address') }}; # General timeformat protocol iso long; @@ -70,8 +70,13 @@ protocol device { }; protocol direct mwu_subnets { +{% if server_type == 'gateway' or server_type == 'monitoring' %} {% for mesh in meshes %} interface "{{ mesh.id }}br"; +{% endfor %} +{% endif %} +{% for network in my_wireguard_networks %} + interface "wg-{{ network.remote[:11] }}"; {% endfor %} import where is_mwu_self_nets_loose(); }; @@ -86,13 +91,13 @@ protocol direct mwu_anycast { interface "anycast"; import where is_mwu_anycast(); }; -{% endif %} protocol static { {% for prefix in internal_prefixes %} route {{ prefix.ipv4 }} reject; {% endfor %} }; +{% endif %} protocol kernel kernel_mwu { scan time 30; @@ -102,21 +107,26 @@ protocol kernel kernel_mwu { if is_mwu_anycast() then reject; {% else %} if is_mwu_anycast() then accept; + if is_freifunk() then accept; + if is_chaosvpn() then accept; + if is_dn42() then accept; {% endif %} if is_mwu_loopback() then accept; reject; }; + merge paths yes limit {{ groups['ffmwu-gateways'] | length }}; kernel table ipt_mwu; }; # Templates template bgp ibgp_mwu { - local mwu_address as mwu_as; + local as mwu_as; import keep filtered on; import filter { {% if server_type == "gateway" %} if is_mwu_anycast() then reject; {% endif %} + if is_mwu_loopback() then accept; if is_mwu_self_nets_loose() then accept; if is_freifunk() then accept; if is_chaosvpn() then accept; @@ -124,8 +134,13 @@ template bgp ibgp_mwu { reject; }; export filter { +{% if server_type == "gateway" %} + if is_mwu_loopback() then accept; if is_mwu_self_nets_loose() then accept; if source = RTS_BGP then accept; +{% else %} + if is_mwu_loopback() then accept; +{% endif %} reject; }; direct; diff --git a/roles/service-bird/templates/bird6.conf.j2 b/roles/service-bird/templates/bird6.conf.j2 index 73e7691..a4b0435 100644 --- a/roles/service-bird/templates/bird6.conf.j2 +++ b/roles/service-bird/templates/bird6.conf.j2 @@ -3,8 +3,8 @@ # # Variables -define router_id = {{ bgp_loopback_net | ipaddr('net') | ipaddr(magic) | ipaddr('address') }}; -define mwu_address = {{ bgp_ipv6_transfer_net | ipaddr('net') | ipaddr(magic) | ipaddr('address') }}; +define router_id = {{ loopback_net_ipv6 | ipaddr('net') | ipaddr(magic) | ipaddr('address') }}; +define mwu_address_legacy = {{ bgp_ipv6_transfer_net_legacy | ipaddr('net') | ipaddr(magic) | ipaddr('address') }}; define mwu_as = {{ as_private }}; # General @@ -58,8 +58,13 @@ protocol device { }; protocol direct mwu_subnets { +{% if server_type == 'gateway' or server_type == 'monitoring' %} {% for mesh in meshes %} interface "{{ mesh.id }}br"; +{% endfor %} +{% endif %} +{% for network in my_wireguard_networks %} + interface "wg-{{ network.remote[:11] }}"; {% endfor %} import where is_mwu_self_nets_loose(); }; @@ -74,13 +79,13 @@ protocol direct mwu_anycast { interface "anycast"; import where is_mwu_anycast(); }; -{% endif %} protocol static { {% for prefix in internal_prefixes %} route {{ prefix.ipv6 }} reject; {% endfor %} }; +{% endif %} protocol kernel kernel_mwu { scan time 30; @@ -90,16 +95,20 @@ protocol kernel kernel_mwu { if is_mwu_anycast() then reject; {% else %} if is_mwu_anycast() then accept; +{% endif %} +{% if server_type == "mesh-service" %} + if is_ula() then accept; {% endif %} if is_mwu_loopback() then accept; reject; }; + merge paths yes limit {{ groups['ffmwu-gateways'] | length }}; kernel table ipt_mwu; }; # Templates template bgp ibgp_mwu { - local mwu_address as mwu_as; + local as mwu_as; import keep filtered on; import filter { {% if server_type == "gateway" %} @@ -110,8 +119,12 @@ template bgp ibgp_mwu { reject; }; export filter { +{% if server_type == "gateway" %} if is_mwu_self_nets_loose() then accept; if source = RTS_BGP then accept; +{% else %} + if is_mwu_loopback() then accept; +{% endif %} reject; }; direct; diff --git a/roles/service-bird/templates/mwu_ipv4_peers.conf.j2 b/roles/service-bird/templates/mwu_ipv4_peers.conf.j2 index 59c5af8..c3e149d 100644 --- a/roles/service-bird/templates/mwu_ipv4_peers.conf.j2 +++ b/roles/service-bird/templates/mwu_ipv4_peers.conf.j2 @@ -2,21 +2,27 @@ # {{ ansible_managed }} # -{% for group in bgp_groups %} -{% for host in groups[group] %} -{% if host != inventory_hostname %} -protocol bgp mwu_{{ host.rsplit('.freifunk-mwu.de')[0] }} from ibgp_mwu { - neighbor {{ bgp_ipv4_transfer_net | ipaddr('net') | ipaddr(hostvars[host]['magic']) | ipaddr('ip') }} as mwu_as; +{% for network in my_wireguard_networks %} +protocol bgp mwu_{{ network.remote }} from ibgp_mwu { +{% if magic < network.remote_magic %} + source address {{ network.ipv4 | ipaddr('address') }}; + neighbor {{ network.ipv4 | ipaddr('1') | ipaddr('address') }} as mwu_as; +{% else %} + source address {{ network.ipv4 | ipaddr('1') | ipaddr('address') }}; + neighbor {{ network.ipv4 | ipaddr('address') }} as mwu_as; +{% endif %} }; -{% endif %} -{% endfor %} {% endfor %} + +{% if server_type == 'gateway' %} {% for item, value in bgp_legacy_servers.items() %} {% if item != inventory_hostname_short %} -protocol bgp mwu_{{ item }} from ibgp_mwu { +protocol bgp mwu_{{ item }}_legacy from ibgp_mwu { + source address mwu_address_legacy; neighbor {{ value.ipv4 }} as mwu_as; }; {% endif %} {% endfor %} +{% endif %} diff --git a/roles/service-bird/templates/mwu_ipv6_peers.conf.j2 b/roles/service-bird/templates/mwu_ipv6_peers.conf.j2 index 4420e1a..1f5d9b1 100644 --- a/roles/service-bird/templates/mwu_ipv6_peers.conf.j2 +++ b/roles/service-bird/templates/mwu_ipv6_peers.conf.j2 @@ -2,21 +2,27 @@ # {{ ansible_managed }} # -{% for group in bgp_groups %} -{% for host in groups[group] %} -{% if host != inventory_hostname %} -protocol bgp mwu_{{ host.rsplit('.freifunk-mwu.de')[0] }} from ibgp_mwu { - neighbor {{ bgp_ipv6_transfer_net | ipaddr('net') | ipsubnet(64, 0) | ipaddr(hostvars[host]['magic']) | ipaddr('ip') }} as mwu_as; +{% for network in my_wireguard_networks %} +protocol bgp mwu_{{ network.remote }} from ibgp_mwu { +{% if magic < network.remote_magic %} + source address {{ network.ipv6 | ipaddr('network') }}; + neighbor {{ network.ipv6 | ipaddr('1') | ipaddr('address') }} as mwu_as; +{% else %} + source address {{ network.ipv6 | ipaddr('1') | ipaddr('address') }}; + neighbor {{ network.ipv6 | ipaddr('network') }} as mwu_as; +{% endif %} }; -{% endif %} -{% endfor %} {% endfor %} + +{% if server_type == 'gateway' %} {% for item, value in bgp_legacy_servers.items() %} {% if item != inventory_hostname_short %} protocol bgp mwu_{{ item }} from ibgp_mwu { + source address mwu_address_legacy; neighbor {{ value.ipv6 }} as mwu_as; }; {% endif %} {% endfor %} +{% endif %} diff --git a/roles/wireguard/defaults/main.yml b/roles/wireguard/defaults/main.yml new file mode 100644 index 0000000..aef116a --- /dev/null +++ b/roles/wireguard/defaults/main.yml @@ -0,0 +1,6 @@ +--- +# All WireGuard networks +wireguard_networks: [] + +# WireGuard networks for specific host, will be filtered automatically +my_wireguard_networks: [] diff --git a/roles/wireguard/handlers/main.yml b/roles/wireguard/handlers/main.yml new file mode 100644 index 0000000..191d07d --- /dev/null +++ b/roles/wireguard/handlers/main.yml @@ -0,0 +1,5 @@ +--- +- name: reload network interfaces + systemd: + name: networking + state: reloaded diff --git a/roles/wireguard/tasks/main.yml b/roles/wireguard/tasks/main.yml new file mode 100644 index 0000000..c60c6c5 --- /dev/null +++ b/roles/wireguard/tasks/main.yml @@ -0,0 +1,80 @@ +--- +- name: Gather my own WireGuard networks. + set_fact: + my_wireguard_networks: "{% set _my_nets = [] %}{% for net in wireguard_networks %}{% if inventory_hostname_short in net.peers %}{% do _my_nets.append(net) %}{% set remote = net.peers | reject('equalto', inventory_hostname_short) | list () | first %}{% set remote_hostname = remote + '.freifunk-mwu.de' %}{% set remote_magic = hostvars[remote_hostname]['magic'] %}{% do net.update({'remote': remote, 'remote_hostname': remote_hostname, 'remote_magic': remote_magic}) %}{% endif %}{% endfor %}{{ _my_nets }}" + +- name: Set unstable pin priority. + blockinfile: + dest: "/etc/apt/preferences.d/limit-unstable" + block: | + Package: * + Pin: release a=unstable + Pin-Priority: -10 + create: True + owner: "root" + group: "root" + mode: "0644" + +- name: Raise WireGuard pin priority. + blockinfile: + dest: "/etc/apt/preferences.d/wireguard" + block: | + Package: wireguard* + Pin: release a=unstable + Pin-Priority: 500 + create: "true" + owner: "root" + group: "root" + mode: "0644" + +- name: Add Debian unstable repository. + apt_repository: + repo: "deb http://deb.debian.org/debian/ unstable main" + state: "present" + filename: "unstable" + update_cache: True + +- name: Install WireGuard packages. + package: + name: "{{ wireguard_packages }}" + state: "present" + +- name: Ensure WireGuard directory exists. + file: + path: "/etc/wireguard" + state: "directory" + owner: "root" + group: "root" + mode: "0640" + +- name: Register the WireGuard public + private key. + set_fact: + wireguard_public_key: "{{ lookup('passwordstore', 'wireguard/' + inventory_hostname_short + ' subkey=public') }}" + wireguard_private_key: "{{ lookup('passwordstore', 'wireguard/' + inventory_hostname_short + ' subkey=private') }}" + no_log: True + +- name: Write the WireGuard private key. + copy: + content: "{{ wireguard_private_key }}" + dest: "/etc/wireguard/wg.priv" + owner: "root" + group: "root" + mode: "0600" + +- name: Write the WireGuard config. + template: + src: "wg.conf.j2" + dest: "/etc/wireguard/wg-{{ item.remote[:11] }}.conf" + owner: root + group: root + mode: 0640 + loop: "{{ my_wireguard_networks }}" + +- name: Configure the WireGuard interface config. + template: + src: "wireguard.j2" + dest: "/etc/network/interfaces.d/wireguard" + owner: "root" + group: "root" + mode: "0644" + notify: reload network interfaces diff --git a/roles/wireguard/templates/wg.conf.j2 b/roles/wireguard/templates/wg.conf.j2 new file mode 100644 index 0000000..5c51794 --- /dev/null +++ b/roles/wireguard/templates/wg.conf.j2 @@ -0,0 +1,12 @@ +# {{ ansible_managed }} +# +# {{ inventory_hostname }} wg_{{ item.remote[:13] }} configuration +# +[Interface] +PrivateKey = {{ wireguard_private_key }} +ListenPort = {{ item.port }} + +[Peer] +Endpoint = {{ item.remote_hostname }}:{{ item.port }} +PublicKey = {{ lookup('passwordstore', 'wireguard/' + item.remote + ' subkey=public') }} +AllowedIPs = 0.0.0.0/0,::/0 diff --git a/roles/wireguard/templates/wireguard.j2 b/roles/wireguard/templates/wireguard.j2 new file mode 100644 index 0000000..acd86c1 --- /dev/null +++ b/roles/wireguard/templates/wireguard.j2 @@ -0,0 +1,19 @@ +# +# {{ ansible_managed }} +# +{% for network in my_wireguard_networks %} +auto wg-{{ network.remote[:11] }} +iface wg-{{ network.remote[:11] }} +{% if magic < network.remote_magic %} + address {{ network.ipv4 | ipaddr('ip/prefix') }} + address {{ network.ipv6 | ipaddr('ip/prefix') }} +{% else %} + address {{ network.ipv4 | ipaddr('1') | ipaddr('ip/prefix') }} + address {{ network.ipv6 | ipaddr('1') | ipaddr('ip/prefix') }} +{% endif %} + pre-up ip link add dev $IFACE type wireguard + pre-up wg setconf $IFACE /etc/wireguard/$IFACE.conf + post-up ip link set up dev $IFACE + post-down ip link del $IFACE + +{% endfor %} diff --git a/roles/wireguard/vars/main.yml b/roles/wireguard/vars/main.yml new file mode 100644 index 0000000..f310b43 --- /dev/null +++ b/roles/wireguard/vars/main.yml @@ -0,0 +1,5 @@ +--- +wireguard_packages: + - wireguard-dkms + - wireguard-tools + - linux-headers-{{ ansible_kernel }}