diff --git a/inventory/group_vars/all b/inventory/group_vars/all index a7b254f..effbd11 100644 --- a/inventory/group_vars/all +++ b/inventory/group_vars/all @@ -10,6 +10,8 @@ routing_tables: icvpn_ipv4_network: 10.207.0.0/16 mwu_icvpn_ipv4_network: 10.207.37.0/24 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 meshes: mz: diff --git a/playbooks/gateways.yml b/playbooks/gateways.yml index 8642784..d22c61f 100755 --- a/playbooks/gateways.yml +++ b/playbooks/gateways.yml @@ -19,4 +19,5 @@ - git-fastd-peers - network-fastd - network-ffrl + - service-bird - service-rclocal diff --git a/roles/service-bird/README.md b/roles/service-bird/README.md new file mode 100644 index 0000000..249e4c2 --- /dev/null +++ b/roles/service-bird/README.md @@ -0,0 +1,36 @@ +# Ansible role service-bird + +Diese Ansible role installiert und konfiguriert den bird daemon. + +- installiert bird +- aktiviert systemd units bird + bird6 +- schreibt bird.conf + bird6.conf +- konfiguriert bird für iBGP mit allen anderen FFMWU-Servern + +Im iBGP peeren wir mangels separatem Transfernetz (im Moment) im Mainzer Mesh Netz. + +## Benötigte Variablen + +- Variable `bgp_loopback_net` # IPv4-Range des Mainzer Meshes, hieraus werden die Loopback Adressen gewählt. +- Variable `bgp_ipv4_transfer_net` # IPv4-Range des Mainzer Meshes, das aktuell als Transfernetz benutzt wird. +- Variable `bgp_ipv6_transfer_net` # IPv6-Range des Mainzer Meshes, das aktuell als Transfernetz benutzt wird. +- Variable `bgp_as_private_mwu` # Private ASN von Freifunk MWU +- Dictionary `bgp_mwu_servers` +``` + spinat: # kurzer Hostname des Peers + ipv4: 10.37.0.7 # IPv4-Adresse des Peers + ipv6: fd37:b4dc:4b1e::a25:7 # IPv6-Adresse des Peers +... + +``` +- Dictionary `meshes` +´´´ +meshes: + xx: +... + ipv4_network: + ipv6: + ula: + - # IPv6-ULA Network +´´´ +- Host Variable `magic` diff --git a/roles/service-bird/handlers/main.yml b/roles/service-bird/handlers/main.yml new file mode 100644 index 0000000..15478b4 --- /dev/null +++ b/roles/service-bird/handlers/main.yml @@ -0,0 +1,17 @@ +--- +- name: reload systemd + systemd: + daemon_reload: yes + become: true + +- name: reload bird + systemd: + name: bird + state: reloaded + become: true + +- name: reload bird6 + systemd: + name: bird6 + state: reloaded + become: true diff --git a/roles/service-bird/tasks/main.yml b/roles/service-bird/tasks/main.yml new file mode 100644 index 0000000..152a1ee --- /dev/null +++ b/roles/service-bird/tasks/main.yml @@ -0,0 +1,46 @@ +--- +- name: install bird packages + apt: + name: "{{ item }}" + state: present + notify: reload systemd + with_items: + - bird-bgp + - bird-doc + become: true + +- name: write bird configuration + template: + src: bird{{ item }}.conf.j2 + dest: /etc/bird/bird{{ item }}.conf + mode: 0640 + owner: bird + group: bird + notify: reload bird{{ item }} + with_items: + - "" + - 6 + become: true + +- name: configure mwu peers + template: + src: mwu_ipv{{ item }}_peers.conf.j2 + dest: /etc/bird/mwu_ipv{{ item }}_peers.conf + mode: 0640 + owner: bird + group: bird + notify: reload bird{{ item }} + with_items: + - 4 + - 6 + become: true + +- name: enable + start systemd units bird + bird6 + systemd: + name: bird{{ item }} + enabled: yes + state: started + with_items: + - "" + - 6 + become: true diff --git a/roles/service-bird/templates/bird.conf.j2 b/roles/service-bird/templates/bird.conf.j2 new file mode 100644 index 0000000..304080a --- /dev/null +++ b/roles/service-bird/templates/bird.conf.j2 @@ -0,0 +1,76 @@ +# +# {{ ansible_managed }} +# + +# Variables +define mwu_address = {{ bgp_ipv4_transfer_net | ipaddr('net') | ipaddr(magic) | ipaddr('address') }}; +define mwu_as = {{ as_private_mwu }}; +define router_id = {{ bgp_loopback_net | ipaddr('net') | ipaddr(magic) | ipaddr('address') }}; + +# General +timeformat protocol iso long; +router id router_id; + +# Functions +function is_default() { + return net ~ [ + 0.0.0.0/0 + ]; +} + +function is_freifunk() { + return net ~ [ + 10.0.0.0/8{16,24} + ]; +} + +function is_dn42() { + return net ~ [ + 172.20.0.0/14{20,28} + ]; +} + +function is_chaosvpn() { + return net ~ [ + 172.31.0.0/16+ + ]; +} + +function is_mwu_self_nets() { + return net ~ [ +{% for item, value in meshes.iteritems() %} + {{ value.ipv4_network | ipaddr('net') }}+{{ "," if not loop.last else "" }} +{% endfor %} + ]; +} + +# Protocols +protocol device { + scan time 30; +}; + +protocol direct mwu_subnets { +{% for item, value in meshes.iteritems() %} + interface "{{ item }}BR"; +{% endfor %} + import where is_mwu_self_nets(); +}; + +# Templates +template bgp ibgp_mwu { + local mwu_address as mwu_as; + import keep filtered on; + import all; + export where source = RTS_BGP; + direct; + gateway direct; +}; + +# Include IPv4 MWU peers +include "mwu_ipv4_peers.con?"; + +# Include IPv4 ICVPN configuration +include "icvpn_ipv4.con?"; + +# Include IPv4 FFRL configuration +include "ffrl_ipv4.con?"; diff --git a/roles/service-bird/templates/bird6.conf.j2 b/roles/service-bird/templates/bird6.conf.j2 new file mode 100644 index 0000000..baebabb --- /dev/null +++ b/roles/service-bird/templates/bird6.conf.j2 @@ -0,0 +1,65 @@ +# +# {{ ansible_managed }} +# + +# 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 mwu_as = {{ as_private_mwu }}; + +# General +timeformat protocol iso long; +router id router_id; + +# Functions +function is_default() { + return net ~ [ + ::/0 + ]; +} + +function is_ula() { + return net ~ [ + fc00::/7{48,64} + ]; +} + +function is_mwu_self_nets() { + return net ~ [ +{% for item, value in meshes.iteritems() %} +{% for ula in value.ipv6.ula %} + {{ ula | ipaddr('net') }}+{{ "," if not loop.last else "" }}{% endfor %}{{ "," if not loop.last else "" }} +{% endfor %} + ]; +} + +# Protocols +protocol device { + scan time 30; +}; + +protocol direct mwu_subnets { +{% for item, value in meshes.iteritems() %} + interface "{{ item }}BR"; +{% endfor %} + import where is_mwu_self_nets(); +}; + +# Templates +template bgp ibgp_mwu { + local mwu_address as mwu_as; + import keep filtered on; + import all; + export where source = RTS_BGP; + direct; + gateway direct; +}; + +# Include IPv6 MWU peers +include "mwu_ipv6_peers.con?"; + +# Include IPv6 ICVPN configuration +include "icvpn_ipv6.con?"; + +# Include IPv6 FFRL configuration +include "ffrl_ipv6.con?"; diff --git a/roles/service-bird/templates/mwu_ipv4_peers.conf.j2 b/roles/service-bird/templates/mwu_ipv4_peers.conf.j2 new file mode 100644 index 0000000..153c36a --- /dev/null +++ b/roles/service-bird/templates/mwu_ipv4_peers.conf.j2 @@ -0,0 +1,12 @@ +# +# {{ ansible_managed }} +# + +{% for item, value in bgp_mwu_servers.iteritems() %} +{% if item != inventory_hostname_short %} +protocol bgp mwu_{{ item }} from ibgp_mwu { + neighbor {{ value.ipv4 }} as mwu_as; +}; +{% endif %} + +{% endfor %} diff --git a/roles/service-bird/templates/mwu_ipv6_peers.conf.j2 b/roles/service-bird/templates/mwu_ipv6_peers.conf.j2 new file mode 100644 index 0000000..59051ff --- /dev/null +++ b/roles/service-bird/templates/mwu_ipv6_peers.conf.j2 @@ -0,0 +1,12 @@ +# +# {{ ansible_managed }} +# + +{% for item, value in bgp_mwu_servers.iteritems() %} +{% if item != inventory_hostname_short %} +protocol bgp mwu_{{ item }} from ibgp_mwu { + neighbor {{ value.ipv6 }} as mwu_as; +}; +{% endif %} + +{% endfor %}