Add a bunch of new roles

- Update Readme
- Update ansible.cfg
- Add playbook to set up gateways
- Add group variables
This commit is contained in:
Tobias Hachmer 2017-09-05 12:01:27 +02:00
parent 1f0b5925a8
commit 94cb21daad
40 changed files with 860 additions and 26 deletions

146
Readme.md
View file

@ -1,40 +1,138 @@
# ansible-ffmwu.git
# Ansible Freifunk MWU
An dieser Stelle soll der ganze ansible-script-junk entstehen, um ein FFMWU-Gateway automagisiert aufzusetzen. Das Geraffel kann später auch auf andere server-Typen erweitert werden, wenn sinnvoll.
Ein server muss minimal vorbereitet sein, bevor er mit den hiesigen Skripten zum Gate (oder zu Sonstigem) gemacht werden kann. Insbesondere müssen die folgenden Voraussetzungen erfüllt sein (diese werden vom playbook `test-prerequisites.yml` getestet):
Wir, die Freifunk MWU Community, nutzen Ansible um unsere Freifunk Server aufzusetzen und zu konfigurieren. In
diesem Repository verwalten wir unsere Ansible Roles und Playbooks.
Ein Server muss minimal vorbereitet sein, bevor dieser per Ansible z.B. zu einem Freifunk-Gateway gemacht werden kann. Insbesondere müssen die folgenden Voraussetzungen erfüllt sein (diese werden vom playbook `playbook-test-prereqs.yml` getestet):
- Ein dedizierter (v)server muss existieren und unter einer IPv4- und einer IPv6-Adresse öffentlich erreichbar sein.
- Die Adressen sollen im MWU-DNS eingetragen sein.
- Es muss eine nakte unterstützte linux-Version aufgesetzt sein (aktuell Ubuntu 14.04, bald Debian).
- Es muss einen user admin geben, auf den die Admins Zugriff haben; dieser muss root-Zugang über sudo haben.
- Die Adressen müssen im MWU-DNS eingetragen sein.
- Als Betriebssystem muss das aktuelle Debian Stable installiert sein.
- Es muss einen User admin geben, auf den die Admins Zugriff haben; dieser muss Root-Zugang über sudo haben.
Zusätzlich ist sehr empfehlenswert, dass die Admins die Maschinen mit ihren fqdns in ihrer ssh-config definiert haben.
Die Server werden mit ihren FQDNs im Ansible Inventory hinterlegt, bedenkt das für eure ssh-config.
Bisher gibt es hier zwei Sammlungen von files: zum Einen der Beginn des eigentlichen Zwecks: bisher kann eine Rolle (auf Basis der obigen Voraussetzungen) alle FFMWU-Server in dem ihnen allen identischen Aspekt vorbereiten, der Pflege der ssh keys der admins. Zum Anderen gibt es ein playbook, das eine lokale Test-VM aufsetzt, auf der man alle eigentlichen playbooks und Rollen testen kann, ohne ernsthaften Schaden anzurichten.
## Variablen für jedes Mesh
## Aufsetzen und Pflegen von Gateways
Viele Rollen brauchen spezifische Informationen, wie IP-Adresse, Masken, Interface-Namen, etc.
Wir verwalten diese Mesh-Informationen in einem Dictionary unter `inventory/group_vars/all`:
Alle FFMWU-Gatways sind auch FFMWU-Server, alle anderen server bei uns überraschenderweise auch; so sind auch Alle im inventory in der Gruppe 'ff-servers' zusammengefasst. Der Aspekt, der allen FFMWU-Servern gemein ist, sind die ssh-keys der admins. Auf einigen servern gibt es allerdings weitere Zugriffsberechtigte (spezialisierte admins).
```
meshes:
mz:
site_number: 37
site_code: ffmz
site_name: Mainz
ipv4_network: 10.37.0.0/18
ipv6:
ula:
- fd37:b4dc:4b1e::/48
public:
- 2a03:2260:11a::/48
dnssl:
- ffmz.org
- user.ffmz.org
batman:
it: 10000
gw: server 96mbit/96mbit
mm: 0
dat: 0
iface_mtu: 1350
peers_mesh_repo: https://github.com/freifunk-mwu/peers-ffmz.git
peers_intragate_repo: https://github.com/freifunk-mwu/ffmz-infrastructure-peers.git
So gibt es eine Rolle ('ffmwu-server'), die allen hosts dieser Gruppe zugewiesen ist (über das playbook 'ffmwu-servers.yml', später auch über Abhängigkeiten der speziellern playbooks). Dieses playbook (einfach starten) weist die Rolle zu, welche ihrerseits die shh keys auf den hosts pflegt.
wi:
site_number: 56
site_code: ffwi
site_name: Wiesbaden
ipv4_network: 10.56.0.0/18
ipv6:
ula:
- fd56:b4dc:4b1e::/48
public:
- 2a03:2260:11b::/48
dnssl:
- ffwi.org
- user.ffwi.org
batman:
it: 10000
gw: server 96mbit/96mbit
mm: 0
dat: 0
iface_mtu: 1350
peers_mesh_repo: https://github.com/freifunk-mwu/peers-ffwi.git
peers_intragate_repo: https://github.com/freifunk-mwu/ffwi-infrastructure-peers.git
```
Die Rolle besteht aus nur einem task und einer definierten Variable, die die keys der admins enthält. Sind auf einem host weitere ssh keys von Nöten, so werden disse als hostvar definiert.
## Erzeugen einer test-VM
## Aufsetzen eines neuen Gateways
Um die playbooks und Rollen gefahrlos testen zu können, bietet sich ein test host an. Hierfür kann eine lokale VM zu Einsatz kommen, wenn die Voraussetzungen stimmen.
- FQDN im Inventory zur Gruppe ffmwu-gateways hinzufügen
- Host-Variablen setzen
- inventory/host_vars/$FQDN
Damit auf der lokalen Maschine (der ansible controle machine) VMs ablaufen (und mit dem playbook angelegt werden) können, müssen verschiedene Voraussetzungen erfüllt sein. U. a.:
```
---
# Gateway-Nummer, von der vieles abgeleitet wird. Integer zwischen 1-254. Muss eindeutig unter allen FFMWU Servern sein.
magic:
- installierte Pakete zu libvirt, kvm und qemu und Pakete virt-manager, isomaster
- >15G freier Plattenplatz
- ansible >= 2.1
# Pfade zu den fastd secrets im passwordstore
fastd_secrets:
mzVPN: "{{ lookup('passwordstore', 'fastd/mzVPN/$Hostname') }}"
wiVPN: "{{ lookup('passwordstore', 'fastd/wiVPN/$Hostname') }}"
mzigVPN: "{{ lookup('passwordstore', 'fastd/mzVPN/$Hostname') }}"
wiigVPN: "{{ lookup('passwordstore', 'fastd/wiVPN/$Hostname') }}"
Leider sind die letzten 2 Meter der Aufgabe offenbar in dieser Art nicht automatisierbar. Deshalb muss der user an einer Stelle mit 'isomaster' kurz etwas manuell durchführen
Das playbook 'loctevm-reset.yml' einfach ausführen.
# FFRL (muss vorher bereits zugewiesen worden sein)
# Öffentliche IPv4 NAT Adresse
ffrl_public_ipv4_nat:
### bekannte Probleme
ffrl_exit_server:
ffrl-a-ak-ber:
public_ipv4_address:
tunnel_ipv4_network: # Format: IP/Maske
tunnel_ipv4_address:
tunnel_ipv4_netmask:
tunnel_ipv6_address:
tunnel_ipv6_netmask:
ffrl-b-ak-ber:
public_ipv4_address:
tunnel_ipv4_network: # Format: IP/Maske
tunnel_ipv4_address:
tunnel_ipv4_netmask:
tunnel_ipv6_address:
tunnel_ipv6_netmask:
ffrl-a-ix-dus:
public_ipv4_address:
tunnel_ipv4_network: # Format: IP/Maske
tunnel_ipv4_address:
tunnel_ipv4_netmask:
tunnel_ipv6_address:
tunnel_ipv6_netmask:
ffrl-b-ix-dus:
public_ipv4_address:
tunnel_ipv4_network: # Format: IP/Maske
tunnel_ipv4_address:
tunnel_ipv4_netmask:
tunnel_ipv6_address:
tunnel_ipv6_netmask:
ffrl-a-fra2-fra:
public_ipv4_address:
tunnel_ipv4_network: # Format: IP/Maske
tunnel_ipv4_address:
tunnel_ipv4_netmask:
tunnel_ipv6_address:
tunnel_ipv6_netmask:
ffrl-b-fra2-fra:
public_ipv4_address:
tunnel_ipv4_network: # Format: IP/Maske
tunnel_ipv4_address:
tunnel_ipv4_netmask:
tunnel_ipv6_address:
tunnel_ipv6_netmask:
- Wenn die VM wegen Zugriffsfehler auf die virtuellen volumes nicht startet, können die Berechtigungen der übergeordneten Verzeichnisse Schuld sein -> hier mal schauen.
- Ein Schritt scheint nicht automagisierbar, hier werden isomaster & der user benötigt.
- Bisher wird direkt die 64bit-Version ausgewählt.
```
- Testen, ob alle Voraussetzungen erfüllt sind: `ansible-playbook playbook-test-prerequisites.yml`
- Neues Gateway aufsetzen per `ansible-playbook playbook-gateways.yml`
- Hierbei werden die definierten Rollen auch auf schon aufgesetzte Gateways angewandt, was unkritisch ist, weil wir unsere Rollen idempotent schreiben.
- Um die Rollen nur auf das neu aufzusetzende Gateway anzuwenden: `ansible-playbook playbook-gateways.yml --limit=$FQDN`

View file

@ -1,10 +1,9 @@
[defaults]
# local
inventory = ./inventory/hosts
retry_files_save_path = ~/.ansible/retry-files
#vault_password_file = ~/.ansible/vault-password-file
# remote
remote_tmp = $HOME/ansible_tmp
ansible_managed = Ansible managed - don't edit this file!
#[ssh_connection]
#pipelining = True

86
inventory/group_vars/all Normal file
View file

@ -0,0 +1,86 @@
---
as_private_mwu: 65037
as_public_ffrl: 201701
routing_tables:
icvpn: 23
mwu: 41
internet: 61
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
meshes:
mz:
site_number: 37
site_code: ffmz
site_name: Mainz
ipv4_network: 10.37.0.0/18
ipv6:
ula:
- fd37:b4dc:4b1e::/48
public:
- 2a03:2260:11a::/48
dnssl:
- ffmz.org
- user.ffmz.org
batman:
it: 10000
gw: server 96mbit/96mbit
mm: 0
dat: 0
iface_mtu: 1350
peers_mesh_repo: https://github.com/freifunk-mwu/peers-ffmz.git
peers_intragate_repo: https://github.com/freifunk-mwu/ffmz-infrastructure-peers.git
wi:
site_number: 56
site_code: ffwi
site_name: Wiesbaden
ipv4_network: 10.56.0.0/18
ipv6:
ula:
- fd56:b4dc:4b1e::/48
public:
- 2a03:2260:11b::/48
dnssl:
- ffwi.org
- user.ffwi.org
batman:
it: 10000
gw: server 96mbit/96mbit
mm: 0
dat: 0
iface_mtu: 1350
peers_mesh_repo: https://github.com/freifunk-mwu/peers-ffwi.git
peers_intragate_repo: https://github.com/freifunk-mwu/ffwi-infrastructure-peers.git
bgp_mwu_servers:
spinat:
ipv4: 10.37.0.7
ipv6: fd37:b4dc:4b1e::a25:7
lotuswurzel:
ipv4: 10.37.0.23
ipv6: fd37:b4dc:4b1e::a25:17
ingwer:
ipv4: 10.37.0.161
ipv6: fd37:b4dc:4b1e::a25:a1
wasserfloh:
ipv4: 10.37.0.231
ipv6: fd37:b4dc:4b1e::a25:e7
zuckerwatte:
ipv4: 10.37.1.2
ipv6: fd37:b4dc:4b1e::a25:102
aubergine:
ipv4: 10.37.1.3
ipv6: fd37:b4dc:4b1e::a25:103
zwiebel:
ipv4: 10.37.1.0
ipv6: fd37:b4dc:4b1e::a25:100
glueckskeks:
ipv4: 10.37.1.1
ipv6: fd37:b4dc:4b1e::a25:101
suesskartoffel:
ipv4: 10.37.1.4
ipv6: fd37:b4dc:4b1e::a25:104

22
playbook-gateways.yml Executable file
View file

@ -0,0 +1,22 @@
#!/usr/bin/ansible-playbook
---
- hosts: ffmwu-gateways
remote_user: admin
roles:
- server-repos
- server-basic
- service-haveged
- service-ntpd
- kmod-batman
- network-routetables
- network-batman
- network-meshbridge
- service-dhcpd
- service-radvd
- service-fastd-mesh
- service-fastd-intragate
- git-fastd-peers
- network-fastd
- network-ffrl

View file

@ -0,0 +1,42 @@
---
- name: install git packages
apt:
name: "{{ item }}"
state: present
with_items:
- git
become: true
- name: create fastd peer mesh directories
file:
path: "/etc/fastd/{{ item.key }}VPN/peers"
state: directory
mode: 0755
owner: admin
group: admin
with_dict: "{{ meshes }}"
become: true
- name: create fastd peer intragate directories
file:
path: "/etc/fastd/{{ item.key }}igVPN/peers"
state: directory
mode: 0755
owner: admin
group: admin
with_dict: "{{ meshes }}"
become: true
- name: clone fastd peer mesh repos
git:
repo: "{{ item.value.peers_mesh_repo }}"
dest: "/etc/fastd/{{ item.key }}VPN/peers"
update: no
with_dict: "{{ meshes }}"
- name: clone fastd peer intragate repos
git:
repo: "{{ item.value.peers_intragate_repo }}"
dest: "/etc/fastd/{{ item.key }}igVPN/peers"
update: no
with_dict: "{{ meshes }}"

View file

@ -0,0 +1,18 @@
---
- name: install batman-module and linux headers
apt:
state: present
name: "{{ item }}"
update_cache: yes
cache_valid_time: 21600
with_items:
- linux-headers-amd64
- batman-adv-dkms
- batctl
become: true
- name: configure batman module to load on system boot
template:
src: batman-adv.module.conf.j2
dest: /etc/modules-load.d/batman-adv.conf
become: true

View file

@ -0,0 +1,6 @@
#
# Load batman-adv module on system boot
# {{ ansible_managed }}
#
batman-adv
dummy

View file

@ -0,0 +1,6 @@
---
- name: activate sysfs variables
systemd:
name: sysfsutils
state: restarted
become: true

View file

@ -0,0 +1,22 @@
---
- name: create dummy interfaces
template:
src: dummy.j2
dest: "/etc/network/interfaces.d/{{ item.key }}0"
with_dict: "{{ meshes }}"
become: true
- name: create batman interfaces
template:
src: batman.j2
dest: "/etc/network/interfaces.d/{{ item.key }}BAT"
with_dict: "{{ meshes }}"
become: true
- name: set sysfs variables
template:
src: sysfs.j2
dest: "/etc/sysfs.d/99-{{ item.key }}BAT.conf"
with_dict: "{{ meshes }}"
notify: activate sysfs variables
become: true

View file

@ -0,0 +1,18 @@
{% set ip4hex = item.value.ipv4_network | ipaddr('net') | ipaddr(magic) | ipaddr('address') | ip4_hex() -%}
{% set mac = '0201' + ip4hex -%}
#
# {{ ansible_managed }}
#
auto {{ item.key }}BAT
iface {{ item.key }}BAT inet manual
pre-up /sbin/ip link add name $IFACE type batadv
pre-up /sbin/ip link set address {{ mac | hwaddr('linux') }} dev $IFACE
pre-up /sbin/ip link set dev {{ item.key }}0 master $IFACE
pre-up /sbin/ip link set up dev $IFACE
post-up /sbin/ip addr flush dev $IFACE
post-up /usr/sbin/batctl -m $IFACE it {{ item.value.batman.it }}
post-up /usr/sbin/batctl -m $IFACE gw {{ item.value.batman.gw }}
post-up /usr/sbin/batctl -m $IFACE mm {{ item.value.batman.mm }}
post-up /usr/sbin/batctl -m $IFACE dat {{ item.value.batman.dat }}
post-down /sbin/ip link set dev {{ item.key }}0 nomaster
post-down /sbin/ip link delete $IFACE 2>&1 || true

View file

@ -0,0 +1,12 @@
{% set ip4hex = item.value.ipv4_network | ipaddr('net') | ipaddr(magic) | ipaddr('address') | ip4_hex() -%}
{% set mac = '0200' + ip4hex -%}
#
# {{ ansible_managed }}
#
auto {{ item.key }}0
iface {{ item.key }}0 inet manual
pre-up /sbin/ip link add $IFACE type dummy
pre-up /sbin/ip link set address {{ mac | hwaddr('linux') }} dev $IFACE
pre-up /sbin/ip link set up dev $IFACE
post-up /sbin/ip addr flush dev $IFACE
post-down /sbin/ip link delete $IFACE 2>&1 || true

View file

@ -0,0 +1,4 @@
#
# {{ ansible_managed }}
#
class/net/{{ item.key }}BAT/mesh/hop_penalty = 60

View file

@ -0,0 +1,14 @@
---
- name: create fastd mesh interfaces
template:
src: fastd-mesh.j2
dest: "/etc/network/interfaces.d/{{ item.key }}VPN"
with_dict: "{{ meshes }}"
become: true
- name: create fastd intragate interfaces
template:
src: fastd-intragate.j2
dest: "/etc/network/interfaces.d/{{ item.key }}igVPN"
with_dict: "{{ meshes }}"
become: true

View file

@ -0,0 +1,10 @@
{% set ip4hex = item.value.ipv4_network | ipaddr('net') | ipaddr(magic) | ipaddr('address') | ip4_hex() -%}
{% set mac = '0212' + ip4hex -%}
#
# {{ ansible_managed }}
#
allow-hotplug {{ item.key }}igVPN
iface {{ item.key }}igVPN inet manual
pre-up /sbin/ip link set address {{ mac | hwaddr('linux') }} dev $IFACE
post-up /sbin/ip link set dev $IFACE up
post-up /sbin/ip link set dev $IFACE master {{ item.key }}BAT

View file

@ -0,0 +1,10 @@
{% set ip4hex = item.value.ipv4_network | ipaddr('net') | ipaddr(magic) | ipaddr('address') | ip4_hex() -%}
{% set mac = '0211' + ip4hex -%}
#
# {{ ansible_managed }}
#
allow-hotplug {{ item.key }}VPN
iface {{ item.key }}VPN inet manual
pre-up /sbin/ip link set address {{ mac | hwaddr('linux') }} dev $IFACE
post-up /sbin/ip link set dev $IFACE up
post-up /sbin/ip link set dev $IFACE master {{ item.key }}BAT

View file

@ -0,0 +1,7 @@
---
- name: create ffrl interfaces
template:
src: ffrl.j2
dest: "/etc/network/interfaces.d/{{ item.key }}"
with_dict: "{{ ffrl_exit_server }}"
become: true

View file

@ -0,0 +1,16 @@
#
# {{ ansible_managed }}
#
auto {{ item.key }}
iface {{ item.key }} inet static
address {{ item.value.tunnel_ipv4_address }}
netmask {{ item.value.tunnel_ipv4_netmask }}
pre-up /sbin/ip tunnel add $IFACE mode gre local {{ ansible_default_ipv4.address | ipaddr('public') }} remote {{ item.value.public_ipv4_address | ipaddr('public') }} ttl 255
post-up /sbin/ip link set $IFACE mtu 1400
post-up /sbin/ip addr add {{ ffrl_public_ipv4_nat }}/32 dev $IFACE
post-down /sbin/ip tunnel del $IFACE
iface {{ item.key }} inet6 static
address {{ item.value.tunnel_ipv6_network | ipaddr('net') | ipaddr('2') | ipaddr('address') }}
netmask {{ item.value.tunnel_ipv6_netmask }}

View file

@ -0,0 +1,6 @@
---
- name: activate sysfs variables
systemd:
name: sysfsutils
state: restarted
become: true

View file

@ -0,0 +1,15 @@
---
- name: create mesh bridges
template:
src: bridge.j2
dest: "/etc/network/interfaces.d/{{ item.key }}BR"
with_dict: "{{ meshes }}"
become: true
- name: set sysfs variables
template:
src: sysfs.j2
dest: "/etc/sysfs.d/99-{{ item.key }}BR.conf"
with_dict: "{{ meshes }}"
notify: activate sysfs variables
become: true

View file

@ -0,0 +1,22 @@
{% set ip4hex = item.value.ipv4_network | ipaddr('net') | ipaddr(magic) | ipaddr('address') | ip4_hex() -%}
{% set mac = '0210' + ip4hex -%}
#
# {{ ansible_managed }}
#
auto {{ item.key }}BR
iface {{ item.key }}BR inet manual
address {{ item.value.ipv4_network | ipaddr('net') | ipaddr(magic) | ipaddr('address') }}
network {{ item.value.ipv4_network | ipaddr('net') | ipaddr(magic) | ipaddr('network') }}
netmask {{ item.value.ipv4_network | ipaddr('net') | ipaddr(magic) | ipaddr('netmask') }}
broadcast {{ item.value.ipv4_network | ipaddr('net') | ipaddr(magic) | ipaddr('broadcast') }}
pre-up /sbin/ip link add name $IFACE type bridge
pre-up /sbin/ip link set address {{ mac | hwaddr('linux') }} dev $IFACE
pre-up /sbin/ip link set dev {{ item.key }}BAT master $IFACE
pre-up /sbin/ip link set up dev $IFACE
{% for ip_type, ip_list in item.value.ipv6.iteritems() %}
{% for ip in ip_list %}
up /sbin/ip address add {{ ip | ipaddr('net') | ipsubnet(64, 0) | ipaddr(magic) }} dev $IFACE
{% endfor %}
{% endfor %}
post-down /sbin/ip link set dev {{ item.key }}BAT nomaster
post-down /sbin/ip link delete $IFACE 2>&1 || true

View file

@ -0,0 +1,4 @@
#
# {{ ansible_managed }}
#
class/net/{{ item.key }}BR/bridge/hash_max = 16384

View file

@ -0,0 +1,9 @@
---
- name: create routing tables
lineinfile:
path: /etc/iproute2/rt_tables
regexp: '^{{ item.value }}'
line: "{{ item.value }}{{ '\t' }}{{ item.key }}"
state: present
with_dict: "{{ routing_tables }}"
become: true

View file

@ -0,0 +1,20 @@
---
- name: ensure common packages are installed
apt:
state: present
name: "{{ item }}"
update_cache: yes
cache_valid_time: 21600
with_items: "{{ packages }}"
become: true
- name: ensure vim is default editor
alternatives:
name: editor
path: /usr/bin/vim.basic
become: true
- name: set timezone to Europe/Berlin
timezone:
name: Europe/Berlin
become: true

View file

@ -0,0 +1,10 @@
---
packages:
- apt-transport-https
- ifupdown2
- man-db
- mlocate
- mosh
- sudo
- sysfsutils
- vim

View file

@ -0,0 +1,34 @@
---
- name: ensure dirmngr and apt-transport-https are installed
apt:
state: present
name: "{{ item }}"
update_cache: yes
cache_valid_time: 21600
with_items:
- dirmngr
- apt-transport-https
become: true
- name: ensure apt key for universe-factory is present
apt_key:
state: present
id: 16ef3f64cb201d9c
keyserver: pgp.mit.edu
become: true
- name: ensure apt key for freifunk-mwu is present
apt_key:
state: present
id: 83A70084
url: "http://repo.freifunk-mwu.de/83A70084.gpg.key"
become: true
- name: ensure needed apt repos are present
apt_repository:
state: present
repo: "{{ item.repo }}"
update_cache: "{{ item.update_cache }}"
filename: "{{ item.name }}"
with_items: "{{ repos }}"
become: true

View file

@ -0,0 +1,12 @@
---
repos:
- name: fastd
repo: 'deb https://repo.universe-factory.net/debian/ sid main'
update_cache: yes
- name: freifunk
repo: 'deb http://repo.freifunk-mwu.de/debian jessie main'
update_cache: yes
- name: freifunk
repo: 'deb-src http://repo.freifunk-mwu.de/debian jessie main'
update_cache: yes

View file

@ -0,0 +1,7 @@
---
- name: restart isc dhcp server
systemd:
name: isc-dhcp-server
enabled: yes
state: restarted
become: true

View file

@ -0,0 +1,39 @@
---
- name: install dhcp packages
apt:
name: isc-dhcp-server
state: present
become: true
- name: enable systemd unit isc-dhcp-server
systemd:
name: isc-dhcp-server
enabled: yes
daemon_reload: yes
become: true
- name: concatenate meshbridge interfaces
set_fact:
dhcp_interfaces: "{% for key, value in meshes.iteritems() %}{{ key }}BR{% if not loop.last %} {% endif %}{% endfor %}"
- name: set ipv4 interfaces isc dhcp should listen on
lineinfile:
path: /etc/default/isc-dhcp-server
regexp: '^INTERFACESv4="'
line: 'INTERFACESv4="{{ dhcp_interfaces }}"'
notify: restart isc dhcp server
become: true
- name: set ipv6 interfaces isc dhcp should listen on
lineinfile:
path: /etc/default/isc-dhcp-server
regexp: '^INTERFACESv6="'
line: 'INTERFACESv6=""'
become: true
- name: configure isc dhcp server
template:
src: dhcpd.conf.j2
dest: /etc/dhcp/dhcpd.conf
# notify: restart isc dhcp server
become: true

View file

@ -0,0 +1,28 @@
#
# {{ ansible_managed }}
#
ddns-update-style none;
authoritative;
server-name "{{ inventory_hostname_short }}";
log-facility local7;
default-lease-time 300;
min-lease-time 300;
max-lease-time 300;
{% for mesh in meshes.values() %}
# DHCP subnet for site {{ mesh.site_name }} ({{ mesh.site_code }})
subnet {{ mesh.ipv4_network | ipaddr('network') }} netmask {{ mesh.ipv4_network | ipaddr('netmask') }} {
range {{ mesh.ipv4_network | ipsubnet(22, ipv4_dhcp_range) | ipaddr('net') | ipaddr('network') }} {{ mesh.ipv4_network | ipsubnet(22, ipv4_dhcp_range) | ipaddr('net') | ipaddr('broadcast') }};
option routers {{ mesh.ipv4_network | ipaddr('net') | ipaddr(magic) | ipaddr('address') }};
option domain-name-servers {{ mesh.ipv4_network | ipaddr('net') | ipaddr(magic) | ipaddr('address') }};
option domain-search {% for domain in mesh.dnssl %}"{{ domain }}"{% if not loop.last %}, {% endif %}{% endfor %};
option ntp-servers {{ mesh.ipv4_network | ipaddr('net') | ipaddr(magic) | ipaddr('address') }};
option interface-mtu {{ mesh.iface_mtu }};
}
{% if not loop.last %}
{% endif %}
{% endfor %}

View file

@ -0,0 +1,28 @@
---
- name: install fastd packages
apt:
name: fastd
state: present
become: true
- name: create fastd intragate directories
file:
path: "/etc/fastd/{{ item.key }}igVPN"
state: directory
mode: 0755
with_dict: "{{ meshes }}"
become: true
- name: template fastd mesh config
template:
src: fastd-intragate.conf.j2
dest: "/etc/fastd/{{ item.key }}igVPN/fastd.conf"
with_dict: "{{ meshes }}"
become: true
- name: write fastd intragate secret
template:
src: fastd-secret.conf.j2
dest: "/etc/fastd/{{ item.key }}igVPN/secret.conf"
with_dict: "{{ meshes }}"
become: true

View file

@ -0,0 +1,23 @@
#
# {{ ansible_managed }}
#
log level warn;
hide ip addresses yes;
hide mac addresses yes;
method "aes128-ctr+umac";
interface "{{ item.key }}igVPN";
bind {{ ansible_default_ipv4.address | ipaddr('public') }}:101{{ item.value.site_number }};
bind {{ ansible_default_ipv6.address | ipaddr('public') | ipwrap }}:101{{ item.value.site_number }};
include "secret.conf";
mtu 1406;
peer group "servers" {
include peers from "peers/gates";
include peers from "peers/services";
}
status socket "/var/run/fastd-{{ item.key }}ig.status";

View file

@ -0,0 +1,9 @@
{% set local_interface = item.key + 'igVPN' -%}
#
# {{ ansible_managed }}
#
{% for interface in fastd_secrets %}
{% if local_interface == interface %}
secret "{{ fastd_secrets[interface] }}";
{% endif %}
{% endfor %}

View file

@ -0,0 +1,28 @@
---
- name: install fastd packages
apt:
name: fastd
state: present
become: true
- name: create fastd directories
file:
path: "/etc/fastd/{{ item.key }}VPN"
state: directory
mode: 0755
with_dict: "{{ meshes }}"
become: true
- name: template fastd mesh config
template:
src: fastd-mesh.conf.j2
dest: "/etc/fastd/{{ item.key }}VPN/fastd.conf"
with_dict: "{{ meshes }}"
become: true
- name: write fastd mesh secret
template:
src: fastd-secret.conf.j2
dest: "/etc/fastd/{{ item.key }}VPN/secret.conf"
with_dict: "{{ meshes }}"
become: true

View file

@ -0,0 +1,30 @@
#
# {{ ansible_managed }}
#
log level warn;
hide ip addresses yes;
hide mac addresses yes;
method "salsa2012+umac";
interface "{{ item.key }}VPN";
bind {{ ansible_default_ipv4.address | ipaddr('public') }}:100{{ item.value.site_number }};
bind {{ ansible_default_ipv6.address | ipaddr('public') | ipwrap }}:100{{ item.value.site_number }};
include "secret.conf";
mtu 1406;
peer group "vpn_nodes" {
peer limit 150;
include peers from "peers";
{% if item.key == "mz" %}
include peers from "peers_bingen";
{% endif %}
}
peer group "servers" {
include peers from "peers/servers";
}
status socket "/var/run/fastd-{{ item.key }}.status";

View file

@ -0,0 +1,9 @@
{% set local_interface = item.key + 'VPN' -%}
#
# {{ ansible_managed }}
#
{% for interface in fastd_secrets %}
{% if local_interface == interface %}
secret "{{ fastd_secrets[interface] }}";
{% endif %}
{% endfor %}

View file

@ -0,0 +1,5 @@
---
- name: reload systemd
systemd:
daemon_reload: yes
become: true

View file

@ -0,0 +1,14 @@
---
- name: install haveged
apt:
name: haveged
state: present
notify: reload systemd
become: true
- name: start and enable systemd unit haveged
systemd:
name: haveged
enabled: yes
state: started
become: true

View file

@ -0,0 +1,29 @@
---
- name: ensure systemd-timesyncd is disabled
systemd:
name: systemd-timesyncd
enabled: no
state: stopped
become: true
- name: install ntp packages
apt:
state: present
name: "{{ item }}"
update_cache: yes
cache_valid_time: 21600
with_items:
- ntp
- ntp-doc
- ntpdate
- ntpstat
become: true
- name: enable and start ntp daemon
systemd:
name: ntp
enabled: yes
state: started
daemon_reload: yes
become: true

View file

@ -0,0 +1,20 @@
---
- name: install radvd packages
apt:
name: radvd
state: present
become: true
- name: enable systemd unit radvd
systemd:
name: radvd
enabled: yes
daemon_reload: yes
become: true
- name: configure radvd
template:
src: radvd.conf.j2
dest: /etc/radvd.conf
#notify: restart radvd
become: true

View file

@ -0,0 +1,43 @@
#
# {{ ansible_managed }}
#
{% for key, value in meshes.iteritems() %}
interface {{ key }}BR
{
AdvSendAdvert on;
IgnoreIfMissing on;
MaxRtrAdvInterval 900;
AdvLinkMTU {{ value.iface_mtu }};
{% for ip_type, ip_list in value.ipv6.iteritems() %}
{% for prefix in ip_list %}
{% if ip_type == "ula" %}
RDNSS {{ prefix | ipaddr('net') | ipsubnet(64, 0) | ipaddr(magic) }}
{
FlushRDNSS off;
};
{% endif %}
{% endfor %}
{% endfor %}
{% for ip_type, ip_list in value.ipv6.iteritems() %}
{% for prefix in ip_list %}
{% if ip_type == "public" %}
prefix {{ prefix | ipaddr('net') | ipsubnet(64, magic) }}
{% else %}
prefix {{ prefix | ipaddr('net') | ipsubnet(64, 0) }}
{% endif %}
{
AdvValidLifetime 864000;
AdvPreferredLifetime 172800;
};
{% endfor %}
{% if not loop.last %}
{% endif %}
{% endfor %}
};
{% if not loop.last %}
{% endif %}
{% endfor %}