diff --git a/inventory/group_vars/all b/inventory/group_vars/all index bc72b66..3c0a1b6 100644 --- a/inventory/group_vars/all +++ b/inventory/group_vars/all @@ -58,6 +58,11 @@ meshes: peers_mesh_repo: https://github.com/freifunk-mwu/peers-ffwi.git peers_intragate_repo: https://github.com/freifunk-mwu/ffwi-infrastructure-peers.git +icvpn: + prefix: mwu + interface: icVPN + icvpn_repo: https://github.com/freifunk/icvpn + bgp_mwu_servers: spinat: ipv4: 10.37.0.7 diff --git a/playbooks/gateways.yml b/playbooks/gateways.yml index 584ee41..b9dc606 100755 --- a/playbooks/gateways.yml +++ b/playbooks/gateways.yml @@ -20,6 +20,7 @@ - git-fastd-peers - network-fastd - network-ffrl + - service-tinc - service-bird - service-bird-icvpn - service-bird-ffrl diff --git a/roles/service-bird-icvpn/meta/main.yml b/roles/service-bird-icvpn/meta/main.yml index ad1a852..0c405d4 100644 --- a/roles/service-bird-icvpn/meta/main.yml +++ b/roles/service-bird-icvpn/meta/main.yml @@ -1,4 +1,5 @@ --- dependencies: - { role: git-repos } + - { role: service-tinc } - { role: service-bird } diff --git a/roles/service-tinc/README.md b/roles/service-tinc/README.md new file mode 100644 index 0000000..f2ad562 --- /dev/null +++ b/roles/service-tinc/README.md @@ -0,0 +1,45 @@ +# Ansible role service-tinc + +Diese Ansible role installiert und konfiguriert den tinc daemon, der für die Verbindung in das InterCity-VPN benötigt wird. + +- installiert tinc +- erzeugt icVPN tinc Instanz + - klont freifunk/icvpn repo + - schreibt tinc.conf + - schreibt tinc-up hook script + - schreibt tinc-down hook script + - liest tinc private key aus dem pass + +## Benötigte Variablen + +- Dictionary `icvpn` +``` +icvpn: + prefix: mwu + interface: icVPN + icvpn_repo: https://github.com/freifunk/icvpn +``` +- Variable `icvpn_ipv4_transfer_net` +- Variable `icvpn_ipv6_transfer_net` +- Dictionary `routing_tables` +``` +routing_tables: + icvpn: 23 + ... +``` +- Host Variable `magic` +- Host Variable `tinc_private_key` +``` +tinc_private_key: "{{ lookup('passwordstore', 'tinc/icVPN/$Hostname_private returnall=true') }}" +``` + +## tinc private key + +Der private Schlüssel der icVPN tinc-Instanz liegt im passwordstore. +Bevor man ein Gateway aufsetzt, muss der private Schlüssel generiert und im passwordstore hinterlegt werden. +Die Variable `tinc_private_key` folgt dem Aufbau: +``` +tinc_private_key: + $Instanz-Name: "{{ lookup('passwordstore', '$Pfad-im-passwordstore returnall=true') }}" +``` + diff --git a/roles/service-tinc/handlers/main.yml b/roles/service-tinc/handlers/main.yml new file mode 100644 index 0000000..b88ce92 --- /dev/null +++ b/roles/service-tinc/handlers/main.yml @@ -0,0 +1,12 @@ +--- +- name: configure systemd unit tinc + systemd: + name: tinc + enabled: yes + daemon_reload: yes + +- name: restart systemd unit tinc + systemd: + name: tinc + enabled: yes + state: restarted diff --git a/roles/service-tinc/tasks/main.yml b/roles/service-tinc/tasks/main.yml new file mode 100644 index 0000000..994f480 --- /dev/null +++ b/roles/service-tinc/tasks/main.yml @@ -0,0 +1,72 @@ +--- +- name: install tinc packages + apt: + name: "{{ item }}" + state: present + with_items: + - tinc + notify: configure systemd unit tinc + +- name: clone icvpn repo + git: + repo: "{{ icvpn.icvpn_repo }}" + dest: /etc/tinc/{{ icvpn.interface }} + update: no + +- name: set directory permissions + file: + path: /etc/tinc/{{ icvpn.interface }} + state: directory + owner: admin + group: admin + recurse: yes + +- name: register metanodes + command: cat /etc/tinc/{{ icvpn.interface }}/metanodes + register: metanodes + changed_when: false + +- name: write tinc.conf + template: + src: tinc.conf.j2 + dest: /etc/tinc/{{ icvpn.interface }}/tinc.conf + mode: 0664 + owner: admin + group: admin + notify: restart systemd unit tinc + +- name: write tinc-up hook script + template: + src: tinc-up.j2 + dest: /etc/tinc/{{ icvpn.interface }}/tinc-up + mode: 0775 + owner: admin + group: admin + notify: restart systemd unit tinc + +- name: write tinc-down hook script + template: + src: tinc-down.j2 + dest: /etc/tinc/{{ icvpn.interface }}/tinc-down + mode: 0775 + owner: admin + group: admin + notify: restart systemd unit tinc + +- name: write tinc private key + template: + src: rsa_key.priv.j2 + dest: /etc/tinc/{{ icvpn.interface }}/rsa_key.priv + mode: 0600 + owner: admin + group: admin + notify: restart systemd unit tinc + +- name: write nets.boot + template: + src: nets.boot.j2 + dest: /etc/tinc/nets.boot + mode: 0644 + owner: root + group: root + notify: restart systemd unit tinc diff --git a/roles/service-tinc/templates/nets.boot.j2 b/roles/service-tinc/templates/nets.boot.j2 new file mode 100644 index 0000000..5e4cdf7 --- /dev/null +++ b/roles/service-tinc/templates/nets.boot.j2 @@ -0,0 +1,5 @@ +# +# {{ ansible_managed }} +# +# This file contains all names of the networks to be started on system startup. +{{ icvpn.interface }} diff --git a/roles/service-tinc/templates/rsa_key.priv.j2 b/roles/service-tinc/templates/rsa_key.priv.j2 new file mode 100644 index 0000000..7c952bc --- /dev/null +++ b/roles/service-tinc/templates/rsa_key.priv.j2 @@ -0,0 +1 @@ +{{ tinc_private_key }} diff --git a/roles/service-tinc/templates/tinc-down.j2 b/roles/service-tinc/templates/tinc-down.j2 new file mode 100644 index 0000000..f0a44b0 --- /dev/null +++ b/roles/service-tinc/templates/tinc-down.j2 @@ -0,0 +1,11 @@ +#!/bin/sh +# +# {{ ansible_managed }} +# +/sbin/ip addr del dev ${INTERFACE} {{ icvpn_ipv4_transfer_net | ipaddr('net') | ipsubnet(24, 37) | ipaddr(magic) | ipaddr('address') }}/16 broadcast {{ icvpn_ipv4_transfer_net | ipaddr('net') | ipaddr('broadcast') }} +/sbin/ip -6 addr del dev ${INTERFACE} {{ icvpn_ipv6_transfer_net | ipaddr('net') | ipsubnet(112, 37) | ipaddr(magic) | ipaddr('address') }}/96 + +/sbin/ip -4 route del {{ icvpn_ipv4_transfer_net }} proto static dev ${INTERFACE} table {{ routing_tables.icvpn }} +/sbin/ip -6 route del {{ icvpn_ipv6_transfer_net }} proto static dev ${INTERFACE} table {{ routing_tables.icvpn }} + +/sbin/ip link set dev ${INTERFACE} down diff --git a/roles/service-tinc/templates/tinc-up.j2 b/roles/service-tinc/templates/tinc-up.j2 new file mode 100644 index 0000000..5fb6692 --- /dev/null +++ b/roles/service-tinc/templates/tinc-up.j2 @@ -0,0 +1,14 @@ +{% set ip4hex = icvpn_ipv4_transfer_net | ipaddr('net') | ipsubnet(24, 37) | ipaddr(magic) | ipaddr('address') | ip4_hex() -%} +{% set mac = '0220' + ip4hex -%} +#!/bin/sh +# +# {{ ansible_managed }} +# +/sbin/ifconfig ${INTERFACE} hw ether {{ mac | hwaddr('linux') }} +/sbin/ip link set dev ${INTERFACE} up + +/sbin/ip -4 route add {{ icvpn_ipv4_transfer_net }} proto static dev ${INTERFACE} table {{ routing_tables.icvpn }} +/sbin/ip -6 route add {{ icvpn_ipv6_transfer_net }} proto static dev ${INTERFACE} table {{ routing_tables.icvpn }} + +/sbin/ip addr add dev ${INTERFACE} {{ icvpn_ipv4_transfer_net | ipaddr('net') | ipsubnet(24, 37) | ipaddr(magic) | ipaddr('address') }}/16 broadcast {{ icvpn_ipv4_transfer_net | ipaddr('net') | ipaddr('broadcast') }} scope link +/sbin/ip -6 addr add dev ${INTERFACE} {{ icvpn_ipv6_transfer_net | ipaddr('net') | ipsubnet(112, 37) | ipaddr(magic) | ipaddr('address') }}/96 preferred_lft 0 diff --git a/roles/service-tinc/templates/tinc.conf.j2 b/roles/service-tinc/templates/tinc.conf.j2 new file mode 100644 index 0000000..15f2e96 --- /dev/null +++ b/roles/service-tinc/templates/tinc.conf.j2 @@ -0,0 +1,12 @@ +Name = {{ icvpn.prefix }}{{ magic }} +PrivateKeyFile = /etc/tinc/{{ icvpn.interface }}/rsa_key.priv +Mode = Switch +PingTimeout = 30 +Port = 10655 +Hostnames = yes +GraphDumpFile = /etc/tinc/{{ icvpn.interface }}/topo.dot +Interface = {{ icvpn.interface }} + +{% for metanode in metanodes.stdout_lines %} +ConnectTo = {{ metanode }} +{% endfor %}