Bau eines Freifunk-Offloaders auf Basis eines Raspberry 4B
Bei größeren Installationen, wie z.B. in Flüchtlingsunterkünften, Wohnheimen, oder Veranstaltungen bzw. Veranstaltungsräumen gelangt man mit den gängigen Plasteroutern sehr schnell an deren Leistungsgrenzen. Die zeigt sich vor allem beim Datendurchsatz, da die in den Routern verbauten CPUs an ihre Grenzen kommen, da diese nicht für eine permanente Ver- und Entschlüsselung von großen Datenmengen ausgelegt sind.
In diesem Konfigurationsbeispiel wollen wir möglichst einfach und schnell einen Offloader für Freifunk München auf Basis eines Raspberry 4B befassen. Dabei gehen wir auf unterschiedliche Konfigurations-Optionen ein und wollen dennoch die Einstiegshürden für den ungeübteren Ansible und Linux-User möglichst tief ansetzen.
Als Basis für die Konfiguration setzen wir beim sehr gut dokumentierten Artikel von @awlnx aus dem Freifunk WIKI auf.
Nicht unerwähnt darf auch @lqb bleiben, der mit entscheidenden Tips zum Gelingen des Ansible-Playbooks beigetragen hat!
Inhalt
Das Kapitel hier ist in folgende Abschnitte strukturiert.
Wer also z.B. bereits einen SSH-Schlüssel sein eigen nennt oder Grundlagen zu Ansible bereits kennt und installiert hat, kann natürlich sofort beim Playbook bzw. dessen Ausführung einsteigen und die nachfolgenden Informationen überspringen.
Folgende Abschnitte beschreiben den eigentlichen Bau des Freifunk-Offloaders mit Ansible-Unterstützung und ist somit der ideale Einsprungpunkt für den versierten LINUX-Admin mit entsprechenden Ansible-Kenntnissen.:
Grundlagen zu SSH
Grundlegende Informationen rund um die SSH1) und deren Umgang bei der täglichen Arbeit finden sich im Kapitel Secure Shell hier im WIKI.
Erstellen eines SSH-Schlüsselpaares
Damit wir selbst für spätere Administrationsaufgaben und auch unser Ansible-Admin-Host Verbindungen mit Hilfe der SSH2) zu unserem Offloader aufbauen kann, benötigen wir natürlich entsprechendes Schlüsselmaterial, abhängig vom jeweiligen Zielsystem bzw. den kryptographischen Eigenschaften.
Bei der Erstellung wollen wir statt einesRSA-Keys auf zeitgemäße und sicherere ed25519 Schlüssel verwenden. Ed25519 ist ein Elliptic Curve Signature Schema, welches beste Sicherheit bei vertretbaren Aufwand verspricht, als ECDSA oder DSA dies der Fall ist. Zur Auswahl sicherer kryptografischer Kurven bei der Elliptic-Curve Cryptography findet man auf der Seite hier hilfreiche Erklärungen und eine Gegenüberstellung der möglichen verschiedenen Alternativen. Weitere Infos zu den ED25519-Schlüsseln und der SSH finden sich im entsprechenden Kapitel hier im WIKI.
Wir erstellen uns nun einen ED25519-Schlüssel (-t
), mit einer festen Schlüssellänge. Der Parameter (-a
) beschreibt dabei die Anzahl der KDF-Schlüsselableitfunktion (siehe manpage von ssh-keygen). Wir verwenden als Beschreibung FFMUC Remote-User (-C
) und als Ziel-/Speicherort ~/.ssh/id_ed25519_ffmuc (-f
).
$ ssh-keygen -t ed25519 -a 100 -C 'FFMUC Remote-User' -f ~/.ssh/id_ed25519_ffmuc
Generating public/private ed25519 key pair.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in ~/.ssh/id_ed25519_ffmuc.
Your public key has been saved in ~/.ssh/id_ed25519_ffmuc.pub.
The key fingerprint is:
SHA256:jTZQUDbCqZaV64+Dj4n90+15+A+933K*fx3L4iUCBY3kKMQ FFMUC Remote-User
The key's randomart image is:
+--[ED25519 256]--+
| o+==.oo |
| .E+ +.+. |
| ++.. = * |
| +..+ + O . |
| ... S + o . |
| ... E * . |
| .oo o + + .|
| .... . =E |
| .. + ooo |
+----[SHA256]-----
Grundlagen zu Ansible
Grundlegende Informationen zu Ansible und dessen Umgang bei der täglichen Arbeit finden sich im Kapitel Ansible hier im WIKI.
Installation von Ansible und Git
Je nach verwendeter Systemumgebung installieren wir nun das vom Paketmaintainer zur Verfügung gestellte RPM bzw. DEB Paket. Im Falle von RedHat basierenden Systemen wie CentOS oder Fedora benutzen wir das Paketverwaltungswerkzeug YUM/DNF oder im Falle von Debian und Ubuntu das Werkzeug APT.
- RPM basierende Systeme:
# dnf install ansible git
bzw.
# yum install ansible git
- DEB basierende Systeme:
# apt install ansible git
bzw. als eigeloggter User via
sudo
mit$ sudo apt install ansible git
Einrichten der eigenen Ansible-Umgebung
Ansible Arbeitsverzeichnis
Für unsere Ansible-Aufgaben (Playbooks) legen wir uns nun im Home-Verzeichnis unseres Admin-Users ein zugehöriges Verzeichnis an.
$ mkdir ~/ansible
Ansible-Konfigurationsdatei
Der ungeduldigen Leser kann auch direkt zur Tat schreiten und das manuelle Anlegen des Verzeichnisses und des Ansible-Scripts überspringen. Mit Folgendem Befehl erledigt man dies sozusagen auf einem Rutsch:
$ mkdir ~/ansible ; wget https://gitlab.nausch.org/django/example_8a/-/archive/main/example_8a-main.tar.gz -O - | tar -xz --strip-components=1 -C ~/ansible
Anschliessend kann man direkt zur Ausführung des Playbooks schreiten:
$ ansible-playbook ~/ansible/playbooks/ansible_grundconfig_v1.yml -K
Als nächstes kopieren wir uns die Vorlage-Konfiguratinsdatei aus dem Verzeichnis /etc/ansible/
in unser Homeverzeichnis.
$ cp /etc/ansible/ansible.cfg ~/.ansible.cfg
Unter dem Konfigurationsgruppe [ defaults ] setzen wir den Parameter inventory = ~/ansible/inventories/production/hosts
und interpreter_python = auto_silent
. Beim ersten Parameter zeigen wir Ansible, wo die Host-Definitionen zu finden sind. beim Parameter interpreter_python
geben wir an, dass keine Ausgabe zu den Angaben des Pfads zum Python-Interpreter auf dem Raspberry ausgegeben werden soll. Der Parameter connect_timeout
definiert, wie lange eine persistente Verbindung bestehen darf, bevor diese hart getrennt wird. Weitere Information zu den Konfigurationsparametern finden sie in der Dokumentation der Konfigurationsoptionen zu Ansible.
$ vim ~/.ansible.cfg
Im Ganzen ergibt sich dann hier die doch überschaubare Konfigurationsdatei zu Ansible.
$ egrep -v '(^.*#|^$)' ~/.ansible.cfg
[defaults] inventory = ~/ansible/inventories/production/hosts interpreter_python = auto_silent [inventory] [privilege_escalation] [paramiko_connection] [ssh_connection] [persistent_connection] connect_timeout = 30 [accelerate] [selinux] [colors] [diff]
Host-Definitionsdatei
Die Definition unseres Hosts mit den tzugehörigen Variablen beziehen wir später aus dem Ansible Playbook Archiv. Somit müssen wir hier nichts extra vorbereiten!
SSH Konfigurationsdatei
Damit wir unseren Raspberry auch direkt über den zuvor definierten Namen ansprechen können, definieren wir nun noch in unserer SSH-Konfigurationsdatei ~/.ssh/config
des Clients diesen Host.
$ vim ~/.ssh/config
Host raspberry-wireguard
Hostname 10.0.10.29
Port 22
User pi
IdentitiesOnly=yes
Protocol 2
IdentityFile ~/.ssh/id_ed25519_ffmuc
Beim Parameter Hostname
geben wir die IP-Adresse an, die unser DHCP-Server dem Raspberry verpasst an; in obigen Konfigurationsbeispiel hat unser Raspberry die IP-Adresse 10.0.10.29
. Die Datei mit dem Eingangs erzeugten SSH-Schlüssel geben wir beim Parameter IdentityFile
an.
Klonen des GIT-Repositories (Ansible-Playbook)
$ cd ~/ansible $ git clone http://gitlab.nausch.org/django/ffmuc-offloader_rpb4.git .
Somit ergibt sich folgende Verzeichnis- und Dateistruktur:
/ansible/
├── filter_plugins
├── inventories
│ ├── production
│ │ ├── group_vars
│ │ │ └── ffmuc
│ │ │ ├── gateway_keys
│ │ │ ├── gateway_link_adresses
│ │ │ ├── gateway_mesh_vpn_vxlan_ids
│ │ │ ├── global_vars
│ │ │ ├── vxlan_ids
│ │ │ └── wireguard_ports
│ │ ├── hosts
│ │ └── host_vars
│ │ ├── rpb4-ol-a
│ │ │ └── individual_host_specification
│ │ ├── rpb4-ol-b
│ │ │ └── individual_host_specification
│ │ └── rpb4-ol-p
│ │ └── individual_host_specification
│ └── staging
│ ├── group_vars
│ ├── hosts.yml
│ └── host_vars
├── library
├── LICENSE
├── module_utils
├── playbooks
│ └── wireguard-offloader.yml
├── README.md
├── roles
│ ├── basic
│ │ ├── defaults
│ │ ├── files
│ │ ├── handlers
│ │ ├── library
│ │ ├── lookup_plugin
│ │ ├── meta
│ │ ├── module_utils
│ │ ├── tasks
│ │ │ ├── hostname.yml
│ │ │ ├── hosts.yml
│ │ │ ├── main.yml
│ │ │ ├── reboot.yml
│ │ │ ├── rfkill.yml
│ │ │ ├── update.yml
│ │ │ └── usercomment.yml
│ │ ├── templates
│ │ │ └── hosts.j2
│ │ └── vars
│ ├── batman
│ │ ├── defaults
│ │ ├── files
│ │ ├── handlers
│ │ ├── library
│ │ ├── lookup_plugin
│ │ ├── meta
│ │ ├── module_utils
│ │ ├── tasks
│ │ │ ├── batmanstart.yml
│ │ │ ├── compile.yml
│ │ │ ├── install.yml
│ │ │ ├── interfaceconfigure.yml
│ │ │ ├── main.yml
│ │ │ ├── modulloads.yml
│ │ │ ├── reboot.yml
│ │ │ ├── rsyslog.yml
│ │ │ └── utilsinstall.yml
│ │ ├── templates
│ │ │ ├── 01-blocklist.j2
│ │ │ ├── batman-adv.module.j2
│ │ │ ├── dkms.j2
│ │ │ └── interfaces.j2
│ │ └── vars
│ ├── client-mesh
│ │ ├── defaults
│ │ ├── files
│ │ ├── handlers
│ │ ├── library
│ │ ├── lookup_plugin
│ │ ├── meta
│ │ ├── module_utils
│ │ ├── tasks
│ │ │ ├── batmanmitwifi.yml
│ │ │ ├── batmanohnewifi.yml
│ │ │ ├── clientohnemesh.yml
│ │ │ ├── getvxlanid.yml
│ │ │ ├── main.yml
│ │ │ ├── meshohneclient.yml
│ │ │ └── meshundclient.yml
│ │ ├── templates
│ │ │ ├── interfaces_client_ohne_mesh.j2
│ │ │ ├── interfaces_mesh_mit_client.j2
│ │ │ ├── interfaces_mesh_ohne_client.j2
│ │ │ ├── rclocal_both.j2
│ │ │ └── rclocal_vxlan.j2
│ │ └── vars
│ ├── common
│ │ ├── defaults
│ │ ├── files
│ │ ├── handlers
│ │ ├── library
│ │ ├── lookup_plugin
│ │ ├── meta
│ │ ├── module_utils
│ │ ├── tasks
│ │ │ └── main.yml
│ │ ├── templates
│ │ └── vars
│ ├── ext-respondd
│ │ ├── defaults
│ │ ├── files
│ │ ├── handlers
│ │ ├── library
│ │ ├── lookup_plugin
│ │ ├── meta
│ │ ├── module_utils
│ │ ├── tasks
│ │ │ ├── aliasgenerate.yml
│ │ │ ├── bugfixing.yml
│ │ │ ├── configgenerate.yml
│ │ │ ├── copyconfig.yml
│ │ │ ├── gitclone.yml
│ │ │ ├── gitinstall.yml
│ │ │ ├── main.yml
│ │ │ └── servicestartup.yml
│ │ ├── templates
│ │ │ ├── ext-respondd_alias.json.j2
│ │ │ └── ext-respondd_config.json.j2
│ │ └── vars
│ ├── final
│ │ ├── defaults
│ │ ├── files
│ │ ├── handlers
│ │ ├── library
│ │ ├── lookup_plugin
│ │ ├── meta
│ │ ├── module_utils
│ │ ├── tasks
│ │ │ ├── main.yml
│ │ │ └── reboot.yml
│ │ ├── templates
│ │ └── vars
│ ├── hostapd
│ │ ├── defaults
│ │ ├── files
│ │ ├── handlers
│ │ ├── library
│ │ ├── lookup_plugin
│ │ ├── meta
│ │ ├── module_utils
│ │ ├── tasks
│ │ │ ├── configure.yml
│ │ │ ├── genconfig.yml
│ │ │ ├── install.yml
│ │ │ ├── main.yml
│ │ │ ├── servicestartup.yml
│ │ │ └── wlanbridging.yml
│ │ ├── templates
│ │ │ ├── hostapd.j2
│ │ │ └── rclocal_wifi.j2
│ │ └── vars
│ ├── vxlan
│ │ ├── defaults
│ │ ├── files
│ │ ├── handlers
│ │ ├── library
│ │ ├── lookup_plugin
│ │ ├── meta
│ │ ├── module_utils
│ │ ├── tasks
│ │ │ ├── configure.yml
│ │ │ ├── main.yml
│ │ │ └── vxlanstart.yml
│ │ ├── templates
│ │ │ ├── systemd-service-file.j2
│ │ │ └── vxlan-init.j2
│ │ └── vars
│ └── wireguard
│ ├── defaults
│ ├── files
│ ├── handlers
│ ├── library
│ ├── lookup_plugin
│ ├── meta
│ ├── module_utils
│ ├── tasks
│ │ ├── brokerinform.yml
│ │ ├── checkup.yml
│ │ ├── configuration.yml
│ │ ├── genkeys.yml
│ │ ├── genlinklocal.yml
│ │ ├── install.yml
│ │ ├── main.yml
│ │ ├── radv-filter.yml
│ │ └── wireguardstart.yml
│ ├── templates
│ │ ├── broker.j2
│ │ ├── checkup.j2
│ │ ├── crontab.j2
│ │ ├── radv-filter.j2
│ │ └── uplink.j2
│ └── vars
└── wireguard-offloader.yml
Kopieren des Ansible-Playbooks
Alternativ zu einem git clone …
können wir natürlich das tar.gz-Archiv per wget holen. Hierzu greifen wir auf folgendes Playbook zurück und laden es uns auf unseren Rechner:
- ffmuc-offloader_rpb4-main.tar.gz3) ( WireGuard )
$ wget https://gitlab.nausch.org/django/ffmuc-offloader_rpb4/-/archive/main/ffmuc-offloader_rpb4-main.tar.gz
Anschliessend entpacken wir es an Ort und Stelle.
$ tar -xvf ffmuc-offloader_rpb4-main.tar.gz
Aufbau des Ansible-Playbooks - Inhalte
Nachfolgend finden wir die Inhalte der einzelnen Dateien die im ansible-playbook enthalten sind:
Inventory-Definition
Das Inventory ist aufgeteilt in einzelne Dateien. Die Definition der Hosts erfolgt via hosts
-Datei:
- ~/ansible/inventories/production/hosts
# Django : 2022-04-06 # Definition einer Hostgruppe "ffmuc" [ffmuc] # Auflistung aller Hosts, die der vorgenannten Hostgruppe angehören. rpb4-ol-a rpb4-ol-b rpb4-ol-p
Je Host den wir bearbeiten wollen definieren wir dann dessen Eigenschaften in der Datei individual_host_specification
im zugehörigen Unterverzeichnis. Beim Host rpb4-ol-b als Beispiel liegt die individuelle Hostkonfiguration demnach hier:
$ less ~/ansible/inventories/production/host_vars/rpb4-ol-b/individual_host_specification
- ..inventories/production/host_vars/rpb4-ol-b/individual_host_specification
# IP-Adresse unseres Raspberry in unserem eigenen lokalen Netzwerk # stationäre schwarzes Plastikgehäuse Raspberry 4B mit PoE-HAT und Display # MAC: dc:a6:32:22:f0:f2 ansible_ssh_host: 192.168.0.22 ansible_port: 22 ansible_user: pi ansible_ssh_private_key_file: ~/.ssh/id_ed25519_freifunk # batman_adv_version: "2022.1" ffmuc_segment: "muc_ost" ffmuc_gateway: "gw06" raspberry_hostname: "ff_pliening_rpb4_ol_v6" node_contact_address: "hier entlang => https://bit.ly/2VxGoXp" raspberry_latitude: "48.198757565" raspberry_longitude: "11.798020899" raspberry_wifi: "true" raspberry_clientvlan: "4" raspberry_meshvlan: "2" raspberry_oled: "false"
Hier passen wir natürlich die Parameter unserer eigenen Umgebung an, damit diese richtig später vom ansible-script auch gesetzt werden!
Im Verzeichnis ../group_vars/ffmuc/
finden sich alle System-/FFMUC-spezifischen Definitionen, die hier nicht verändert werden müssen!
../group_vars/ffmuc/ ├── gateway_keys ├── gateway_link_adresses ├── gateway_mesh_vpn_vxlan_ids ├── global_vars ├── vxlan_ids └── wireguard_ports
Der interessierte Leser kann hier natürlich bei Interesse jeweils einen Blick hinein werfen.
$ less ~/ansible/inventories/production/group_vars/ffmuc/..
- gateway_keys
# aus https://github.com/freifunkMUC/site-ffm/blob/stable/domains/ "publickey" gw_publickey: gw04: "TszFS3oFRdhsJP3K0VOlklGMGYZy+oFCtlaghXJqW2g=" gw05: "igyqOmWiz4EZxPG8ZzU537MnHhaqlwfa7HarB3KmnEg=" gw06: "pkRaUOoLuuHnUt9BEGeKrhF3OMYBPecc0iYkika6uhE=" gw07: "PcKkakZcTEx3LKh+G06Opb8/esg08aWK33A5/Ff1YXE="
- gateway_link_adresses
# aus https://github.com/freifunkMUC/site-ffm/blob/stable/domains/ "link_address" gw_linklocal: gw04: "fe80::27c:16ff:fec0:6c74" gw05: "fe80::281:8eff:fef0:73aa" gw06: "fe80::2a2:e4ff:fef9:2269" gw07: "fe80::23b:d2ff:fe95:967f"
- gateway_mesh_vpn_vxlan_ids
# https://ffmuc.net/wiki/doku.php?id=knb:rpb4_wg#berechnung_der_mesh_vpn_vxlan_id gw_vxlan_ids: muc_cty: 3836090 muc_nord: 1920014 muc_ost: 12097488 muc_sued: 12815947 muc_west: 29149 uml_nord: 403289 uml_ost: 12645856 uml_sued: 12090508 uml_west: 935867 gauting: 4681119 freising: 4669918 welt: 4831583 augsburg: 2962115
- global_vars
ansible_ssh_user: pi dtparam: "i2c_arm=on"
- vxlan_ids
# Die vxlan id berechnet sich aus dem domain_seed: https://ffmuc.net/wiki/doku.php?id=knb:rpb4_wg#mesh_per_vxlan1 vxlan_ids: muc_cty: 10758607 muc_nord: 15521492 muc_ost: 2948862 muc_sued: 8599288 muc_west: 7318933 uml_nord: 5705961 uml_ost: 4892713 uml_sued: 16544703 uml_west: 16677749 gauting: 16175732 freising: 12937858 welt: 16306234 augsburg: 10700201q
- wireguard_ports
wireguard_ports: muc_cty: 40002 muc_nord: 40003 muc_ost: 40004 muc_sued: 40005 muc_west: 40006 uml_nord: 40007 uml_ost: 40008 uml_sued: 40009 uml_west: 40010 gauting: 40012 freising: 40013 welt: 40011 augsburg: 40014
Playbook "main"
- ~/ansible/wireguard-offloader.yml
--- # Start der YML Datei # Ansible Playbook für (statische) Konfiguration eines Offloader auf Basis eines Raspberry PI 4B # Aufruf via $ ansible-playbook playbooks/wireguard-offloader.yml für alle Hosts der Gruppe # bzw. $ ansible-playbook playbooks/wireguard-offloader.yml --limit rpb4-ol-a für nur einen # Host mit dem Namen rpb4 aus derm inventory - name: wireguard-offloader.yml # Name des Playbooks hosts: ffmuc # Hostgruppe für die das Playbook gelten soll become: true # Rechteerweiterung am Zielsystem via sudo/su become_user: root # Nutzer für die Ansible Aufgaben auf dem Remote-System roles: - role: basic # Basiskonfiguration des Hosts (Host-/Username anpassen und System Updaten) tags: basic - role: batman # Installation und Konfiguration der BATMAN Kernel-Module tags: batmam # - role: wireguard # Installation und Konfiguration des wireguard Tunnels tags: wireguard # - role: vxlan # Konfiguration von VXLAN für wireguard-Tunnel-Verbindung in Richtung Gateway tags: vxlan # - role: ext-respondd # Installation und Konfiguration des ext-respondd (Statistiken für https://map.ffmuc.net) tags: ext-respondd # - role: hostapd # Installation und Konfiguration des hostap Treibers für den WiFi-Support when: ( raspberry_wifi == true ) # tags: hostapd # - role: client-mesh # Grundkonfiguration von Client und/oder Meshing (V)LANs tags: client-mesh # - role: final # Reboot nach Abschluss der Konfiguration unseres Offloaders tags: final # ... # YML Ende
Rolle "basic"
Tasks
- ~/ansible/roles/basic/tasks/main.yml
--- # Grundkonfiguration und Systemupgrade des Raspberry Pi OS - include: hostname.yml # Hostname ändern - include: hosts.yml # /etc/hosts anpassen - include: usercomment.yml # Beschreibung des User 'pi' anpassen - include: rfkill.yml # Service rfkill bei Raspberry Pi OS deaktivieren - include: update.yml # Update und Upgrade der APT-Pakete - include: reboot.yml # Reboot nach Abschluss der Erstinstallation/-konfiguration ...
- ~/ansible/roles/basic/tasks/hostname.yml
--- - name: "Hostname ändern" ansible.builtin.command: cmd: hostnamectl set-hostname {{ raspberry_hostname }} changed_when: false ...
- ~/ansible/roles/basic/tasks/hosts.yml
--- - name: "Template Konfigurationsdatei für /etc/hosts an Ort und Stelle kopieren und Variablen anpassen" ansible.builtin.template: src: templates/hosts.j2 dest: /etc/hosts owner: root group: root mode: '0644' ...
- ~/ansible/roles/basic/tasks/usercomment.yml
--- - name: "Beschreibung des User 'pi' anpassen" ansible.builtin.user: name: pi comment: "Raspberry Pi OS System User" state: present ...
- ~/ansible/roles/basic/tasks/rfkill.yml
--- - name: "Service rfkill am Raspberry deaktivieren" ansible.builtin.command: cmd: rfkill unblock wifi changed_when: false ...
- ~/ansible/roles/basic/tasks/update.yml
--- - name: "Zuerst 'apt-get update' ausführen" ansible.builtin.apt: update_cache: true - name: "Alle installierten Pakete Updaten" ansible.builtin.apt: name: "*" state: latest ...
- ~/ansible/roles/basic/tasks/reboot.yml
--- - name: "Reboot nach update" ansible.builtin.reboot: ...
Templates
- ~/ansible/roles/basic/templates/hosts.j2
127.0.0.1 localhost {{ raspberry_hostname }} ::1 localhost ip6-localhost ip6-loopback ff02::1 ip6-allnodes ff02::2 ip6-allrouters
Rolle "batman"
Tasks
- ~/ansible/roles/batman/tasks/main.yml
--- # Installation und Konfiguration von BATMAN - include: install.yml # Download des aktuellen BATMAN Archives - include: compile.yml # BATMAN Kernel-Module erzeugen - include: modulloads.yml # MATMAN-ADV und DUMMY Module laden - include: utilsinstall.yml # Installation der bridge-utils und batctl - include: batmanstart.yml # Aktivierung von BATMAN_V - include: interfaceconfigure.yml # Konfiguration der Interfaces - include: rsyslog.yml # syslog-Anpassungen - include: reboot.yml # Reboot nach Ende des Installationsschritts ... # YML Ende
- ~/ansible/roles/batman/tasks/install.yml
--- - name: "Download des aktuellen BATMAN Archives" ansible.builtin.get_url: url: https://downloads.open-mesh.org/batman/releases/batman-adv-{{ batman_adv_version }}/batman-adv-{{ batman_adv_version }}.tar.gz dest: /usr/src/batman-adv-{{ batman_adv_version }}.tar.gz mode: '0644' - name: "Entpacken des BATMAN-Archives" ansible.builtin.unarchive: src: /usr/src/batman-adv-{{ batman_adv_version }}.tar.gz dest: /usr/src remote_src: true ...
- ~/ansible/roles/batman/tasks/compile.yml
--- - name: "Installation des Dynamic Kernel Module Support Framework und der Header Files für den Raspberry Pi OS Linux Kernel" ansible.builtin.apt: update_cache: true pkg: - dkms - raspberrypi-kernel-headers state: present - name: "Rebuild BATMAN Kernel Header Dateien" community.general.make: chdir: /usr/src/linux-headers-{{ ansible_kernel }} target: scripts ignore_errors: true - name: "Anlegen der dkms.conf für Dynamic Kernel Module Support" ansible.builtin.template: src: templates/dkms.j2 dest: /usr/src/batman-adv-{{ batman_adv_version }}/dkms.conf owner: root group: root mode: '0644' - name: "Dynamic Kernel Module Support hinzufügen" ansible.builtin.command: cmd: dkms add -m batman-adv -v {{ batman_adv_version }} register: ret failed_when: ret.rc != 0 and ret.rc != 3 changed_when: ret.rc == 0 - name: "Dynamic Kernel Module bauen" ansible.builtin.command: cmd: dkms build -m batman-adv -v {{ batman_adv_version }} changed_when: false - name: "BATMAN Dynamic Kernel Module installieren" ansible.builtin.command: cmd: dkms install -m batman-adv -v {{ batman_adv_version }} changed_when: false ...
- ~/ansible/roles/batman/tasks/modulloads.yml
--- - name: "Laden der BATMAN Dynamic Kernel Module beim Booten sicherstellen" ansible.builtin.template: src: templates/batman-adv.module.j2 dest: /etc/modules-load.d/batman-adv.module.conf owner: root group: root mode: '0644' - name: "BATMAN dummy Modul laden" community.general.modprobe: name: dummy state: present - name: "BATMAN-ADV Modul laden" community.general.modprobe: name: batman_adv state: present ...
- ~/ansible/roles/batman/tasks/utilsinstall.yml
--- - name: "Installation der bridge-utils" ansible.builtin.apt: pkg: - bridge-utils - dnsutils - vim state: present - name: "Installation des batctl-packages" ansible.builtin.apt: pkg: - batctl default_release: "/^bullseye(|-security|-updates)$/" state: present ...
- ~/ansible/roles/batman/tasks/batmanstart.yml
--- - name: "Aktivierung von BATMAN_V" ansible.builtin.command: cmd: batctl ra BATMAN_V changed_when: false ...
- ~/ansible/roles/batman/tasks/interfaceconfigure.yml
--- - name: "Konfiguration des Interfaces" ansible.builtin.template: src: templates/interfaces.j2 dest: /etc/network/interfaces owner: root group: root mode: '0644' ...
- ~/ansible/roles/batman/tasks/rsyslog.yml
--- - name: "rsyslog konfigurieren, damit received packet ... with own address as source address im syslog unterdrückit werden" template: src: templates/01-blocklist.j2 dest: /etc/rsyslog.d/01-blocklist.conf owner: root group: root mode: '0644' ...
- ~/ansible/roles/batman/tasks/reboot.yml
--- - name: "Reboot nach Ende der BATMAN Installationsschritte" ansible.builtin.reboot: ...
Templates
- ~/ansible/roles/batman/templates/01-blocklist.j2
:msg,contains,": received packet on bat-{{ ffmuc_segment }} with own address as source address " STOP
- ~/ansible/roles/batman/templates/batman-adv.module.j2
# Generated by Ansible on {{ ansible_date_time.date }}, do not edit manually! # # Load batman-adv module on system boot # batman-adv dummy
- ~/ansible/roles/batman/templates/dkms.j2
PACKAGE_NAME=batman-adv PACKAGE_VERSION={{ batman_adv_version }} DEST_MODULE_LOCATION=/extra BUILT_MODULE_NAME=batman-adv BUILT_MODULE_LOCATION=net/batman-adv MAKE="'make'" CLEAN="'make' clean" AUTOINSTALL="yes"
- ~/ansible/roles/batman/templates/interfaces.j2
# Generated by Ansible on {{ ansible_date_time.date }}, do not edit manually! # interfaces(5) file used by ifup(8) and ifdown(8) # Please note that this file is written to be used with dhcpcd # For static IP, consult /etc/dhcpcd.conf and 'man dhcpcd.conf' # Include files from /etc/network/interfaces.d: # source-directory /etc/network/interfaces.d auto eth0 iface eth0 inet dhcp auto br-{{ ffmuc_segment }} iface br-{{ ffmuc_segment }} inet dhcp bridge-ports bat-{{ ffmuc_segment }} pre-up /usr/sbin/batctl ra BATMAN_V pre-up /sbin/ip link add dummy-{{ ffmuc_segment }} type dummy pre-up /sbin/ip link set address $(ip -br l | grep eth0 | egrep -o '([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})' | head -1) dev dummy-{{ ffmuc_segment }} pre-up /sbin/ip link set dummy-{{ ffmuc_segment }} up pre-up /usr/sbin/batctl meshif bat-{{ ffmuc_segment }} if add dummy-{{ ffmuc_segment }} pre-up /sbin/ip link set bat-{{ ffmuc_segment }} up pre-up /usr/sbin/batctl meshif bat-{{ ffmuc_segment }} gw_mode client pre-up /sbin/ip link set address $(ip -br l | grep eth0 | egrep -o '([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})' | head -1) dev bat-{{ ffmuc_segment }} post-up /sbin/ip link set address $(ip -br l | grep eth0 | egrep -o '([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})' | head -1) dev br-{{ ffmuc_segment }}
Rolle "wireguard"
Tasks
- ~/ansible/roles/wireguard/tasks/main.yml
--- # Installation und Konfiguration von WIREGUARD - include: install.yml # Installation des wireguard-Paketes - include: genkeys.yml # Schlüsselmaterial erzeugen - include: genlinklocal.yml # lokale link-local IPv6 Adresse generieren - include: configuration.yml # Konfigurationsdatei kopieren und anpassen - include: brokerinform.yml # Public-Key unseres Nodes an den Broker übermitteln - include: wireguardstart.yml # Aktivierung des wireguard client-daemon - include: radv-filter.yml # RADV-Filter setzen - include: checkup.yml # Wireguard überprüfen ... # YML Ende
- ~/ansible/roles/wireguard/tasks/install.yml
--- - name: "Installation von wireguard und iptables" ansible.builtin.apt: pkg: - wireguard - iptables state: present ...
- ~/ansible/roles/wireguard/tasks/genkeys.yml
--- - name: "Schlüsselmaterial erstellen" ansible.builtin.command: cmd: /usr/bin/wg genkey | tee client_private.key | wg pubkey | tee client_public.key args: chdir: /etc/wireguard/ creates: client_private.key - name: "Zugriffsrechte des Private Keys anpassen" ansible.builtin.file: path: /etc/wireguard/client_private.key mode: '0600' - name: "Zugriffsrechte des Public Keys anpassen" ansible.builtin.file: path: /etc/wireguard/client_public.key mode: '0600' ...
- ~/ansible/roles/wireguard/tasks/genlinklocal.yml
--- - name: "lokale link-local IPv6 Adresse aus dem PUBLIC-Key erzeugen" ansible.builtin.shell: | cat /etc/wireguard/client_public.key | md5sum | sed 's/^\(..\)\(..\)\(..\)\(..\)\(..\).*$/fe80::02\1:\2ff:fe\3:\4\5/' register: wg_node_linklocal changed_when: false ...
- ~/ansible/roles/wireguard/tasks/configuration.yml
--- - name: "private-key einlesen und in Variable übergeben" ansible.builtin.command: cmd: cat /etc/wireguard/client_private.key register: wg_client_privatekey changed_when: false - name: "public-key einlesen und in Variable übergeben" ansible.builtin.command: cmd: cat /etc/wireguard/client_public.key register: wg_client_publickey changed_when: false - name: "Socket ermitteln" ansible.builtin.set_fact: ffmuc_wireguard_port: "{{ item.value }}" loop: "{{ lookup('dict', wireguard_ports) }}" when: "ffmuc_segment in item.key" - name: "link-local des Gateways ermitteln" ansible.builtin.set_fact: ffmuc_wireguard_linklocal: "{{ item.value }}" loop: "{{ lookup('dict', gw_linklocal) }}" when: "ffmuc_gateway in item.key" - name: "publickey des Gateways ermitteln" ansible.builtin.set_fact: ffmuc_wireguard_gwpubkey: "{{ item.value }}" loop: "{{ lookup('dict', gw_publickey) }}" when: "ffmuc_gateway in item.key" - name: "Konfigurationsdatei des wireguard-Tunnels erzeugen" ansible.builtin.template: src: templates/uplink.j2 dest: /etc/wireguard/wg-uplink.conf owner: root group: root mode: '0644' ...
- ~/ansible/roles/wireguard/tasks/brokerinform.yml
--- - name: "systemd unit file für broker -Information anlegen" ansible.builtin.template: src: templates/broker.j2 dest: /etc/systemd/system/broker.service owner: root group: root mode: '0644' - name: "Service broker starten beim Booten starten" ansible.builtin.systemd: name: broker daemon_reload: true state: started enabled: true ...
- ~/ansible/roles/wireguard/tasks/wireguardstart.yml
--- - name: "Service wireguard via systemd starten" ansible.builtin.systemd: name: wg-quick@wg-uplink daemon_reload: true state: started enabled: true ...
- ~/ansible/roles/wireguard/tasks/radv-filter.yml
--- - name: "Startsrcipt für der RADV-Filter anlegen" template: src: templates/radv-filter.j2 dest: /usr/local/bin/radv-filter owner: root group: root mode: '0644' ...
- ~/ansible/roles/wireguard/tasks/checkup.yml
--- - name: "Lokale link-local IPv6 Adresse aus dem PUBLIC-Key erzeugen" ansible.builtin.shell: | cat /etc/wireguard/client_public.key | md5sum | sed 's/^\(..\)\(..\)\(..\)\(..\)\(..\).*$/fe80::02\1:\2ff:fe\3:\4\5/' register: wg_node_linklocal changed_when: false - name: "checkupscript zum Testen der wireguard-Verbindung anlegen" ansible.builtin.template: src: templates/checkup.j2 dest: /usr/local/bin/checkup owner: root group: root mode: '0750' - name: "Ausführungsrechte des Bash-Scripts anpassen" ansible.builtin.file: path: /usr/local/bin/checkup mode: '0740' - name: "crontab für minütlichen checkup der wireguard-Verbindung anlegen" ansible.builtin.template: src: templates/crontab.j2 dest: /etc/crontab owner: root group: root mode: '0644' ...
Templates
- ~/ansible/roles/wireguard/templates/broker.j2
# Generated by Ansible on {{ ansible_date_time.date }}, do not edit manually! [Unit] # see man systemd.unit Description=Inform tunnel about our wireguard-public key Documentation=https://dokuwiki.nausch.org/doku.php/centos:ansible:ffmuc-rpb4-ol Before=wg-quick.target [Service] # see man systemd.service, systemd.exec ExecStart=/usr/bin/wget -q -O- --post-data='{"domain":"ffmuc_{{ ffmuc_segment }}","public_key":"{{ wg_client_publickey.stdout }}"}' http://broker.ffmuc.net/api/v1/wg/key/exchange StandardOutput=syslog StandardError=syslog [Install] WantedBy=default.target
- ~/ansible/roles/wireguard/templates/checkup.j2
#!/bin/bash # Generated by Ansible on {{ ansible_date_time.date }}, do not edit manually! # Check connectivity to supernode HTTP_STATUS_CODE=(`curl --silent --interface wg-uplink --get --ipv6 --connect-timeout 5 --write-out '%{http_code}' --output /dev/null 'http://[{{ ffmuc_wireguard_linklocal }}]:80'`) if [ ${HTTP_STATUS_CODE} != "200" ]; then logger -t checkuplink "curl --silent --interface wg-uplink --get --ipv6 --connect-timeout 5 --write-out '%{http_code}' --output /dev/null 'http://[{{ ffmuc_wireguard_linklocal }}]:80' faild with HTTP-errorcode: ${HTTP_STATUS_CODE}" logger -t checkuplink "... better we restart the wireguar-tunnel!" ip link set nomaster bat-{{ ffmuc_segment }} dev vxlan-mesh &> /dev/null ip link del dev mesh-vpn &> /dev/null ip link del wg-uplink &> /dev/null systemctl stop wg-quick@wg-uplink systemctl restart networking logger -t checkuplink "Sending public-key to the broker." /usr/bin/wget -q -O- --post-data='{"domain":"ffmuc_{{ ffmuc_segment }}","public_key":"{{ wg_client_publickey.stdout }}"}' http://broker.ffmuc.net/api/v1/wg/key/exchange logger -t checkuplink "Starting wireguard-daemon." systemctl start wg-quick@wg-uplink logger -t checkuplink "Starting vxlan-meshing." vxlan else #logger -t checkuplink "wiregurad-tunnel is up an running : HTTP-statuscode: ${HTTP_STATUS_CODE}" fi
- ~/ansible/roles/wireguard/templates/crontab.j2
# Generated by Ansible on {{ ansible_date_time.date }}, do not edit manually! # /etc/crontab: system-wide crontab # Unlike any other crontab you don't have to run the `crontab' # command to install the new version when you edit this file # and files in /etc/cron.d. These files also have username fields, # that none of the other crontabs do. SHELL=/bin/sh PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin MAILTO="" # Example of job definition: # .---------------- minute (0 - 59) # | .------------- hour (0 - 23) # | | .---------- day of month (1 - 31) # | | | .------- month (1 - 12) OR jan,feb,mar,apr ... # | | | | .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat # | | | | | # * * * * * user-name command to be executed 17 * * * * root cd / && run-parts --report /etc/cron.hourly 25 6 * * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily ) 47 6 * * 7 root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly ) 52 6 1 * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly ) # # check wireguard-connection -* * * * * root /usr/local/bin/checkup 2>&1 /dev/null # set firewall-role for RA-Filter -* * * * * root /usr/local/bin/radv-filter 2>&1 /dev/null
- ~/ansible/roles/wireguard/templates/uplink.j2
[Interface] PrivateKey = {{ wg_client_privatekey.stdout }} Address = {{ wg_node_linklocal.stdout }} [Peer] PublicKey = {{ ffmuc_wireguard_gwpubkey }} AllowedIPs = {{ ffmuc_wireguard_linklocal }} Endpoint = {{ ffmuc_gateway }}.ext.ffmuc.net:{{ ffmuc_wireguard_port }} PersistentKeepalive = 25
Rolle "vxlan"
Tasks
- ~/ansible/roles/vxlan/tasks/main.yml
--- # Installation und Konfiguration von VXLAN - include: configure.yml # VXLAN Konfigurieren - include: vxlanstart.yml # Aktivierung des wireguard client-daemon ... # YML Ende
- ~/ansible/roles/vxlan/tasks/configure.yml
--- - name: "Paketfilter anpassen - Eingehenden VXLAN Verkehr auf dem Mesh-Interface erlauben" ansible.builtin.command: | ip6tables -I INPUT 1 -i wg-uplink -m udp -p udp --dport 8472 -j ACCEPT changed_when: false - name: "VXLAN-ID des gewählten Segments ermitteln" ansible.builtin.set_fact: ffmuc_vxlan_id: "{{ item.value }}" loop: "{{ lookup('dict', gw_vxlan_ids) }}" when: "ffmuc_segment in item.key" - name: "link-local des Gateways ermitteln" ansible.builtin.set_fact: ffmuc_wireguard_linklocal: "{{ item.value }}" loop: "{{ lookup('dict', gw_linklocal) }}" when: "ffmuc_gateway in item.key" - name: "lokale link-local IPv6 Adresse aus dem PUBLIC-Key erzeugen" ansible.builtin.shell: | cat /etc/wireguard/client_public.key | md5sum | sed 's/^\(..\)\(..\)\(..\)\(..\)\(..\).*$/fe80::02\1:\2ff:fe\3:\4\5/' register: wg_node_linklocal changed_when: false - name: "Startupdatei für VXLAN kopieren" template: src: templates/vxlan-init.j2 dest: /usr/local/bin/vxlan owner: root group: root mode: '0750' ...
- ~/ansible/roles/vxlan/tasks/vxlanstart.yml
--- - name: "systemd-unitfile anlegen" ansible.builtin.template: src: templates/systemd-service-file.j2 dest: /etc/systemd/system/vxlan.service owner: root group: root mode: '0644' - name: "Neues Unitfile dem systemd bekannt geben" ansible.builtin.systemd: daemon_reload: true - name: "Service vxlan via systemd starten" ansible.builtin.systemd: name: vxlan.service daemon_reload: true state: started enabled: true ...
Templates
- ~/ansible/roles/vxlan/templates/systemd-service-file.j2
# Generated by Ansible on {{ ansible_date_time.date }}, do not edit manually! [Unit] # see man systemd.unit Description=Bringing up VXLAN Interface Documentation=https://dokuwiki.nausch.org/doku.php/centos:ansible:ffmuc-rpb4-ol After=wg-quick@wg-uplink.service [Service] # see man systemd.service, systemd.exec Type=oneshot ExecStart=/usr/local/bin/vxlan StandardOutput=syslog StandardError=syslog [Install] WantedBy=multi-user.target
- ~/ansible/roles/vxlan/templates/vxlan-init.j2
#!/bin/bash # Generated by Ansible on {{ ansible_date_time.date }}, do not edit manually! # Bring up VXLAN ip link add mesh-vpn type vxlan id {{ ffmuc_vxlan_id }} local {{ wg_node_linklocal.stdout }} remote {{ ffmuc_wireguard_linklocal }} dstport 8472 dev wg-uplink ip link set up dev mesh-vpn # Bind mesh-vpn to BATMAN-Device /usr/sbin/batctl meshif bat-{{ ffmuc_segment }} if add mesh-vpn # If we have a BATMAN_V env we need to correct the throughput value now /usr/sbin/batctl hardif mesh-vpn throughput_override 10000
Rolle "ext-respondd"
Tasks
- ~/ansible/roles/ext-respondd/tasks/main.yml
--- # Installation und Konfiguration des ext-respondd (Statistiken für https://map.ffmuc.net) - include: gitinstall.yml # Installation der Pakete git und python3-netifaces - include: gitclone.yml # Repo ext-respondd klonen - include: copyconfig.yml # Systemd Startdatei für respondd kopieren - include: aliasgenerate.yml # Erstellen der resondd Konfigurationsdatei alias.json - include: configgenerate.yml # Erstellen der resondd Konfigurationsdatei config.json - include: servicestartup.yml # Service ext-respondd beim Booten starten
- ~/ansible/roles/ext-respondd/tasks/gitinstall.yml
--- - name: "Installation der Pakete git und python3-netifaces" ansible.builtin.apt: update_cache: true pkg: - git - python3-netifaces state: present ...
- ~/ansible/roles/ext-respondd/tasks/gitclone.yml
--- - name: "ggf. bestehende Altlast bereinigen" ansible.builtin.file: path: /opt/ext-respondd state: absent - name: "Repo ext-respondd klonen" ansible.builtin.git: repo: https://github.com/freifunkMUC/ext-respondd dest: /opt/ext-respondd/ version: master clone: true update: true ...
- ~/ansible/roles/ext-respondd/tasks/copyconfig.yml
--- - name: "Systemd Startdatei für respondd kopieren" ansible.builtin.copy: src: /opt/ext-respondd/ext-respondd.service.example dest: /etc/systemd/system/ext-respondd.service remote_src: true # cmd: cp /opt/ext-respondd/ext-respondd.service.example /etc/systemd/system/ext-respondd.service ...
- ~/ansible/roles/ext-respondd/tasks/aliasgenerate.yml
--- - name: "Erstellen der resondd Konfigurationsdatei alias.json" ansible.builtin.template: src: templates/ext-respondd_alias.json.j2 dest: /opt/ext-respondd/alias.json owner: root group: root mode: '0644' ...
- ~/ansible/roles/ext-respondd/tasks/configgenerate.yml
--- - name: "Erstellen der resondd Konfigurationsdatei config.json" ansible.builtin.template: src: templates/ext-respondd_config.json.j2 dest: /opt/ext-respondd/config.json owner: root group: root mode: '0644' ...
- ~/ansible/roles/ext-respondd/tasks/bugfixing.yml
--- - name: "Typo in der /opt/ext-respondd/lib/nodeinfo.py korrigieren" ansible.builtin.replace: path: /opt/ext-respondd/lib/nodeinfo.py # zu ersetzende/korrigierende Zeile regexp: 'Processor' # wird ersetzt durch replace: 'processor' ...
- ~/ansible/roles/ext-respondd/tasks/servicestartup.yml
--- - name: "Service ext-respondd beim Booten starten" systemd: name: ext-respondd daemon_reload: true state: started enabled: true ...
Templates
- ~/ansible/roles/ext-respondd/templates/ext-respondd_alias.json.j2
{ "nodeinfo": { "hostname": "{{ raspberry_hostname }}", "hardware": { "model": "Raspberry Pi 4B" }, "owner": { "contact": "{{ node_contact_address }}" }, "system": { "site_code": "ffmuc_{{ ffmuc_segment }}", "role": "client" }, "location": { "latitude": {{ raspberry_latitude }}, "longitude": {{ raspberry_longitude }} } }, "firstseen": "2019-08-14T12:34:56" }
- ~/ansible/roles/ext-respondd/templates/ext-respondd_config.json.j2
{ "batman": "bat-{{ ffmuc_segment }}", "bridge": "br-{{ ffmuc_segment }}", "mesh-vpn": [ "fastd-{{ ffmuc_segment }}" ], "wan": "eth0", "rate_limit": 30, "rate_limit_burst": 10 }
Rolle "hostapd"
Tasks
- ~/ansible/roles/hostapd/tasks/main.yml
--- # Installation und Konfiguration des hostap Treibers für den WiFi-Support - include: install.yml # Paket hostapd für WLAN installieren - include: configure.yml # hostapd konfigurieren - include: genconfig.yml # hostapd Konfigurationsdatei anlegen - include: wlanbridging.yml # wlan0 in Bridge packen - include: servicestartup.yml # Service hostapd beim Booten und jetzt starten # und so das Laden der Unit Datei vom Service # hostapd ermöglichen ... # YML Ende
- ~/ansible/roles/hostapd/tasks/install.yml
--- - name: "Paket hostapd für WLAN installieren" ansible.builtin.apt: update_cache: true pkg: - hostapd state: present ...
- ~/ansible/roles/hostapd/tasks/configure.yml
--- - name: "hostapd konfigurieren" ansible.builtin.command: | echo 'DAEMON_OPTS="-d"' >> /etc/default/hostapd changed_when: false ...
- ~/ansible/roles/hostapd/tasks/genconfig.yml
--- - name: "hostapd Konfigurationsdatei anlegen" ansible.builtin.template: src: templates/hostapd.j2 dest: /etc/hostapd/hostapd.conf owner: root group: root mode: '0644' ...
- ~/ansible/roles/hostapd/tasks/wlanbridging.yml
--- - name: "wlan0 in Bridge packen" template: src: templates/rclocal_wifi.j2 dest: /etc/rc.local owner: root group: root mode: '0750' ...
- ~/ansible/roles/hostapd/tasks/servicestartup.yml
--- - name: "Service hostapd beim Booten und jetzt starten und das Laden der Unit Datei vom Service hostapd ermöglichen" ansible.builtin.systemd: name: hostapd enabled: true masked: false state: started ...
Templates
- ~/ansible/roles/hostapd/templates/hostapd.j2
ssid=muenchen.freifunk.net/{{ ffmuc_segment }} country_code=US interface=wlan0 driver=nl80211 macaddr_acl=0 logger_syslog=0 logger_syslog_level=4 logger_stdout=-1 logger_stdout_level=0 hw_mode=a wmm_enabled=1 # N ieee80211n=1 require_ht=1 ht_capab=[MAX-AMSDU-3839][HT40+][SHORT-GI-20][SHORT-GI-40][DSSS_CCK-40] # AC ieee80211ac=1 require_vht=1 ieee80211d=0 ieee80211h=0 vht_capab=[MAX-AMSDU-3839][SHORT-GI-80] vht_oper_chwidth=1 channel=36 vht_oper_centr_freq_seg0_idx=42
- ~/ansible/roles/hostapd/templates/rclocal_wifi.j2
#!/bin/sh -e # Generated by Ansible on {{ ansible_date_time.date }}, do not edit manually! # # rc.local # # This script is executed at the end of each multiuser runlevel. # Make sure that the script will "exit 0" on success or any other # value on error. # # In order to enable or disable this script just change the execution # bits. # # By default this script does nothing. # Print the IP address _IP=$(hostname -I) || true if [ "$_IP" ]; then printf "My IP address is %s\n" "$_IP" fi sleep 10; /sbin/brctl addif br-{{ ffmuc_segment }} wlan0 exit 0
Rolle "client-mesh"
Tasks
- ~/ansible/roles/client-mesh/tasks/main.yml
--- # Grundkonfiguration von Client und/oder Meshing (V)LANs - include: clientohnemesh.yml # Konfiguration des Client-VLAN ohne Mesh-Netz - include: getvxlanid.yml # vxlan_id für ausgewähltes Segment ermitteln - include: meshohneclient.yml # Konfiguration des Mesh-VLAN ohne Client-VLAN - include: meshundclient.yml # Konfiguration von Mesh- und Client-VLAN - include: batmanohnewifi.yml # Konfiguration des bevorzugte Meshingpoint in BATMAN_V ohne Wifi-Nutzung - include: batmanmitwifi.yml # Konfiguration des bevorzugte Meshingpoint in BATMAN_V mit Wifi-Nutzung ... # YML Ende
- ~/ansible/roles/client-mesh/tasks/clientohnemesh.yml
--- - name: "Konfiguration des Client-VLAN ohne Mesh-Netz" ansible.builtin.template: src: templates/interfaces_client_ohne_mesh.j2 dest: /etc/network/interfaces owner: root group: root mode: '0640' when: ( raspberry_clientvlan|length > 0 ) and ( raspberry_meshvlan|length == 0 ) ...
- ~/ansible/roles/client-mesh/tasks/getvxlanid.yml
--- - name: "vxlan_id für ausgewähltes Segment ermitteln" ansible.builtin.set_fact: ffmuc_vxlan_id: "{{ item.value }}" loop: "{{ lookup('dict', vxlan_ids) }}" when: "ffmuc_segment in item.key" ...
- ~/ansible/roles/client-mesh/tasks/meshohneclient.yml
--- - name: "Konfiguration des Mesh-VLAN ohne Client-VLAN" ansible.builtin.template: src: templates/interfaces_mesh_ohne_client.j2 dest: /etc/network/interfaces owner: root group: root mode: '0640' when: ( raspberry_clientvlan|length == 0 ) and ( raspberry_meshvlan|length > 0 ) ...
- ~/ansible/roles/client-mesh/tasks/meshundclient.yml
--- - name: "Konfiguration von Mesh- und Client-VLAN" ansible.builtin.template: src: templates/interfaces_mesh_mit_client.j2 dest: /etc/network/interfaces owner: root group: root mode: '0640' when: ( raspberry_clientvlan|length > 0 ) and ( raspberry_meshvlan|length > 0 ) ...
- ~/ansible/roles/client-mesh/tasks/batmanohnewifi.yml
--- - name: "Konfiguration des bevorzugte Meshingpoint in BATMAN_V ohne Wifi-Nutzung" ansible.builtin.template: src: templates/rclocal_vxlan.j2 dest: /etc/rc.local owner: root group: root mode: '0750' when: ( raspberry_meshvlan|length > 0 ) and ( raspberry_wifi != "true" ) ...
- ~/ansible/roles/client-mesh/tasks/batmanmitwifi.yml
--- - name: "Konfiguration des bevorzugte Meshingpoint in BATMAN_V mit Wifi-Nutzung" ansible.builtin.template: src: templates/rclocal_both.j2 dest: /etc/rc.local owner: root group: root mode: '0750' when: ( raspberry_meshvlan|length > 0 ) and ( raspberry_wifi == "true" ) ...
Templates
- ~/ansible/roles/client-mesh/templates/interfaces_client_ohne_mesh.j2
# Generated by Ansible on {{ ansible_date_time.date }}, do not edit manually! # interfaces(5) file used by ifup(8) and ifdown(8) # Please note that this file is written to be used with dhcpcd # For static IP, consult /etc/dhcpcd.conf and 'man dhcpcd.conf' # Include files from /etc/network/interfaces.d: # source-directory /etc/network/interfaces.d auto eth0 iface eth0 inet dhcp auto eth0.{{ raspberry_clientvlan }} iface eth0.{{ raspberry_clientvlan }} inet manual auto br-{{ ffmuc_segment }} iface br-{{ ffmuc_segment }} inet dhcp bridge-ports bat-{{ ffmuc_segment }} eth0.{{ raspberry_clientvlan }} pre-up /usr/sbin/batctl ra BATMAN_V pre-up /sbin/ip link add dummy-{{ ffmuc_segment }} type dummy pre-up /sbin/ip link set address $(ip -br l | grep eth0 | egrep -o '([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})' | head -1) dev dummy-{{ ffmuc_segment }} pre-up /sbin/ip link set dummy-{{ ffmuc_segment }} up pre-up /usr/sbin/batctl meshif bat-{{ ffmuc_segment }} if add dummy-{{ ffmuc_segment }} pre-up /sbin/ip link set bat-{{ ffmuc_segment }} up pre-up /usr/sbin/batctl meshif bat-{{ ffmuc_segment }} gw_mode client pre-up /sbin/ip link set address $(ip -br l | grep eth0 | egrep -o '([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})' | head -1) dev bat-{{ ffmuc_segment }} post-up /sbin/ip link set address $(ip -br l | grep eth0 | egrep -o '([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})' | head -1) dev br-{{ ffmuc_segment }}
- ~/ansible/roles/client-mesh/templates/interfaces_mesh_mit_client.j2
# Generated by Ansible on {{ ansible_date_time.date }}, do not edit manually! # interfaces(5) file used by ifup(8) and ifdown(8) # Please note that this file is written to be used with dhcpcd # For static IP, consult /etc/dhcpcd.conf and 'man dhcpcd.conf' # Include files from /etc/network/interfaces.d: # source-directory /etc/network/interfaces.d auto eth0 iface eth0 inet dhcp auto eth0.{{ raspberry_meshvlan }} iface eth0.{{ raspberry_meshvlan }} inet manual pre-up /sbin/ip link add vxlan-mesh type vxlan id {{ ffmuc_vxlan_id }} group ff02::15c dstport 4789 port 32768 61000 no udpcsum udp6zerocsumtx udp6zerocsumrx dev eth0.{{ raspberry_meshvlan }} || true up /sbin/ip link set vxlan-mesh up post-up /usr/sbin/batctl ra BATMAN_V post-up /usr/sbin/batctl meshif bat-{{ ffmuc_segment }} if add vxlan-mesh down ip link set vxlan-mesh down post-down ip link del vxlan-mesh || true auto eth0.{{ raspberry_clientvlan }} iface eth0.{{ raspberry_clientvlan }} inet manual auto br-{{ ffmuc_segment }} iface br-{{ ffmuc_segment }} inet dhcp bridge-ports bat-{{ ffmuc_segment }} eth0.{{ raspberry_clientvlan }} pre-up /usr/sbin/batctl ra BATMAN_V pre-up /sbin/ip link add dummy-{{ ffmuc_segment }} type dummy pre-up /sbin/ip link set address $(ip -br l | grep eth0 | egrep -o '([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})' | head -1) dev dummy-{{ ffmuc_segment }} pre-up /sbin/ip link set dummy-{{ ffmuc_segment }} up pre-up /usr/sbin/batctl meshif bat-{{ ffmuc_segment }} if add dummy-{{ ffmuc_segment }} pre-up /sbin/ip link set bat-{{ ffmuc_segment }} up pre-up /usr/sbin/batctl meshif bat-{{ ffmuc_segment }} gw_mode client pre-up /sbin/ip link set address $(ip -br l | grep eth0 | egrep -o '([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})' | head -1) dev bat-{{ ffmuc_segment }} post-up /sbin/ip link set address $(ip -br l | grep eth0 | egrep -o '([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})' | head -1) dev br-{{ ffmuc_segment }}
- ~/ansible/roles/client-mesh/templates/interfaces_mesh_ohne_client.j2
# Generated by Ansible on {{ ansible_date_time.date }}, do not edit manually! # interfaces(5) file used by ifup(8) and ifdown(8) # Please note that this file is written to be used with dhcpcd # For static IP, consult /etc/dhcpcd.conf and 'man dhcpcd.conf' # Include files from /etc/network/interfaces.d: # source-directory /etc/network/interfaces.d auto eth0 iface eth0 inet dhcp auto eth0.{{ raspberry_meshvlan }} iface eth0.{{ raspberry_meshvlan }} inet manual pre-up /sbin/ip link add vxlan-mesh type vxlan id {{ ffmuc_vxlan_id }} group ff02::15c dstport 4789 port 32768 61000 no udpcsum udp6zerocsumtx udp6zerocsumrx dev eth0.{{ raspberry_meshvlan }} || true up /sbin/ip link set vxlan-mesh up post-up /usr/sbin/batctl ra BATMAN_V post-up /usr/sbin/batctl meshif bat-{{ ffmuc_segment }} if add vxlan-mesh down ip link set vxlan-mesh down post-down ip link del vxlan-mesh || true auto br-{{ ffmuc_segment }} iface br-{{ ffmuc_segment }} inet dhcp bridge-ports bat-{{ ffmuc_segment }} pre-up /usr/sbin/batctl ra BATMAN_V pre-up /sbin/ip link add dummy-{{ ffmuc_segment }} type dummy pre-up /sbin/ip link set address $(ip -br l | grep eth0 | egrep -o '([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})' | head -1) dev dummy-{{ ffmuc_segment }} pre-up /sbin/ip link set dummy-{{ ffmuc_segment }} up pre-up /usr/sbin/batctl meshif bat-{{ ffmuc_segment }} if add dummy-{{ ffmuc_segment }} pre-up /sbin/ip link set bat-{{ ffmuc_segment }} up pre-up /usr/sbin/batctl meshif bat-{{ ffmuc_segment }} gw_mode client pre-up /sbin/ip link set address $(ip -br l | grep eth0 | egrep -o '([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})' | head -1) dev bat-{{ ffmuc_segment }} post-up /sbin/ip link set address $(ip -br l | grep eth0 | egrep -o '([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})' | head -1) dev br-{{ ffmuc_segment }}
- ~/ansible/roles/client-mesh/templates/rclocal_both.j2
#!/bin/sh -e # Generated by Ansible on {{ ansible_date_time.date }}, do not edit manually! # # rc.local # # This script is executed at the end of each multiuser runlevel. # Make sure that the script will "exit 0" on success or any other # value on error. # # In order to enable or disable this script just change the execution # bits. # # By default this script does nothing. # Print the IP address _IP=$(hostname -I) || true if [ "$_IP" ]; then printf "My IP address is %s\n" "$_IP" fi sleep 10; /sbin/brctl addif br-{{ ffmuc_segment }} wlan0 /usr/sbin/batctl hardif mesh-vpn throughput_override 10000 exit 0
- ~/ansible/roles/client-mesh/templates/rclocal_vxlan.j2
#!/bin/sh -e # Generated by Ansible on {{ ansible_date_time.date }}, do not edit manually! # # rc.local # # This script is executed at the end of each multiuser runlevel. # Make sure that the script will "exit 0" on success or any other # value on error. # # In order to enable or disable this script just change the execution # bits. # # By default this script does nothing. # Print the IP address _IP=$(hostname -I) || true if [ "$_IP" ]; then printf "My IP address is %s\n" "$_IP" fi /usr/sbin/batctl hardif mesh-vpn throughput_override 10000 exit 0
Rolle "final"
Tasks
- ~/ansible/roles/final/tasks/main.yml
--- # Reboot nach Abschluss der Konfiguration unseres Offloaders - include: reboot.yml # abschließender Reboot nach Fertigstellung ... # YML Ende
- ~/ansible/roles/final/tasks/reboot.yml
--- - name: "Reboot nach Abschluss der Konfiguration unseres Offloaders" ansible.builtin.reboot: ...
Download des auf Debian Buster basierenden Raspbian
Nachdem es aktuell10) noch kein fertiges Gluon Image für das Raspberry PI 4B gibt, holen wir uns nun das aktuelle Raspberry Pi OS (früher unter dem Namen Raspbian bekannt) auf unseren Rechner. Dies hat mitunter auch noch den Charme, dass wir bei Bedarf alle normalen Anwendungen wie Webserver, Chatserver oder z.B. den Unifi-Controller einfach installieren können.
Eine Anleitung zur manuellen Installation findet man auf der offiziellen Raspbian Seite.
$ wget https://downloads.raspberrypi.org/raspios_lite_arm64/images/raspios_lite_arm64-2022-01-28/2022-01-28-raspios-bullseye-arm64-lite.zip{,.sha256}
Bevor wir nun das Archiv entpacken überprüfen wir noch die Integrität der heruntergeladenen Datei. Hierzu berechnen wir erst einmal die SHA256-Prüfsumme der Datei raspbian_lite_latest.
$ sha256sum --check 2022-01-28-raspios-bullseye-arm64-lite.zip.sha256 2022-01-28-raspios-bullseye-arm64-lite.zip: OK
Da der SHA256-Prüfsummencheck positiv erfolgreich war und mit einem OK bestätigt wurde, können wir nun das Archiv entpacken.
$ unzip 2022-01-28-raspios-bullseye-arm64-lite.zip
Archive: 2022-01-28-raspios-bullseye-arm64-lite.zip inflating: 2022-01-28-raspios-bullseye-arm64-lite.img
Kopieren des Raspbian Images auf die microSD-Karte
Nun können wir das Image auf die MicroSD Karte, die wir später in den Raspberry 4B stecken kopieren. Wir werfen also am besten einmal einen Blick in das syslog unseres Arbeitsrechners und erkennen so das Device unserer Speicherkarte.
# tail -f /var/log/messages
bzw.
$ sudo tail -f /var/log/syslog
Sep 5 21:10:57 Djangos-ThinkPad-X230 kernel: [12795.867603] mmc0: new high speed SDHC card at address aaaa Sep 5 21:10:57 Djangos-ThinkPad-X230 kernel: [12795.868313] mmcblk0: mmc0:aaaa SC16G 14.8 GiB Sep 5 21:10:57 Djangos-ThinkPad-X230 kernel: [12795.871017] mmcblk0: p1 p2 Sep 5 21:10:58 Djangos-ThinkPad-X230 kernel: [12796.199093] FAT-fs (mmcblk0p1): Volume was not properly unmounted. Some data may be corrupt. Please run fsck. Sep 5 21:10:58 Djangos-ThinkPad-X230 systemd[1]: Finished Clean the /media/django/boot mount point. Sep 5 21:10:58 Djangos-ThinkPad-X230 udisksd[976]: Mounted /dev/mmcblk0p1 at /media/django/boot on behalf of uid 1001 Sep 5 21:10:58 Djangos-ThinkPad-X230 kernel: [12796.302402] EXT4-fs (mmcblk0p2): recovery complete Sep 5 21:10:58 Djangos-ThinkPad-X230 kernel: [12796.303545] EXT4-fs (mmcblk0p2): mounted filesystem with ordered data mode. Opts: (null) Sep 5 21:10:58 Djangos-ThinkPad-X230 systemd[1]: Finished Clean the /media/django/rootfs mount point. Sep 5 21:10:58 Djangos-ThinkPad-X230 udisksd[976]: Mounted /dev/mmcblk0p2 at /media/django/rootfs on behalf of uid 1001 Sep 5 21:11:09 Djangos-ThinkPad-X230 gnome-terminal-[8119]: g_menu_insert_item: assertion 'G_IS_MENU_ITEM (item)' failed
In dem gezeigtem Fall handelt es sich also um die Gerätedatei /dev/mmcblk0
. Wir wissen also wie wir nun die zuvor heruntergeladene Debian Buster Image-Datei auf die MicroSD-Karte kopieren müssen. In der Regel hat der „normale Nutzer“ keine Rechte um diese Gerätedatei anzusprechen, wir müssen also als Benutzer root oder mir den Rechten des Benutzers root die Gerätedatei /dev/mmcblk0
in diesem Konfigurationsbeispiel ansprechen.
# dd if=/home/django/Freifunk/2022-01-28-raspios-bullseye-arm64-lite.img of=/dev/mmcblk0 bs=4M status=progress conv=fsync
bzw.
$ sudo dd if=/home/django/Freifunk/2022-01-28-raspios-bullseye-arm64-lite.img of=/dev/mmcblk0 bs=4M status=progress conv=fsync
Da wir später weder Tastatur noch Monitor an unseren Raspberry 4B anstecken wollen, diesen demnach im headless-Mode betreiben wollen und werden, legen wir noch eine Datei /boot/ssh
auf der SD-Karte ab. Nach dem erneuten Anstecken der MicroSD-Karte wir der Speicher in der Regel im Verzeichnis /run/media/
oder auch /media/
gemountet. Zum Anlagen der betreffenden Datei ssh
in dem Verzeichnis reicht also folgender Aufruf, bei dem wir den Usernamen natürlich unseren Gegebenheiten entsprechend anpassen.:
# touch /run/media/django/boot/ssh
bzw.
$ touch /media/django/boot/ssh
Anschliessend können wir nach einem unmounten des Gerätes /dev/sdb
die Micro-SD-Karte in den Kartenslot des Raspberry 4B stecken und den Kleinstcomputer mit dem Netzwerk sowie dem zugehörigen Netzteil verbinden und starten.
Ändern des Default-Passwortes und kopieren des SSH-Public-Keys auf den Raspberry 4
Der Benutzername lautet pi
und das Passwort raspberry
. Das Passwort dieses Nutzers ändern wir nun als erstes ab, da sonst die Gefahr besteht, dass Fremde sich unseres Offloaders bemächtigen!
Wir ändern also das Default-Passwort gleich mal ab und packen auch unseren SSH-Public-key auf den Raspberry 4B. Da wir die IP-Adresse, die unser Raspberry vom DHCP-Server zugewiesen bekommt in unserer SSH-Client-Konfigurationsdatei bereits hinterlegt haben, können wir nun den RaspBerry 4B direkt über den definierten Namen raspberry-ansible
ansprechen.
$ ssh -l pi raspberry-ansible -o IdentitiesOnly=yes "passwd" && \ ssh-copy-id -i ~/.ssh/id_ed25519_ffmuc.pub -o IdentitiesOnly=yes pi@raspberry-ansible
Alternativ dazu müssten wir den Raspberry 4B über die IP-Adresse ansprechen, die dieser zugewiesen bekommt. In dem folgenden Beispiel wäre das die IP-Adresse: 192.168.0.25:
$ ssh -l pi 192.168.0.25 -o IdentitiesOnly=yes "passwd" && \ ssh-copy-id -i ~/.ssh/id_ed25519_ffmuc.pub -o IdentitiesOnly=yes pi@192.168.0.25
In dem folgenden Konfigurationsbeispiel vergeben wir für den Benutzer pi
das Passwort gECzebzn7GYSLvXueECAxeGm7l7
. Beim Ändern des bestehenden Passwortes müssen wir einmal das Default-Passwort raspberry
eingeben und dann 2x das neue gECzebzn7GYSLvXueECAxeGm7l7
. Beim Kopieren des Public-Keys müssen wir dann einmalig das neue geänderte Passwort gECzebzn7GYSLvXueECAxeGm7l7
verwenden.
The authenticity of host '10.0.10.29 (10.0.10.29)' can't be established. ECDSA key fingerprint is SHA256:vXhdvud24tyTUtOan4XeTZ7GzxZDQn9Rj0mxuhimkH4. Are you sure you want to continue connecting (yes/no/[fingerprint])? yes Warning: Permanently added '10.0.10.29' (ECDSA) to the list of known hosts. pi@10.0.10.29's password: Current password: raspberry New password: gECzebzn7GYSLvXueECAxeGm7l7 Retype new password: gECzebzn7GYSLvXueECAxeGm7l7 passwd: password updated successfully Changing password for pi. /usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/home/django/.ssh/id_ed25519_freifunk.pub" /usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed /usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys pi@10.0.10.29's password: Number of key(s) added: 1 Now try logging into the machine, with: "ssh -o 'IdentitiesOnly=yes' 'pi@raspberry-ansible'" and check to make sure that only the key(s) you wanted were added.
$ ssh raspberry-ansible
Linux raspberrypi 5.4.51-v7l+ #1333 SMP Mon Aug 10 16:51:40 BST 2020 armv7l The programs included with the Debian GNU/Linux system are free software; the exact distribution terms for each program are described in the individual files in /usr/share/doc/STERNCHEN/copyright. Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent permitted by applicable law. Wi-Fi is currently blocked by rfkill. Use raspi-config to set the country before use. pi@raspberrypi:~ $
Starten des Ansible-Playbooks
Beim Abarbeiten des ansible-playbook werden zur Konfiguration des Offloaders und dessen Komponenten/Dienste folgende Parameter benötigt:
- Batman-Release (Version) der zum Einsatz kommen soll.
- Segment/Domäne in dem der Offloader betrieben werden soll
- Angaben zur Freifunk Karte zur Darstellung
- Hostname des Offloaders
- Kontakt-Adresse des Node-Betreibers
- Geographische Breitengrad des Raspberry Offloaders
- Geographische Längengrad des Raspberry Offloaders
- Funktionen, die der Raspberry Offloader noch ausführen soll:
- Soll der Raspberry Offloader ein WLAN ausstrahlen (SSID leitet sich vom Segment-Namen ab)?
- Soll der Raspberry Offloader ein Client-VLAN zur Verfügung stellen, wenn ja wie lautet die VLAN-ID?
- Soll der Raspberry Offloader ein Mesh-VLAN zur Verfügung stellen, wenn ja wie lautet die VLAN-ID?
- Ist an dem Raspberry ein OLE-Display von AZDelivery verbaut/angeschlossen?
wireguard-offloader.yml
In dem tar.gz-Archiv des Playbooks ist seit Version v4 11) folgendes ansible-playbooks enthalten: wireguard-offloader.yml.yml
Hier werden die zur Konfiguration benötigten Parameter nicht beim Aufruf des Playbooks abgefragt, sondern in zugehörigen Inventory-Datei hinterlegt. Das ist im ersten Schritt für den ungeübten Ansible-Nutzer zwar augenscheinlich aufwändiger, hat aber den Vorteil, dass man die zur Konfiguration benötigten Parameter immer sofort „zur Hand“ hat.
In der Host-spezifischen Konfigurationsdatei sind diese Parameter entsprechend zu hinterlegen. Folgendes Beispiel zeigt dies für den Host mit dem Namen rpb4-ol-b aus dem Inventory.
$ vim ~/ansible/inventories/production/host_vars/rpb4-ol-b/individual_host_specification
# IP-Adresse unseres Raspberry in unserem eigenen lokalen Netzwerk
# stationäre schwarzes Plastikgehäuse Raspberry 4B mit PoE-HAT und Display
# MAC: dc:a6:32:22:f0:f2
ansible_ssh_host: 192.168.0.22
ansible_port: 22
ansible_user: pi
ansible_ssh_private_key_file: ~/.ssh/id_ed25519_freifunk
#
batman_adv_version: "2022.1"
ffmuc_segment: "muc_ost"
ffmuc_gateway: "gw06"
raspberry_hostname: "ff_pliening_rpb4_ol_v6"
node_contact_address: "hier entlang => https://bit.ly/2VxGoXp"
raspberry_latitude: "48.198757565"
raspberry_longitude: "11.798020899"
raspberry_wifi: "true"
raspberry_clientvlan: "4"
raspberry_meshvlan: "2"
raspberry_oled: "false"
Diese passen wir natürlich noch auf unsere lokale Umgebung hin an.
Playbook Lauf
Nachdem wir die Informationen in dem Ansible-Playbook hinterlegt haben, können wir wie gewohnt das Ansible-Scriptes ausführen.
$ ansible-playbook ~/ansible/wireguard-offloader.yml
PLAY [raspi_offloader.yml] *********************************************************************************************************************************
TASK [Gathering Facts] *************************************************************************************************************************************
ok: [raspi_offloader]
TASK [basic : Hostname ändern] *****************************************************************************************************************************
changed: [raspi_offloader]
TASK [basic : Template Konfigurationsdatei für /etc/hosts an Ort und Stelle kopieren und Variablen anpassen] ***********************************************
changed: [raspi_offloader]
TASK [basic : Beschreibung des User 'pi' anpassen] *********************************************************************************************************
changed: [raspi_offloader]
TASK [basic : Service rfkill am Raspberry deaktivieren] ****************************************************************************************************
changed: [raspi_offloader]
TASK [basic : Update und Upgrade der APT-Paket] ************************************************************************************************************
[WARNING]: Updating cache and auto-installing missing dependency: python-apt
changed: [raspi_offloader]
TASK [basic : Reboot nach update] **************************************************************************************************************************
changed: [raspi_offloader]
TASK [batman : *BATMAN Installation* : Download des aktuellen BATMAN Archives] *****************************************************************************
changed: [raspi_offloader]
TASK [batman : *BATMAN Installation* : Entpacken des BATMAN-Archives] **************************************************************************************
changed: [raspi_offloader]
TASK [batman : *BATMAN compile* : Installation des Dynamic Kernel Module Support Framework und der Header Files für den Raspberry Pi OS Linux Kernel] ******
changed: [raspi_offloader]
TASK [batman : *BATMAN compile* : Rebuild BATMAN Kernel Header Dateien] ************************************************************************************
fatal: [raspberry-wireguard]: FAILED! => {"changed": false, "cmd": "/usr/bin/make scripts", "msg": "make: *** No rule to make target 'scripts'. Stop.", "rc": 2, "stderr": "make: *** No rule to make target 'scripts'. Stop.\n", "stderr_lines": ["make: *** No rule to make target 'scripts'. Stop."], "stdout": "", "stdout_lines": []}
...ignoring
TASK [batman : *BATMAN compile* : Anlegen der dkms.conf für Dynamic Kernel Module Support] *****************************************************************
changed: [raspi_offloader]
TASK [batman : *BATMAN compile* : Dynamic Kernel Module Support hinzufügen] ********************************************************************************
changed: [raspi_offloader]
TASK [batman : *BATMAN compile* : Dynamic Kernel Module bauen] *********************************************************************************************
changed: [raspi_offloader]
TASK [batman : *BATMAN compile* : BATMAN Dynamic Kernel Module installieren] *******************************************************************************
changed: [raspi_offloader]
TASK [batman : *BATMAN load-modules* : Laden der BATMAN Dynamic Kernel Module beim Booten sicherstellen] ***************************************************
changed: [raspi_offloader]
TASK [batman : *BATMAN load-modules* : dummy Modul laden] **************************************************************************************************
changed: [raspi_offloader]
TASK [batman : *BATMAN load-modules* : BATMAN-ADV Modul laden] *********************************************************************************************
changed: [raspi_offloader]
TASK [batman : *buster-backport* : PGP-Schlüssel 04EE7237B7D453EC für buster-backports installieren] *******************************************************
changed: [raspi_offloader]
TASK [batman : *buster-backport* : PGP-Schlüssel 648ACFD622F3D138 für buster-backports installieren] *******************************************************
changed: [raspi_offloader]
TASK [batman : *buster-backport* : buster-backports dem System bekannt machen] *****************************************************************************
changed: [raspi_offloader]
TASK [batman : *buster-backport* : APT-Cache aktualisieren] ************************************************************************************************
changed: [raspi_offloader]
TASK [batman : *utils-installation* : Installation der bridge-utils] ***************************************************************************************
changed: [raspi_offloader]
TASK [batman : *utils-installation* : Installation der bridge-utils] ***************************************************************************************
changed: [raspi_offloader]
TASK [batman : *BATMAN-ADV* : Aktivierung von BATMAN_V] ****************************************************************************************************
changed: [raspi_offloader]
TASK [batman : *BATMAN-ADV Interfaces* : Konfiguration des Interfaces] *************************************************************************************
changed: [raspi_offloader]
TASK [batman : *BATMAN Installation* : Reboot nach Ende der BATMAN Installationsschritte] ******************************************************************
changed: [raspi_offloader]
TASK [wireguard : *wireguard* : Installation von wireguard] ************************************************************************************************
changed: [raspi_offloader]
TASK [wireguard : *wireguard* : Schlüsselmaterial erstellen] ***********************************************************************************************
changed: [raspi_offloader]
TASK [wireguard : *wireguard* : Zugriffsrechte des Private Keys anpassen] **********************************************************************************
changed: [raspi_offloader]
TASK [wireguard : *wireguard : *wireguard* : Zugriffsrechte des Public Keys anpassen] **********************************************************************
changed: [raspi_offloader]
TASK [wireguard : *wireguard : *wireguard* : lokale link-local IPv6 Adresse aus dem PUBLIC-Key erzeugen] ***************************************************
changed: [raspi_offloader]
TASK [wireguard : *wireguard* : private-key einlesen und in Variable übergeben] ****************************************************************************
changed: [raspi_offloader]
TASK [wireguard : *wireguard* : public-key einlesen und in Variable übergeben] *****************************************************************************
changed: [raspi_offloader]
TASK [wireguard : *wireguard* : Socket ermitteln] **********************************************************************************************************
skipping: [raspberry-wireguard] => (item={'key': 'muc_cty', 'value': 40002})
skipping: [raspberry-wireguard] => (item={'key': 'muc_nord', 'value': 40003})
ok: [raspberry-wireguard] => (item={'key': 'muc_ost', 'value': 40004})
skipping: [raspberry-wireguard] => (item={'key': 'muc_sued', 'value': 40005})
skipping: [raspberry-wireguard] => (item={'key': 'muc_west', 'value': 40006})
skipping: [raspberry-wireguard] => (item={'key': 'uml_nord', 'value': 40007})
skipping: [raspberry-wireguard] => (item={'key': 'uml_ost', 'value': 40008})
skipping: [raspberry-wireguard] => (item={'key': 'uml_sued', 'value': 40009})
skipping: [raspberry-wireguard] => (item={'key': 'uml_west', 'value': 40010})
skipping: [raspberry-wireguard] => (item={'key': 'gauting', 'value': 40012})
skipping: [raspberry-wireguard] => (item={'key': 'freising', 'value': 40013})
skipping: [raspberry-wireguard] => (item={'key': 'welt', 'value': 40011})
TASK [wireguard : *wireguard* : link-local des Gateways ermitteln] ******************************************************************************************
ok: [raspberry-wireguard] => (item={'key': 'gw04', 'value': 'fe80::27c:16ff:fec0:6c74'})
skipping: [raspberry-wireguard] => (item={'key': 'gw05', 'value': 'fe80::281:8eff:fef0:73aa'})
TASK [wireguard : *wireguard* : publickey des Gateways ermitteln] *******************************************************************************************
ok: [raspberry-wireguard] => (item={'key': 'gw04', 'value': 'TszFS3oFRdhsJP3K0VOlklGMGYZy+oFCtlaghXJqW2g='})
skipping: [raspberry-wireguard] => (item={'key': 'gw05', 'value': 'igyqOmWiz4EZxPG8ZzU537MnHhaqlwfa7HarB3KmnEg='})
TASK [wireguard : *wireguard* : Konfigurationsdatei des wireguard-Tunnels erzeugen] *************************************************************************
changed: [raspi_offloader]
TASK [wireguard : *wireguard* : systemd unit file für broker -Information anlegen] **************************************************************************
changed: [raspi_offloader]
TASK [wireguard : *wireguard* : Service broker starten beim Booten starten] *********************************************************************************
changed: [raspi_offloader]
TASK [wireguard : *wireguard* : Service wireguard via systemd starten] **************************************************************************************
changed: [raspi_offloader]
TASK [wireguard : *wireguard* : lokale link-local IPv6 Adresse aus dem PUBLIC-Key erzeugen] *****************************************************************
changed: [raspi_offloader]
TASK [wireguard : *wireguard* : checkupscript zum Testen der wireguard-Verbindung anlegen] ******************************************************************
changed: [raspi_offloader]
TASK [wireguard : *wireguard* : Ausführungsrechte des Bash-Scripts anpassen] ********************************************************************************
changed: [raspi_offloader]
TASK [wireguard : *wireguard* : crontab für minütlichen checkup der wireguard-Verbindung anlegen] ***********************************************************
changed: [raspi_offloader]
TASK [Installation von FASTD] *******************************************************************************************************************************
changed: [raspi_offloader]
TASK [Verzeichnis für fastd- Konfigurationsdatei anlegen] ***************************************************************************************************
changed: [raspi_offloader]
TASK [Schlüssel für fastd erstellen] ************************************************************************************************************************
changed: [raspi_offloader]
TASK [vxlan : *VXLAN* : Paketfilter anpassen - Eingehenden VXLAN Verkehr auf dem Mesh-Interface erlauben] ***************************************************
changed: [raspi_offloader]
TASK [vxlan : *VXLAN* : VXLAN-ID des gewählten Segments ermitteln] ******************************************************************************************
skipping: [raspberry-wireguard] => (item={'key': 'muc_cty', 'value': 3836090})
skipping: [raspberry-wireguard] => (item={'key': 'muc_nord', 'value': 1920014})
ok: [raspberry-wireguard] => (item={'key': 'muc_ost', 'value': 12097488})
skipping: [raspberry-wireguard] => (item={'key': 'muc_sued', 'value': 12815947})
skipping: [raspberry-wireguard] => (item={'key': 'muc_west', 'value': 29149})
skipping: [raspberry-wireguard] => (item={'key': 'uml_nord', 'value': 403289})
skipping: [raspberry-wireguard] => (item={'key': 'uml_ost', 'value': 12645856})
skipping: [raspberry-wireguard] => (item={'key': 'uml_sued', 'value': 12090508})
skipping: [raspberry-wireguard] => (item={'key': 'uml_west', 'value': 935867})
skipping: [raspberry-wireguard] => (item={'key': 'gauting', 'value': 4681119})
skipping: [raspberry-wireguard] => (item={'key': 'freising', 'value': 4669918})
skipping: [raspberry-wireguard] => (item={'key': 'welt', 'value': 4831583})
TASK [vxlan : *VXLAN* : link-local des Gateways ermitteln] **************************************************************************************************
ok: [raspberry-wireguard] => (item={'key': 'gw04', 'value': 'fe80::27c:16ff:fec0:6c74'})
skipping: [raspberry-wireguard] => (item={'key': 'gw05', 'value': 'fe80::281:8eff:fef0:73aa'})
TASK [vxlan : *VXLAN* : lokale link-local IPv6 Adresse aus dem PUBLIC-Key erzeugen] *************************************************************************
changed: [raspi_offloader]
TASK [vxlan : *VXLAN* : Startupdatei für VXLAN kopieren] ****************************************************************************************************
changed: [raspi_offloader]
TASK [vxlan : *VXLAN* : Ausführungsrechte des Bash-Scripts anpassen] ****************************************************************************************
changed: [raspi_offloader]
TASK [vxlan : *VXLAN* : systemd-unitfile anlegen] ***********************************************************************************************************
changed: [raspi_offloader]
TASK [vxlan : *VXLAN* : Neues Unitfile dem systemd bekannt geben] *******************************************************************************************
changed: [raspi_offloader]
TASK [vxlan : *VXLAN* : Service vxlan via systemd starten] **************************************************************************************************
changed: [raspi_offloader]
TASK [ext-respondd : Installation der Pakete git und python3-netifaces] *************************************************************************************
changed: [raspi_offloader]
TASK [ext-respondd : Repo ext-respondd klonen] **************************************************************************************************************
changed: [raspi_offloader]
TASK [ext-respondd : Systemd Startdatei für respondd kopieren] **********************************************************************************************
changed: [raspi_offloader]
TASK [ext-respondd : Erstellen der resondd Konfigurationsdatei alias.json] **********************************************************************************
changed: [raspi_offloader]
TASK [ext-respondd : Erstellen der resondd Konfigurationsdatei config.json] *********************************************************************************
changed: [raspi_offloader]
TASK [ext-respondd : Service ext-respondd beim Booten starten] **********************************************************************************************
changed: [raspi_offloader]
TASK [hostapd : Paket hostapd für WLAN installieren] ********************************************************************************************************
changed: [raspi_offloader]
TASK [hostapd : hostapd konfigurieren] **********************************************************************************************************************
changed: [raspi_offloader]
TASK [hostapd : hostapd Konfigurationsdatei anlegen] ********************************************************************************************************
changed: [raspi_offloader]
TASK [hostapd : wlan0 in Bridge packen] *********************************************************************************************************************
changed: [raspi_offloader]
TASK [hostapd : Service hostapd beim Booten und jetzt starten und das Laden der Unit Datei vom Service hostapd ermöglichen] *********************************
changed: [raspi_offloader]
TASK [client-mesh : Konfiguration des Client-VLAN ohne Mesh-Netz] *******************************************************************************************
changed: [raspi_offloader]
TASK [client-mesh : vxlan_id für ausgewähltes Segment ermitteln] ********************************************************************************************
skipping: [raspberry-wireguard] => (item={'key': 'muc_cty', 'value': 10758607})
skipping: [raspberry-wireguard] => (item={'key': 'muc_nord', 'value': 15521492})
ok: [raspberry-wireguard] => (item={'key': 'muc_ost', 'value': 2948862})
skipping: [raspberry-wireguard] => (item={'key': 'muc_sued', 'value': 8599288})
skipping: [raspberry-wireguard] => (item={'key': 'muc_west', 'value': 7318933})
skipping: [raspberry-wireguard] => (item={'key': 'uml_nord', 'value': 5705961})
skipping: [raspberry-wireguard] => (item={'key': 'uml_ost', 'value': 4892713})
skipping: [raspberry-wireguard] => (item={'key': 'uml_sued', 'value': 16544703})
skipping: [raspberry-wireguard] => (item={'key': 'uml_west', 'value': 16677749})
skipping: [raspberry-wireguard] => (item={'key': 'gauting', 'value': 16175732})
skipping: [raspberry-wireguard] => (item={'key': 'freising', 'value': 12937858})
skipping: [raspberry-wireguard] => (item={'key': 'welt', 'value': 16306234})
TASK [client-mesh : Konfiguration des Mesh-VLAN ohne Client-VLAN] *******************************************************************************************
skipping: [raspi_offloader]
TASK [client-mesh : Konfiguration von Mesh- und Client-VLAN] ************************************************************************************************
changed: [raspi_offloader]
TASK [client-mesh : Konfiguration des bevorzugte Meshingpoint in BATMAN_V ohne Wifi-Nutzung] ****************************************************************
skipping: [raspi_offloader]
TASK [client-mesh : Konfiguration des bevorzugte Meshingpoint in BATMAN_V mit Wifi-Nutzung ******************************************************************
changed: [raspi_offloader]
TASK [oled : Für OLED-Konfiguration i2c-bcm2708 in /etc/modules eintragen] **********************************************************************************
changed: [raspi_offloader]
TASK [oled : Für OLED-Konfiguration i2c-dev in /etc/modules eintragen] **************************************************************************************
changed: [raspi_offloader]
TASK [oled : Installation der für das OLED benötigten Pakete] ***********************************************************************************************
changed: [raspi_offloader]
TASK [oled : Laden des Kernelmodul i2c_arm beim Booten veranlassen] *****************************************************************************************
changed: [raspi_offloader]
TASK [oled : Reboot nach Konfigurationsänderung] ************************************************************************************************************
changed: [raspi_offloader]
TASK [oled : Repo Adafruit_Python_SSD1306 klonen] ***********************************************************************************************************
changed: [raspi_offloader]
TASK [oled : Für OLED-Konfiguration Adafruit_Python_SSD1306 installieren] ***********************************************************************************
changed: [raspi_offloader]
TASK [oled : Script zur Anzeige klonen] *********************************************************************************************************************
changed: [raspi_offloader]
TASK [oled : Script zur Bandbreitenauslastung anpassen] *****************************************************************************************************
changed: [raspi_offloader]
TASK [oled : Startscript für das OLED anlegen] **************************************************************************************************************
changed: [raspi_offloader]
TASK [oled : Service oled-bandwidth beim Booten starten] ****************************************************************************************************
changed: [raspi_offloader]
TASK [final : Reboot nach Abschluss der Konfiguration unseres Offloaders] ***********************************************************************************
changed: [raspi_offloader]
PLAY RECAP *****************************************************************************************************************************
raspi_offloader : ok=80 changed=71 unreachable=0 failed=0 skipped=3 rescued=0 ignored=1
Auch hier wird nach Beendigung des Ansible-Laufs der Knoten auf der Freifunkkarte an der gewünschten Stelle auftauchen. Nach dem letzten Reboot, der automatisch ausgeführt wird, finden wir unseren Offloader auf der Freifunkkarte: