Dies ist eine alte Version des Dokuments!
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
ACHTUNG: Artikel in Überarbeitung!!! ACHTUNG:
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:
<file bash ~/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</file>
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
<file bash ..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“</file>
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!
<code>../group_vars/ffmuc/
├── gateway_keys
├── gateway_link_adresses
├── gateway_mesh_vpn_vxlan_ids
├── global_vars
├── vxlan_ids
└── wireguard_ports</code>
Der interessierte Leser kann hier natürlich bei Interesse jeweils einen Blick hinein werfen.
$ less ~/ansible/inventories/production/group_vars/ffmuc/..
<file bash 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=“</file>
<file bash 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“</file>
<file bash 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</file>
<file bash global_vars>ansible_ssh_user: pi
dtparam: „i2c_arm=on“</file>
<file bash 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</file>
<file bash 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</file>
=== Playbook „main“ ===
<file java ~/ansible/wireguard-offloader.yml>— # Ansible Playbook für (statische) Konfiguration eines Offloader auf Basis eines Raspberry PI 4B
- name: raspi_offloader_file.yml
hosts: raspberry-wireguard
become: yes
become_user: root
roles:
- basic # Basiskonfiguration des Hosts (Host-/Username anpassen und System Updaten)
- batman # Installation und Konfiguration der BATMAN Kernel-Module
- wireguard # Installation und Konfiguration des wireguard Tunnels
- vxlan # Konfiguration von VXLAN für wireguard-Tunnel-Verbindung in Richtung Gateway
- ext-respondd # Installation und Konfiguration des ext-respondd (Statistiken für https://map.ffmuc.net)
- hostapd # Installation und Konfiguration des hostap Treibers für den WiFi-Support
- client-mesh # Grundkonfiguration von Client und/oder Meshing (V)LANs
- oled # Konfiguration eines OLEDisplays sofern eines am Respberry 4B verbaut ist
- final # Reboot nach Abschluss der Konfiguration unseres Offloaders
… # YML Ende
</file>
=== Rolle „basic“ ===
== Tasks ==
<file java ~/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 update
</file>
<file java ~/ansible/roles/basic/tasks/hostname.yml>—
- name: „Hostname ändern“
# https://docs.ansible.com/ansible/latest/modules/shell_module.html
shell:
cmd: hostnamectl set-hostname raspberry_hostname
</file>
<file java ~/ansible/roles/basic/tasks/hosts.yml>—
- name: „Template Konfigurationsdatei für /etc/hosts an Ort und Stelle kopieren und Variablen anpassen“
# https://docs.ansible.com/ansible/latest/modules/template_module.html
template:
src: templates/hosts.j2
dest: /etc/hosts
</file>
<file java ~/ansible/roles/basic/tasks/usercomment.yml>—
- name: „Beschreibung des User 'pi' anpassen“
# https://docs.ansible.com/ansible/latest/modules/user_module.htm
user:
name: pi
comment: „Raspberry Pi OS System User“
state: present
</file>
<file java ~/ansible/roles/basic/tasks/rfkill.yml>—
- name: „Service rfkill am Raspberry deaktivieren“
# https://docs.ansible.com/ansible/latest/modules/shell_module.html
shell:
cmd: rfkill unblock wifi
</file>
<file java ~/ansible/roles/basic/tasks/update.yml>—
- name: „Update und Upgrade der APT-Pakete“
# https://docs.ansible.com/ansible/latest/modules/apt_module.html
apt:
upgrade: dist
update_cache: yes
</file>
<file java ~/ansible/roles/basic/tasks/reboot.yml>—
- name: „Reboot nach update“
# https://docs.ansible.com/ansible/latest/modules/reboot_module.html
reboot:
</file>
== Templates ==
<file java ~/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
</file>
=== Rolle „batman“ ===
== Tasks ==
<file java ~/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: backport.yml # Buster-backports für Installation von batctl vorbereiten
- include: utilsinstall.yml # Installation der bridge-utils und batctl
- include: batmanstart.yml # Aktivierung von BATMAN_V
- include: interfaceconfigure.yml # Konfiguration der Interfaces
- include: reboot.yml # Rebot nach Ende des Installationsschritts
</file>
<file java ~/ansible/roles/batman/tasks/install.yml>—
- name: „*BATMAN Installation* : Download des aktuellen BATMAN Archives“
# https://docs.ansible.com/ansible/latest/modules/get_url_module.html
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: „*BATMAN Installation* : Entpacken des BATMAN-Archives“
# https://docs.ansible.com/ansible/latest/modules/unarchive_module.html
unarchive:
src: /usr/src/batman-adv-batman_adv_version.tar.gz
dest: /usr/src
remote_src: yes
</file>
<file java ~/ansible/roles/batman/tasks/compile.yml>—
- name: „*BATMAN compile* : Installation des Dynamic Kernel Module Support Framework und der Header Files für den Raspberry Pi OS Linux Kernel“
# https://docs.ansible.com/ansible/latest/modules/apt_module.html
apt:
update_cache: yes
pkg:
- dkms
- raspberrypi-kernel-headers
state: present
- name: „*BATMAN compile* : Rebuild BATMAN Kernel Header Dateien“
# https://docs.ansible.com/ansible/latest/modules/make_module.html
make:
chdir: /usr/src/linux-headers-ansible_kernel
target: scripts
ignore_errors: yes
- name: „*BATMAN compile* : Anlegen der dkms.conf für Dynamic Kernel Module Support“
# https://docs.ansible.com/ansible/latest/modules/template_module.html
template:
src: templates/dkms.j2
dest: /usr/src/batman-adv-batman_adv_version/dkms.conf
- name: „*BATMAN compile* : Dynamic Kernel Module Support hinzufügen“
# https://docs.ansible.com/ansible/latest/modules/command_module.html
command: 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: „*BATMAN compile* : Dynamic Kernel Module bauen“
# https://docs.ansible.com/ansible/latest/modules/command_module.html
command: dkms build -m batman-adv -v batman_adv_version
- name: „*BATMAN compile* : BATMAN Dynamic Kernel Module installieren“
# https://docs.ansible.com/ansible/latest/modules/command_module.html
command: dkms install -m batman-adv -v batman_adv_version
</file>
<file java ~/ansible/roles/batman/tasks/modulloads.yml>—
- name: „*BATMAN load-modules* : Laden der BATMAN Dynamic Kernel Module beim Booten sicherstellen“
# https://docs.ansible.com/ansible/latest/modules/template_module.html
template:
src: templates/batman-adv.module.j2
dest: /etc/modules-load.d/batman-adv.module.conf
- name: „*BATMAN load-modules* : dummy Modul laden“
# https://docs.ansible.com/ansible/latest/modules/modprobe_module.html
modprobe:
name: dummy
state: present
- name: „*BATMAN load-modules* : BATMAN-ADV Modul laden“
# https://docs.ansible.com/ansible/latest/modules/modprobe_module.html
modprobe:
name: batman_adv
state: present
</file>
<file java ~/ansible/roles/batman/tasks/backport.yml>—
- name: „*buster-backport* : PGP-Schlüssel 04EE7237B7D453EC für buster-backports installieren“
# https://docs.ansible.com/ansible/latest/modules/shell_module.html
shell:
cmd: apt-key adv –keyserver hkp:p80.pool.sks-keyservers.net:80 –recv-key 04EE7237B7D453EC
- name: „*buster-backport* : PGP-Schlüssel 648ACFD622F3D138 für buster-backports installieren“
# https://docs.ansible.com/ansible/latest/modules/shell_module.html
shell:
cmd: apt-key adv –keyserver hkp:p80.pool.sks-keyservers.net:80 –recv-key 648ACFD622F3D138
- name: „*buster-backport* : buster-backports dem System bekannt machen“
# https://docs.ansible.com/ansible/latest/modules/shell_module.html
shell:
cmd: echo „deb http://deb.debian.org/debian buster-backports main“ | tee /etc/apt/sources.list.d/buster-backports.list
- name: „*buster-backport* : APT-Cache aktualisieren“
# https://docs.ansible.com/ansible/latest/modules/apt_module.html
apt:
update_cache: yes
</file>
<file java ~/ansible/roles/batman/tasks/utilsinstall.yml>—
- name: „*utils-installation* : Installation der bridge-utils“
# https://docs.ansible.com/ansible/latest/modules/apt_module.html
apt:
#update_cache: yes
pkg:
- bridge-utils
- dnsutils
- vim
state: present
- name: „*utils-installation* : Installation der bridge-utils“
# https://docs.ansible.com/ansible/latest/modules/apt_module.html
apt:
#update_cache: yes
pkg:
- batctl
default_release: buster-backports
state: present
</file>
<file java ~/ansible/roles/batman/tasks/batmanstart.yml>—
- name: „*BATMAN-ADV* : Aktivierung von BATMAN_V“
# https://docs.ansible.com/ansible/latest/modules/shell_module.html
shell:
cmd: batctl ra BATMAN_V
</file>
<file java ~/ansible/roles/batman/tasks/interfaceconfigure.yml>—
- name: „*BATMAN-ADV Interfaces* : Konfiguration des Interfaces“
# https://docs.ansible.com/ansible/latest/modules/template_module.html
template:
src: templates/interfaces.j2
dest: /etc/network/interfaces
</file>
<file java ~/ansible/roles/batman/tasks/reboot.yml>—
- name: „*BATMAN Installation* : Reboot nach Ende der BATMAN Installationsschritte“
# https://docs.ansible.com/ansible/latest/modules/reboot_module.html
reboot:
</file>
== Templates ==
<file java ~/ansible/roles/batman/templates/batman-adv.module.j2>#
# Load batman-adv module on system boot
#
batman-adv
dummy
</file>
<file java ~/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“
</file>
<file java ~/ansible/roles/batman/templates/interfaces.j2># 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
</file>
=== Rolle „wireguard“ ===
== Tasks ==
<file java ~/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: checkup.yml # Wireguard überprüfen
</file>
<file java ~/ansible/roles/wireguard/tasks/install.yml>—
- name: „*wireguard* : Installation von wireguard“
# https://docs.ansible.com/ansible/latest/modules/apt_module.html
apt:
#update_cache: yes
pkg:
- wireguard
state: present
</file>
<file java ~/ansible/roles/wireguard/tasks/genkeys.yml>—
- name: „*wireguard* : Schlüsselmaterial erstellen“
# https://docs.ansible.com/ansible/latest/modules/shell_module.html
shell: /usr/bin/wg genkey | tee client_private.key | wg pubkey | tee client_public.key
args:
chdir: /etc/wireguard/
creates: client_private.key
- name: „*wireguard* : Zugriffsrechte des Private Keys anpassen“
# https://docs.ansible.com/ansible/latest/modules/file_module.html
file:
path: /etc/wireguard/client_private.key
mode: '0600'
- name: „*wireguard* : Zugriffsrechte des Public Keys anpassen“
# https://docs.ansible.com/ansible/latest/modules/file_module.html
file:
path: /etc/wireguard/client_public.key
mode: '0600'
</file>
<file java ~/ansible/roles/wireguard/tasks/genlinklocal.yml>—
- name: „*wireguard* : lokale link-local IPv6 Adresse aus dem PUBLIC-Key erzeugen“
# https://docs.ansible.com/ansible/latest/modules/shell_module.html
shell: cat /etc/wireguard/client_public.key | md5sum | sed 's/^\(..\)\(..\)\(..\)\(..\)\(..\).*$/fe80::02\1:\2ff:fe\3:\4\5/'
register: wg_node_linklocal
</file>
<file java ~/ansible/roles/wireguard/tasks/configuration.yml>—
- name: „*wireguard* : private-key einlesen und in Variable übergeben“
# https://docs.ansible.com/ansible/latest/collections/ansible/builtin/shell_module.html
shell: cat /etc/wireguard/client_private.key
register: wg_client_privatekey
- name: „*wireguard* : public-key einlesen und in Variable übergeben“
# https://docs.ansible.com/ansible/latest/collections/ansible/builtin/shell_module.html
shell: cat /etc/wireguard/client_public.key
register: wg_client_publickey
- name: „*wireguard* : Socket ermitteln“
# https://docs.ansible.com/ansible/latest/collections/ansible/builtin/set_fact_module.html
set_fact:
ffmuc_wireguard_port: „item.value“
loop: „lookup_dict_wireguard_ports“
when: „ffmuc_segment in item.key“
- name: „*wireguard* : link-local des Gateways ermitteln“
# https://docs.ansible.com/ansible/latest/collections/ansible/builtin/set_fact_module.html
set_fact:
ffmuc_wireguard_linklocal: „item.value“
loop: „lookup_dict_gw_linklocal“
when: „ffmuc_gateway in item.key“
- name: „*wireguard* : publickey des Gateways ermitteln“
# https://docs.ansible.com/ansible/latest/collections/ansible/builtin/set_fact_module.html
set_fact:
ffmuc_wireguard_gwpubkey: „item.value“
loop: „lookup_dict_gw_publickey“
when: „ffmuc_gateway in item.key“
- name: „*wireguard* : Konfigurationsdatei des wireguard-Tunnels erzeugen“
# https://docs.ansible.com/ansible/latest/modules/template_module.html
template:
src: templates/uplink.j2
dest: /etc/wireguard/wg-uplink.conf
</file>
<file java ~/ansible/roles/wireguard/tasks/brokerinform.yml>—
- name: „*wireguard* : systemd unit file für broker -Information anlegen“
# https://docs.ansible.com/ansible/latest/modules/template_module.html
template:
src: templates/broker.j2
dest: /etc/systemd/system/broker.service
- name: „*wireguard* : Service broker starten beim Booten starten“
# https://docs.ansible.com/ansible/latest/modules/systemd_module.html
systemd:
name: broker
daemon_reload: yes
state: started
enabled: yes
</file>
<file java ~/ansible/roles/wireguard/tasks/wireguardstart.yml>—
- name: „*wireguard* : Service wireguard via systemd startem“
# https://docs.ansible.com/ansible/latest/modules/systemd_module.html
systemd:
name: wg-quick@wg-uplink
daemon_reload: yes
state: started
enabled: yes
</file>
<file java ~/ansible/roles/wireguard/tasks/checkup.yml>—
- name: „*wireguard* : lokale link-local IPv6 Adresse aus dem PUBLIC-Key erzeugen“
# https://docs.ansible.com/ansible/latest/modules/shell_module.html
shell: cat /etc/wireguard/client_public.key | md5sum | sed 's/^\(..\)\(..\)\(..\)\(..\)\(..\).*$/fe80::02\1:\2ff:fe\3:\4\5/'
register: wg_node_linklocal
- name: „*wireguard* : checkupscript zum Testen der wireguard-Verbindung anlegen“
# https://docs.ansible.com/ansible/latest/modules/template_module.html
template:
src: templates/checkup.j2
dest: /usr/local/bin/checkup
- name: „*wireguard* : Ausführungsrechte des Bash-Scripts anpassen“
# https://docs.ansible.com/ansible/latest/modules/file_module.html
file:
path: /usr/local/bin/checkup
mode: '0740'
- name: „*wireguard* : crontab für minütlichen checkup der wireguard-Verbindung anlegen“
# https://docs.ansible.com/ansible/latest/modules/template_module.html
template:
src: templates/crontab.j2
dest: /etc/crontab
</file>
== Templates ==
<file java ~/ansible/roles/wireguard/templates/broker.j2># Django : 2020-12-07
[Unit]
# see man systemd.unit
Description=Inform tunnel about our wireguard-public key
Documentation=https://wiki.mailserver.guru/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
</file>
<file java ~/ansible/roles/wireguard/templates/checkup.j2>#!/bin/bash
# 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
</file>
<file java ~/ansible/roles/wireguard/templates/crontab.j2># /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
# 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
</file>
<file java ~/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
</file>
=== Rolle „vxlan“ ===
<file java ~/ansible/roles/vxlan/tasks/main.yml>— # Installation und Konfiguration von VXLAN
- include: configure.yml # VXLAN Konfigurieren
- include: vxlanstart.yml # Aktivierung des wireguard client-daemon
</file>
== Tasks ==
<file java ~/ansible/roles/vxlan/tasks/configure.yml> - name: „*VXLAN* : Paketfilter anpassen - Eingehenden VXLAN Verkehr auf dem Mesh-Interface erlauben“
# https://docs.ansible.com/ansible/latest/modules/commans_module.html
command: ip6tables -I INPUT 1 -i wg-uplink -m udp -p udp –dport 8472 -j ACCEPT
- name: „*VXLAN* : VXLAN-ID des gewählten Segments ermitteln“
# https://docs.ansible.com/ansible/latest/collections/ansible/builtin/set_fact_module.html
set_fact:
ffmuc_vxlan_id: „item.value“
loop: „lookup_dict_gw_vxlan_ids“
when: „ffmuc_segment in item.key“
- name: „*VXLAN* : link-local des Gateways ermitteln“
# https://docs.ansible.com/ansible/latest/collections/ansible/builtin/set_fact_module.html
set_fact:
ffmuc_wireguard_linklocal: „item.value“
loop: „lookup_dict_gw_linklocal“
when: „ffmuc_gateway in item.key“
- name: „*VXLAN* : lokale link-local IPv6 Adresse aus dem PUBLIC-Key erzeugen“
# https://docs.ansible.com/ansible/latest/modules/shell_module.html
shell: cat /etc/wireguard/client_public.key | md5sum | sed 's/^\(..\)\(..\)\(..\)\(..\)\(..\).*$/fe80::02\1:\2ff:fe\3:\4\5/'
register: wg_node_linklocal
- name: „*VXLAN* : Startupdatei für VXLAN kopieren“
# https://docs.ansible.com/ansible/latest/modules/template_module.html
template:
src: templates/vxlan-init.j2
dest: /usr/local/bin/vxlan
- name: „*VXLAN* : Ausführungsrechte des Bash-Scripts anpassen“
# https://docs.ansible.com/ansible/latest/modules/file_module.html
file:
path: /usr/local/bin/vxlan
mode: '0740'
</file>
<file java ~/ansible/roles/vxlan/tasks/vxlanstart.yml>—
- name: „*VXLAN* : systemd-unitfile anlegen“
# https://docs.ansible.com/ansible/latest/modules/template_module.html
template:
src: templates/systemd-service-file.j2
dest: /etc/systemd/system/vxlan.service
- name: „*VXLAN* : Neues Unitfile dem systemd bekannt geben“
# https://docs.ansible.com/ansible/latest/modules/systemd_module.html
systemd:
daemon_reexec: yes
- name: „*VXLAN* : Service vxlan via systemd starten“
# https://docs.ansible.com/ansible/latest/modules/systemd_module.html
systemd:
name: vxlan.service
daemon_reload: yes
state: started
enabled: yes
</file>
== Templates ==
<file java ~/ansible/roles/vxlan/templates/systemd-service-file.j2>[Unit]
# see man systemd.unit
Description=Bringing up VXLAN Interface
Documentation=https://wiki.mailserver.guru/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
</file>
<file bash ~/ansible/roles/vxlan/templates/vxlan-init.j2>#!/bin/bash
# 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
</file>
=== Rolle „ext-respondd“ ===
== Tasks ==
<file java ~/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
</file>
<file java ~/ansible/roles/ext-respondd/tasks/aliasgenerate.yml>—
- name: „Erstellen der resondd Konfigurationsdatei alias.json“
# https://docs.ansible.com/ansible/latest/modules/template_module.html
template:
src: templates/ext-respondd_alias.json.j2
dest: /opt/ext-respondd/alias.json
</file>
<file java ~/ansible/roles/ext-respondd/tasks/configgenerate.yml>—
- name: „Erstellen der resondd Konfigurationsdatei config.json“
# https://docs.ansible.com/ansible/latest/modules/template_module.html
template:
src: templates/ext-respondd_config.json.j2
dest: /opt/ext-respondd/config.json
</file>
<file java ~/ansible/roles/ext-respondd/tasks/copyconfig.yml>—
- name: „Systemd Startdatei für respondd kopieren“
# https://docs.ansible.com/ansible/latest/modules/shell_module.html
shell:
cmd: cp /opt/ext-respondd/ext-respondd.service.example /etc/systemd/system/ext-respondd.service
</file>
<file java ~/ansible/roles/ext-respondd/tasks/gitclone.yml>—
- name: „Repo ext-respondd klonen“
# https://docs.ansible.com/ansible/latest/modules/git_module.html
git:
repo: https://github.com/freifunkMUC/ext-respondd
dest: /opt/ext-respondd/
</file>
<file java ~/ansible/roles/ext-respondd/tasks/gitinstall.yml>—
- name: „Installation der Pakete git und python3-netifaces“
# https://docs.ansible.com/ansible/latest/modules/apt_module.html
apt:
update_cache: yes
pkg:
- git
- python3-netifaces
state: present
</file>
<file java ~/ansible/roles/ext-respondd/tasks/servicestartup.yml>—
- name: „Service ext-respondd beim Booten starten“
# https://docs.ansible.com/ansible/latest/modules/systemd_module.html
systemd:
name: ext-respondd
daemon_reload: yes
state: started
enabled: yes
</file>
== Templates ==
<file java ~/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“
}
</file>
<file java ~/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
}
</file>
=== Rolle „hostapd“ ===
== Tasks ==
<file java ~/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 das Laden der Unit Datei vom Service hostapd ermöglichen
</file>
<file java ~/ansible/roles/hostapd/tasks/configure.yml>—
- name: „hostapd konfigurieren“
# https://docs.ansible.com/ansible/latest/modules/shell_module.html
shell: echo 'DAEMON_OPTS=„-d“' » /etc/default/hostapd
when: ( raspberry_wifi == „ja“ )
</file>
<file java ~/ansible/roles/hostapd/tasks/genconfig.yml>—
- name: „hostapd Konfigurationsdatei anlegen“
# https://docs.ansible.com/ansible/latest/modules/template_module.html
template:
src: templates/hostapd.j2
dest: /etc/hostapd/hostapd.conf
when: ( raspberry_wifi == „ja“ )
</file>
<file java ~/ansible/roles/hostapd/tasks/install.yml>—
- name: „Paket hostapd für WLAN installieren“
# https://docs.ansible.com/ansible/latest/modules/apt_module.html
apt:
update_cache: yes
pkg:
- hostapd
state: present
when: ( raspberry_wifi == „ja“ )
</file>
<file java ~/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“
# https://docs.ansible.com/ansible/latest/modules/systemd_module.html
systemd:
name: hostapd
enabled: yes
masked: no
state: started
when: ( raspberry_wifi == „ja“ )
</file>
<file java ~/ansible/roles/hostapd/tasks/wlanbridging.yml>—
- name: „wlan0 in Bridge packen“
# https://docs.ansible.com/ansible/latest/modules/template_module.html
template:
src: templates/rclocal_wifi.j2
dest: /etc/rc.local
when: ( raspberry_wifi == „ja“ )
</file>
== Templates ==
<file java ~/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
</file>
<file java ~/ansible/roles/hostapd/templates/rclocal_wifi.j2>#!/bin/sh -e
#
# 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
</file>
=== Rolle „client-mesh“ ===
== Tasks ==
<file java ~/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
</file>
<file java ~/ansible/roles/client-mesh/tasks/batmanmitwifi.yml>—
- name: „Konfiguration des bevorzugte Meshingpoint in BATMAN_V mit Wifi-Nutzung“
# https://docs.ansible.com/ansible/latest/modules/template_module.html
template:
src: templates/rclocal_both.j2
dest: /etc/rc.local
when: ( raspberry_meshvlan|length > 0 ) and ( raspberry_wifi == „ja“ )
</file>
<file java ~/ansible/roles/client-mesh/tasks/batmanohnewifi.yml>—
- name: „Konfiguration des bevorzugte Meshingpoint in BATMAN_V ohne Wifi-Nutzung“
# https://docs.ansible.com/ansible/latest/modules/template_module.html
template:
src: templates/rclocal_vxlan.j2
dest: /etc/rc.local
when: ( raspberry_meshvlan|length > 0 ) and ( raspberry_wifi != „ja“ )
</file>
<file java ~/ansible/roles/client-mesh/tasks/clientohnemesh.yml>django@Djangos-ThinkPad-X230:~$ cat ~/ansible/roles/client-mesh/tasks/clientohnemesh.yml
—
- name: „Konfiguration des Client-VLAN ohne Mesh-Netz“
# https://docs.ansible.com/ansible/latest/modules/template_module.html
template:
src: templates/interfaces_client_ohne_mesh.j2
dest: /etc/network/interfaces
when: ( raspberry_clientvlan|length > 0 ) and ( raspberry_meshvlan|length == 0 )
</file>
<file java ~/ansible/roles/client-mesh/tasks/getvxlanid.yml>—
- name: „vxlan_id für ausgewähltes Segment ermitteln“
# https://docs.ansible.com/ansible/latest/modules/set_fact_module.html
set_fact:
ffmuc_vxlan_id: „item.value“
loop: „lookup_dict_vxlan_ids“
when: „ffmuc_segment in item.key“
</file>
<file java ~/ansible/roles/client-mesh/tasks/meshohneclient.yml>—
- name: „Konfiguration des Mesh-VLAN ohne Client-VLAN“
# https://docs.ansible.com/ansible/latest/modules/template_module.html
template:
src: templates/interfaces_mesh_ohne_client.j2
dest: /etc/network/interfaces
when: ( raspberry_clientvlan|length == 0 ) and ( raspberry_meshvlan|length > 0 )
</file>
<file java ~/ansible/roles/client-mesh/tasks/meshundclient.yml>—
- name: „Konfiguration von Mesh- und Client-VLAN“
# https://docs.ansible.com/ansible/latest/modules/template_module.html
template:
src: templates/interfaces_mesh_mit_client.j2
dest: /etc/network/interfaces
when: ( raspberry_clientvlan|length > 0 ) and ( raspberry_meshvlan|length > 0 )
</file>
== Templates ==
<file java ~/ansible/roles/client-mesh/templates/interfaces_client_ohne_mesh.j2># 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
</file>
<file java ~/ansible/roles/client-mesh/templates/interfaces_mesh_mit_client.j2># 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
</file>
<file java ~/ansible/roles/client-mesh/templates/interfaces_mesh_ohne_client.j2># 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
</file>
<file bash ~/ansible/roles/client-mesh/templates/rclocal_both.j2>#!/bin/sh -e
#
# 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
</file>
<file bash ~/ansible/roles/client-mesh/templates/rclocal_vxlan.j2>#!/bin/sh -e
#
# 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
</file>
=== Rolle „oled“ ===
== Tasks ==
<file java ~/ansible/roles/oled/tasks/main.yml>— # Konfiguration eines OLEDisplays sofern eines am Respberry 4B verbaut ist
- include: i2c-bcm2708.yml # Für OLED-Konfiguration i2c-bcm2708 in /etc/modules eintragen
- include: i2c-dev.yml # Für OLED-Konfiguration i2c-dev in /etc/modules eintragen
- include: packages.yml # Installation der für das OLED benötigten Pakete
- include: i2c_arm.yml # Laden des Kernelmodul i2c_arm beim Booten veranlassen
- include: reboot.yml # Reboot nach Konfigurationsänderung
- include: adafruitclone.yml # Repo Adafruit_Python_SSD1306 klonen
- include: adafruitconfig.yml # Für OLED-Konfiguration Adafruit_Python_SSD1306 installieren
- include: scriptclone.yml # Script zur Anzeige klonen
- include: scriptconfig.yml # Script zur Bandbreitenauslastung anpassen
- include: scriptstart.yml # Startscript für das OLED anlegen
- include: scriptstartup.yml # Service oled-bandwidth beim Booten starten
</file>
<file java ~/ansible/roles/oled/tasks/adafruitclone.yml>—
- name: „Repo Adafruit_Python_SSD1306 klonen“
# https://docs.ansible.com/ansible/latest/modules/git_module.html
git:
repo: https://github.com/adafruit/Adafruit_Python_SSD1306.git
dest: /usr/local/src/Adafruit_Python_SSD1306
when: ( raspberry_oled == „ja“ )
</file>
<file java ~/ansible/roles/oled/tasks/adafruitconfig.yml>—
- name: „Für OLED-Konfiguration Adafruit_Python_SSD1306 installieren“
# https://docs.ansible.com/ansible/latest/modules/shell_module.html
shell: cd /usr/local/src/Adafruit_Python_SSD1306 && python3 setup.py install && pip3 install Adafruit-BBIO
when: ( raspberry_oled == „ja“ )
</file>
<file java ~/ansible/roles/oled/tasks/i2c_arm.yml>—
- name: „Laden des Kernelmodul i2c_arm beim Booten veranlassen“
# https://docs.ansible.com/ansible/latest/modules/template_module.html
template:
src: templates/config.j2
dest: /boot/config.txt
when: ( raspberry_oled == „ja“ )
</file>
<file java ~/ansible/roles/oled/tasks/i2c-bcm2708.yml>—
- name: „Für OLED-Konfiguration i2c-bcm2708 in /etc/modules eintragen“
# https://docs.ansible.com/ansible/latest/modules/shell_module.html
shell: echo i2c-bcm2708 » /etc/modules
when: ( raspberry_oled == „ja“ )
</file>
<file java ~/ansible/roles/oled/tasks/i2c-dev.yml>—
- name: „Für OLED-Konfiguration i2c-dev in /etc/modules eintragen“
# https://docs.ansible.com/ansible/latest/modules/shell_module.html
shell: echo i2c-dev » /etc/modules
when: ( raspberry_oled == „ja“ )
</file>
<file java ~/ansible/roles/oled/tasks/packages.yml>—
- name: „Installation der für das OLED benötigten Pakete“
# https://docs.ansible.com/ansible/latest/modules/apt_module.html
apt:
update_cache: yes
pkg:
- python3-dev
- python3-smbus
- i2c-tools
- python3-pil
- python3-pip
- python3-setuptools
- python3-rpi.gpio
- git
- fonts-freefont-ttf
state: present
when: ( raspberry_oled == „ja“ )
</file>
<file java ~/ansible/roles/oled/tasks/reboot.yml>—
- name: „Reboot nach Konfigurationsänderung“
# https://docs.ansible.com/ansible/latest/modules/reboot_module.html
reboot:
when: ( raspberry_oled == „ja“ )
</file>
<file java ~/ansible/roles/oled/tasks/scriptclone.yml>—
- name: „Script zur Anzeige klonen“
# https://docs.ansible.com/ansible/latest/modules/git_module.html
git:
repo: https://github.com/awlx/raspberry-oled-bandwidth
dest: /usr/local/src/raspberry-oled-bandwidth
force: yes
when: ( raspberry_oled == „ja“ )
</file>
<file java ~/ansible/roles/oled/tasks/scriptconfig.yml>—
- name: „Script zur Bandbreitenauslastung anpassen“
# https://docs.ansible.com/ansible/latest/modules/template_module.html
template:
src: templates/bandwidth.j2
dest: /usr/local/src/raspberry-oled-bandwidth/bandwidth.py
when: ( raspberry_oled == „ja“ )
</file>
<file java ~/ansible/roles/oled/tasks/scriptstart.yml>—
- name: „Startscript für das OLED anlegen“
# https://docs.ansible.com/ansible/latest/modules/template_module.html
template:
src: templates/oled-bandwidth.j2
dest: /etc/systemd/system/oled-bandwidth.service
when: ( raspberry_oled == „ja“ )
</file>
<file java ~/ansible/roles/oled/tasks/scriptstartup.yml>—
- name: „Service oled-bandwidth beim Booten starten“
# https://docs.ansible.com/ansible/latest/modules/systemd_module.html
systemd:
name: oled-bandwidth
daemon_reload: yes
state: started
enabled: yes
when: ( raspberry_oled == „ja“ )
</file>
== Templates ==
<file python ~/ansible/roles/oled/templates/bandwidth.j2># Inspired by https://github.com/DarrenBeck/rpi-oled-bandwidth and https://photochirp.com/r-pi/use-raspberry-pi-oled-bandwidth-monitor/
#
# Maintained by awlnx - aw@awlnx.space
#
import subprocess
import time
import re
import Adafruit_GPIO.SPI as SPI
import Adafruit_SSD1306
from PIL import Image
from PIL import ImageDraw
from PIL import ImageFont
import math
# Adjust to your needs
wifi = 'wlan0'
vpn = 'mesh-vpn'
batman = 'bat-ffmuc_segment'
primary_mac = 'ansible_eth0.macaddress'
# We assume 100mbit/s max bandwidth
maxRateIn = 10000000
maxRateOut = 10000000
PImaxRateIn = 10000000
PImaxRateOut = 10000000
### DO NOT EDIT BELOW THIS POINT ###
# Raspberry Pi pin configuration:
RST = 'P9_15'
# 128×64 display with hardware I2C:
disp = Adafruit_SSD1306.SSD1306_128_64(rst=RST)
# Initialize library.
disp.begin()
# Clear display.
disp.clear()
disp.display()
# Create blank image for drawing.
# Make sure to create image with mode '1' for 1-bit color.
width = disp.width
height = disp.height
image = Image.new('1', (width, height))
# Get drawing object to draw on image.
draw = ImageDraw.Draw(image)
font = ImageFont.truetype('/usr/share/fonts/truetype/freefont/FreeSans.ttf', 12)
fontsmall = ImageFont.truetype('/usr/share/fonts/truetype/freefont/FreeSans.ttf', 10)
fontverysmall = ImageFont.truetype('/usr/share/fonts/truetype/freefont/FreeSans.ttf', 8)
fontmedium = ImageFont.truetype('/usr/share/fonts/truetype/freefont/FreeSans.ttf', 12)
#Display Image
disp.image(image)
disp.display()
#Functions
def get_network_bytes(interface):
for line in open('/proc/net/dev', 'r'):
if interface in line:
data = line.split('%s:' % interface)[1].split()
rx_bytes, tx_bytes = (data[0], data[8])
return (int(rx_bytes), int(tx_bytes))
def drawBar (x, barHeight):
# parameters are x, y, end x, end y
# draw.rectangle 10) 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
<code>Archive: 2022-01-28-raspios-bullseye-arm64-lite.zip
inflating: 2022-01-28-raspios-bullseye-arm64-lite.img</code>
==== 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.
<code> # tail -f /var/log/messages</code> bzw. <code> $ sudo tail -f /var/log/syslog</code>
<code>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</code>
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.
<code> # dd if=/home/django/Freifunk/2022-01-28-raspios-bullseye-arm64-lite.img of=/dev/mmcblk0 bs=4M status=progress conv=fsync</code> bzw.
<code> $ sudo dd if=/home/django/Freifunk/2022-01-28-raspios-bullseye-arm64-lite.img of=/dev/mmcblk0 bs=4M status=progress conv=fsync</code>
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.:
<code> # touch /run/media/django/boot/ssh</code> bzw. <code> $ touch /media/django/boot/ssh</code>
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.
<code>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.
</code>
$ ssh raspberry-ansible
<html><pre class=„code“>
<font style=„color: rgb(0, 0, 0)“>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.
<font style=„color: rgb(136, 198, 29)“><b>pi@raspberrypi</b></font><b>:</b><font style=„color: rgb(105, 133, 169)“><b>~ $ </b></font>
</pre>
</html>
==== 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 den Zeilen 55 bis 64
sind diese Parameter entsprechend zu hinterlegen.
$ vim ~/ansible/inventories/production/hosts.yml +54
<code> 54 batman_adv_version: „2020.4“
55 ffmuc_segment: „muc_ost“
56 ffmuc_gateway: „gw04“
57 raspberry_hostname: „raspbian-ansible-offloader“
58 node_contact_address: „https://bit.ly/2VxGoXp“
59 raspberry_latitude: „48.239094621“
60 raspberry_longitude: „11.558936834“
61 raspberry_wifi: „ja“
62 raspberry_clientvlan: „123“
63 raspberry_meshvlan: „456“
64 raspberry_oled: „ja“</code>
=== 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
<html><pre class=„code“>
<font style=„color: rgb(0, 0, 0)“>
PLAY [raspi_offloader.yml] *
TASK [Gathering Facts] *
<font style=„color: rgb(51, 145, 5)“>ok: [raspi_offloader]</font>
TASK [basic : Hostname ändern] *
<font style=„color: rgb(191, 125, 0)“>changed: [raspi_offloader]</font>
TASK [basic : Template Konfigurationsdatei für /etc/hosts an Ort und Stelle kopieren und Variablen anpassen] *
<font style=„color: rgb(191, 125, 0)“>changed: [raspi_offloader]</font>
TASK [basic : Beschreibung des User 'pi' anpassen] *
<font style=„color: rgb(191, 125, 0)“>changed: [raspi_offloader]</font>
TASK [basic : Service rfkill am Raspberry deaktivieren]
<font style=„color: rgb(191, 125, 0)“>changed: [raspi_offloader]</font>
TASK [basic : Update und Upgrade der APT-Paket]
<font style=„color: rgb(169, 126, 155)“><b>[WARNING]: Updating cache and auto-installing missing dependency: python-apt</b></font>
<font style=„color: rgb(191, 125, 0)“>changed: [raspi_offloader]</font>
TASK [basic : Reboot nach update]
<font style=„color: rgb(191, 125, 0)“>changed: [raspi_offloader]</font>
TASK [batman : *BATMAN Installation* : Download des aktuellen BATMAN Archives] *
<font style=„color: rgb(191, 125, 0)“>changed: [raspi_offloader]</font>
TASK [batman : *BATMAN Installation* : Entpacken des BATMAN-Archives]
<font style=„color: rgb(191, 125, 0)“>changed: [raspi_offloader]</font>
TASK [batman : *BATMAN compile* : Installation des Dynamic Kernel Module Support Framework und der Header Files für den Raspberry Pi OS Linux Kernel]
<font style=„color: rgb(191, 125, 0)“>changed: [raspi_offloader]</font>
TASK [batman : *BATMAN compile* : Rebuild BATMAN Kernel Header Dateien]
<font style=„color: rgb(201, 0, 0)“>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“: []}</font>
<font style=„color: rgb(2, 110, 147)“>…ignoring</font>
TASK [batman : *BATMAN compile* : Anlegen der dkms.conf für Dynamic Kernel Module Support] *
<font style=„color: rgb(191, 125, 0)“>changed: [raspi_offloader]</font>
TASK [batman : *BATMAN compile* : Dynamic Kernel Module Support hinzufügen]
<font style=„color: rgb(191, 125, 0)“>changed: [raspi_offloader]</font>
TASK [batman : *BATMAN compile* : Dynamic Kernel Module bauen] *
<font style=„color: rgb(191, 125, 0)“>changed: [raspi_offloader]</font>
TASK [batman : *BATMAN compile* : BATMAN Dynamic Kernel Module installieren] *
<font style=„color: rgb(191, 125, 0)“>changed: [raspi_offloader]</font>
TASK [batman : *BATMAN load-modules* : Laden der BATMAN Dynamic Kernel Module beim Booten sicherstellen] *
<font style=„color: rgb(191, 125, 0)“>changed: [raspi_offloader]</font>
TASK [batman : *BATMAN load-modules* : dummy Modul laden]
<font style=„color: rgb(191, 125, 0)“>changed: [raspi_offloader]</font>
TASK [batman : *BATMAN load-modules* : BATMAN-ADV Modul laden] *
<font style=„color: rgb(191, 125, 0)“>changed: [raspi_offloader]</font>
TASK [batman : *buster-backport* : PGP-Schlüssel 04EE7237B7D453EC für buster-backports installieren] *
<font style=„color: rgb(191, 125, 0)“>changed: [raspi_offloader]</font>
TASK [batman : *buster-backport* : PGP-Schlüssel 648ACFD622F3D138 für buster-backports installieren] *
<font style=„color: rgb(191, 125, 0)“>changed: [raspi_offloader]</font>
TASK [batman : *buster-backport* : buster-backports dem System bekannt machen] *
<font style=„color: rgb(191, 125, 0)“>changed: [raspi_offloader]</font>
TASK [batman : *buster-backport* : APT-Cache aktualisieren]
<font style=„color: rgb(191, 125, 0)“>changed: [raspi_offloader]</font>
TASK [batman : *utils-installation* : Installation der bridge-utils] *
<font style=„color: rgb(191, 125, 0)“>changed: [raspi_offloader]</font>
TASK [batman : *utils-installation* : Installation der bridge-utils] *
<font style=„color: rgb(191, 125, 0)“>changed: [raspi_offloader]</font>
TASK [batman : *BATMAN-ADV* : Aktivierung von BATMAN_V]
<font style=„color: rgb(191, 125, 0)“>changed: [raspi_offloader]</font>
TASK [batman : *BATMAN-ADV Interfaces* : Konfiguration des Interfaces] *
<font style=„color: rgb(191, 125, 0)“>changed: [raspi_offloader]</font>
TASK [batman : *BATMAN Installation* : Reboot nach Ende der BATMAN Installationsschritte]
<font style=„color: rgb(191, 125, 0)“>changed: [raspi_offloader]</font>
TASK [wireguard : *wireguard* : Installation von wireguard]
<font style=„color: rgb(191, 125, 0)“>changed: [raspi_offloader]</font>
TASK [wireguard : *wireguard* : Schlüsselmaterial erstellen] *
<font style=„color: rgb(191, 125, 0)“>changed: [raspi_offloader]</font>
TASK [wireguard : *wireguard* : Zugriffsrechte des Private Keys anpassen]
<font style=„color: rgb(191, 125, 0)“>changed: [raspi_offloader]</font>
TASK [wireguard : *wireguard : *wireguard* : Zugriffsrechte des Public Keys anpassen]
<font style=„color: rgb(191, 125, 0)“>changed: [raspi_offloader]</font>
TASK [wireguard : *wireguard : *wireguard* : lokale link-local IPv6 Adresse aus dem PUBLIC-Key erzeugen] *
<font style=„color: rgb(191, 125, 0)“>changed: [raspi_offloader]</font>
TASK [wireguard : *wireguard* : private-key einlesen und in Variable übergeben]
<font style=„color: rgb(191, 125, 0)“>changed: [raspi_offloader]</font>
TASK [wireguard : *wireguard* : public-key einlesen und in Variable übergeben] *
<font style=„color: rgb(191, 125, 0)“>changed: [raspi_offloader]</font>
TASK [wireguard : *wireguard* : Socket ermitteln]
<font style=„color: rgb(2, 110, 147)“>skipping: [raspberry-wireguard] ⇒ (item={'key': 'muc_cty', 'value': 40002})
skipping: [raspberry-wireguard] ⇒ (item={'key': 'muc_nord', 'value': 40003})</font>
<font style=„color: rgb(51, 145, 5)“>ok: [raspberry-wireguard] ⇒ (item={'key': 'muc_ost', 'value': 40004})</font>
<font style=„color: rgb(2, 110, 147)“>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})</font>
TASK [wireguard : *wireguard* : link-local des Gateways ermitteln]
<font style=„color: rgb(51, 145, 5)“>ok: [raspberry-wireguard] ⇒ (item={'key': 'gw04', 'value': 'fe80::27c:16ff:fec0:6c74'})</font>
<font style=„color: rgb(2, 110, 147)“>skipping: [raspberry-wireguard] ⇒ (item={'key': 'gw05', 'value': 'fe80::281:8eff:fef0:73aa'})</font>
TASK [wireguard : *wireguard* : publickey des Gateways ermitteln] *
<font style=„color: rgb(51, 145, 5)“>ok: [raspberry-wireguard] ⇒ (item={'key': 'gw04', 'value': 'TszFS3oFRdhsJP3K0VOlklGMGYZy+oFCtlaghXJqW2g='})</font>
<font style=„color: rgb(2, 110, 147)“>skipping: [raspberry-wireguard] ⇒ (item={'key': 'gw05', 'value': 'igyqOmWiz4EZxPG8ZzU537MnHhaqlwfa7HarB3KmnEg='})</font>
TASK [wireguard : *wireguard* : Konfigurationsdatei des wireguard-Tunnels erzeugen] *
<font style=„color: rgb(191, 125, 0)“>changed: [raspi_offloader]</font>
TASK [wireguard : *wireguard* : systemd unit file für broker -Information anlegen]
<font style=„color: rgb(191, 125, 0)“>changed: [raspi_offloader]</font>
TASK [wireguard : *wireguard* : Service broker starten beim Booten starten] *
<font style=„color: rgb(191, 125, 0)“>changed: [raspi_offloader]</font>
TASK [wireguard : *wireguard* : Service wireguard via systemd starten]
<font style=„color: rgb(191, 125, 0)“>changed: [raspi_offloader]</font>
TASK [wireguard : *wireguard* : lokale link-local IPv6 Adresse aus dem PUBLIC-Key erzeugen] *
<font style=„color: rgb(191, 125, 0)“>changed: [raspi_offloader]</font>
TASK [wireguard : *wireguard* : checkupscript zum Testen der wireguard-Verbindung anlegen]
<font style=„color: rgb(191, 125, 0)“>changed: [raspi_offloader]</font>
TASK [wireguard : *wireguard* : Ausführungsrechte des Bash-Scripts anpassen]
<font style=„color: rgb(191, 125, 0)“>changed: [raspi_offloader]</font>
TASK [wireguard : *wireguard* : crontab für minütlichen checkup der wireguard-Verbindung anlegen] *
<font style=„color: rgb(191, 125, 0)“>changed: [raspi_offloader]</font>
TASK [Installation von FASTD] *
<font style=„color: rgb(191, 125, 0)“>changed: [raspi_offloader]</font>
TASK [Verzeichnis für fastd- Konfigurationsdatei anlegen] *
<font style=„color: rgb(191, 125, 0)“>changed: [raspi_offloader]</font>
TASK [Schlüssel für fastd erstellen]
<font style=„color: rgb(191, 125, 0)“>changed: [raspi_offloader]</font>
TASK [vxlan : *VXLAN* : Paketfilter anpassen - Eingehenden VXLAN Verkehr auf dem Mesh-Interface erlauben] *
<font style=„color: rgb(191, 125, 0)“>changed: [raspi_offloader]</font>
TASK [vxlan : *VXLAN* : VXLAN-ID des gewählten Segments ermitteln]
<font style=„color: rgb(2, 110, 147)“>skipping: [raspberry-wireguard] ⇒ (item={'key': 'muc_cty', 'value': 3836090})
skipping: [raspberry-wireguard] ⇒ (item={'key': 'muc_nord', 'value': 1920014})</font>
<font style=„color: rgb(51, 145, 5)“>ok: [raspberry-wireguard] ⇒ (item={'key': 'muc_ost', 'value': 12097488})</font>
<font style=„color: rgb(2, 110, 147)“>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})</font>
TASK [vxlan : *VXLAN* : link-local des Gateways ermitteln]
<font style=„color: rgb(51, 145, 5)“>ok: [raspberry-wireguard] ⇒ (item={'key': 'gw04', 'value': 'fe80::27c:16ff:fec0:6c74'})</font>
<font style=„color: rgb(2, 110, 147)“>skipping: [raspberry-wireguard] ⇒ (item={'key': 'gw05', 'value': 'fe80::281:8eff:fef0:73aa'})</font>
TASK [vxlan : *VXLAN* : lokale link-local IPv6 Adresse aus dem PUBLIC-Key erzeugen] *
<font style=„color: rgb(191, 125, 0)“>changed: [raspi_offloader]</font>
TASK [vxlan : *VXLAN* : Startupdatei für VXLAN kopieren]
<font style=„color: rgb(191, 125, 0)“>changed: [raspi_offloader]</font>
TASK [vxlan : *VXLAN* : Ausführungsrechte des Bash-Scripts anpassen]
<font style=„color: rgb(191, 125, 0)“>changed: [raspi_offloader]</font>
TASK [vxlan : *VXLAN* : systemd-unitfile anlegen] *
<font style=„color: rgb(191, 125, 0)“>changed: [raspi_offloader]</font>
TASK [vxlan : *VXLAN* : Neues Unitfile dem systemd bekannt geben] *
<font style=„color: rgb(191, 125, 0)“>changed: [raspi_offloader]</font>
TASK [vxlan : *VXLAN* : Service vxlan via systemd starten]
<font style=„color: rgb(191, 125, 0)“>changed: [raspi_offloader]</font>
TASK [ext-respondd : Installation der Pakete git und python3-netifaces] *
<font style=„color: rgb(191, 125, 0)“>changed: [raspi_offloader]</font>
TASK [ext-respondd : Repo ext-respondd klonen]
<font style=„color: rgb(191, 125, 0)“>changed: [raspi_offloader]</font>
TASK [ext-respondd : Systemd Startdatei für respondd kopieren]
<font style=„color: rgb(191, 125, 0)“>changed: [raspi_offloader]</font>
TASK [ext-respondd : Erstellen der resondd Konfigurationsdatei alias.json]
<font style=„color: rgb(191, 125, 0)“>changed: [raspi_offloader]</font>
TASK [ext-respondd : Erstellen der resondd Konfigurationsdatei config.json] *
<font style=„color: rgb(191, 125, 0)“>changed: [raspi_offloader]</font>
TASK [ext-respondd : Service ext-respondd beim Booten starten]
<font style=„color: rgb(191, 125, 0)“>changed: [raspi_offloader]</font>
TASK [hostapd : Paket hostapd für WLAN installieren]
<font style=„color: rgb(191, 125, 0)“>changed: [raspi_offloader]</font>
TASK [hostapd : hostapd konfigurieren]
<font style=„color: rgb(191, 125, 0)“>changed: [raspi_offloader]</font>
TASK [hostapd : hostapd Konfigurationsdatei anlegen]
<font style=„color: rgb(191, 125, 0)“>changed: [raspi_offloader]</font>
TASK [hostapd : wlan0 in Bridge packen] *
<font style=„color: rgb(191, 125, 0)“>changed: [raspi_offloader]</font>
TASK [hostapd : Service hostapd beim Booten und jetzt starten und das Laden der Unit Datei vom Service hostapd ermöglichen] *
<font style=„color: rgb(191, 125, 0)“>changed: [raspi_offloader]</font>
TASK [client-mesh : Konfiguration des Client-VLAN ohne Mesh-Netz] *
<font style=„color: rgb(191, 125, 0)“>changed: [raspi_offloader]</font>
TASK [client-mesh : vxlan_id für ausgewähltes Segment ermitteln]
<font style=„color: rgb(2, 110, 147)“>skipping: [raspberry-wireguard] ⇒ (item={'key': 'muc_cty', 'value': 10758607})
skipping: [raspberry-wireguard] ⇒ (item={'key': 'muc_nord', 'value': 15521492})</font>
<font style=„color: rgb(51, 145, 5)“>ok: [raspberry-wireguard] ⇒ (item={'key': 'muc_ost', 'value': 2948862})</font>
<font style=„color: rgb(2, 110, 147)“>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})</font>
TASK [client-mesh : Konfiguration des Mesh-VLAN ohne Client-VLAN] *
<font style=„color: rgb(2, 110, 147)“>skipping: [raspi_offloader]</font>
TASK [client-mesh : Konfiguration von Mesh- und Client-VLAN]
<font style=„color: rgb(191, 125, 0)“>changed: [raspi_offloader]</font>
TASK [client-mesh : Konfiguration des bevorzugte Meshingpoint in BATMAN_V ohne Wifi-Nutzung]
<font style=„color: rgb(2, 110, 147)“>skipping: [raspi_offloader]</font>
TASK [client-mesh : Konfiguration des bevorzugte Meshingpoint in BATMAN_V mit Wifi-Nutzung
<font style=„color: rgb(191, 125, 0)“>changed: [raspi_offloader]</font>
TASK [oled : Für OLED-Konfiguration i2c-bcm2708 in /etc/modules eintragen]
<font style=„color: rgb(191, 125, 0)“>changed: [raspi_offloader]</font>
TASK [oled : Für OLED-Konfiguration i2c-dev in /etc/modules eintragen]
<font style=„color: rgb(191, 125, 0)“>changed: [raspi_offloader]</font>
TASK [oled : Installation der für das OLED benötigten Pakete] *
<font style=„color: rgb(191, 125, 0)“>changed: [raspi_offloader]</font>
TASK [oled : Laden des Kernelmodul i2c_arm beim Booten veranlassen] *
<font style=„color: rgb(191, 125, 0)“>changed: [raspi_offloader]</font>
TASK [oled : Reboot nach Konfigurationsänderung]
<font style=„color: rgb(191, 125, 0)“>changed: [raspi_offloader]</font>
TASK [oled : Repo Adafruit_Python_SSD1306 klonen] *
<font style=„color: rgb(191, 125, 0)“>changed: [raspi_offloader]</font>
TASK [oled : Für OLED-Konfiguration Adafruit_Python_SSD1306 installieren] *
<font style=„color: rgb(191, 125, 0)“>changed: [raspi_offloader]</font>
TASK [oled : Script zur Anzeige klonen] *
<font style=„color: rgb(191, 125, 0)“>changed: [raspi_offloader]</font>
TASK [oled : Script zur Bandbreitenauslastung anpassen] *
<font style=„color: rgb(191, 125, 0)“>changed: [raspi_offloader]</font>
TASK [oled : Startscript für das OLED anlegen]
<font style=„color: rgb(191, 125, 0)“>changed: [raspi_offloader]</font>
TASK [oled : Service oled-bandwidth beim Booten starten]
<font style=„color: rgb(191, 125, 0)“>changed: [raspi_offloader]</font>
TASK [final : Reboot nach Abschluss der Konfiguration unseres Offloaders] *
<font style=„color: rgb(191, 125, 0)“>changed: [raspi_offloader]</font>
PLAY RECAP *
<font style=„color: rgb(191, 125, 0)“>raspi_offloader </font>: <font style=„color: rgb(51, 145, 5)“>ok=80</font> <font style=„color: rgb(191, 125, 0)“>changed=71</font> unreachable=0 failed=0 <font style=„color: rgb(2, 110, 147)“>skipped=3</font> rescued=0 <font style=„color: rgb(169, 126, 155)“>ignored=1</font>
</pre>
</html>
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:
====== Links ======
* zurück zum Kapitel "Ansible - Playbook-Beispiele" ⇐
* ⇒ weiter zum Kapitel "Ansible - Erweiterte Konfigurationsbeispiele
* Zurück zur "Ansible"-Übersicht
* Zurück zu >>Projekte und Themenkapitel<<
* Zurück zur Startseite**
draw.rectangle ((x, 32 - barHeight, x + 8, height - 32), outline=255, fill=255)def drawBarLOW (x, barLOWHeight):
# parameters are x, y, end x, end y draw.rectangle ((x, 32 + barLOWHeight, x + 8, height - 32), outline=255, fill=255)def textRate(rate):
# rate -> raw bitrate # Returns: SI formatted bitrate if rate == 0: return "0B" rate = rate * 8 size_name = ( "b/s", "kb/s", "mb/s", "gb/s", "tb/s", "pb/s", "eb/s") i = int(math.floor(math.log(rate , 1024))) p = math.pow(1024, i) s = round(rate / p, 1) return "%s %s" % (s, size_name[i])lastInBytes = get_network_bytes(vpn)[0]; lastOutBytes = get_network_bytes(vpn)[1]; lastPIInBytes = get_network_bytes(wifi)[0]; lastPIOutBytes = get_network_bytes(wifi)[1]; lastTime = time.time() #timed array vars timerTime = time.time() highestSpeedIn = 0 highestSpeedOut = 0 PIhighestSpeedIn = 0 PIhighestSpeedOut = 0 speedArrayIn = [] speedArrayOut = [] PIspeedArrayIn = [] PIspeedArrayOut = [] inMax = 0 outMax = 0 PIinMax = 0 PIoutMax = 0 while (1):
time.sleep(2) draw.rectangle((0, 0, width, height), outline=0, fill=0)
now = time.time() elapsed = now - lastTime lastTime = now
#calculate rates in and out inBytes = get_network_bytes(vpn)[0] currInBytes = (inBytes - lastInBytes) / elapsed lastInBytes = inBytes
outBytes = get_network_bytes(vpn)[1] currOutBytes = (outBytes - lastOutBytes) / elapsed lastOutBytes = outBytes
PIinBytes = get_network_bytes(wifi)[0] currPIInBytes = (PIinBytes - lastPIInBytes) / elapsed lastPIInBytes = PIinBytes
PIoutBytes = get_network_bytes(wifi)[1] currPIOutBytes = (PIoutBytes - lastPIOutBytes) / elapsed lastPIOutBytes = PIoutBytes
#max rate last 24 hours calculations
if currInBytes > highestSpeedIn: highestSpeedIn = currInBytes if currOutBytes > highestSpeedOut: highestSpeedOut = currOutBytes if currPIInBytes > PIhighestSpeedIn: PIhighestSpeedIn = currPIInBytes if currPIOutBytes > PIhighestSpeedOut: PIhighestSpeedOut = currPIOutBytes
if now > timerTime + 3600: print('----------------------------------------------------------------- time expired') timerTime = now
speedArrayIn.append (highestSpeedIn) if len (speedArrayIn) > 23: del speedArrayIn[0] inMax = max(speedArrayIn)
speedArrayOut.append (highestSpeedOut) if len (speedArrayOut) > 23: del speedArrayOut[0] outMax = max(speedArrayOut)
highestSpeedIn = 0 highestSpeedOut = 0
PIspeedArrayIn.append (PIhighestSpeedIn) if len (PIspeedArrayIn) > 23: del PIspeedArrayIn[0] PIinMax = max(PIspeedArrayIn)
PIspeedArrayOut.append (PIhighestSpeedOut) if len (PIspeedArrayOut) > 23: del PIspeedArrayOut[0] PIoutMax = max(PIspeedArrayOut)
PIhighestSpeedIn = 0 PIhighestSpeedOut = 0
#adjust these in each loop in case we find a faster speed inMax = max(inMax, highestSpeedIn) outMax = max(outMax, highestSpeedOut) PIinMax = max(PIinMax, PIhighestSpeedIn) PIoutMax = max(PIoutMax, PIhighestSpeedOut)
#draw graph inHeight = 0.0 outHeight = 0.0 PIinHeight = 0.0 PIoutHeight = 0.0
if currInBytes > 0: inHeight = float(currInBytes / maxRateIn) * 32
if currOutBytes > 0: outHeight = float(currOutBytes / maxRateOut) * 32
if currPIInBytes > 0: PIinHeight = float(currPIInBytes / PImaxRateIn) * 32
if currPIOutBytes > 0: PIoutHeight = float(currPIOutBytes / PImaxRateOut) * 32
drawBar (0, inHeight) drawBar (10, PIinHeight) drawBarLOW (0, outHeight) drawBarLOW (10, PIoutHeight) #write rates draw.text((26,38), textRate(currInBytes), font=font, fill=255) draw.text((26,50), textRate(currOutBytes), font=font, fill=255)
draw.text((81,38), textRate(currPIInBytes), font=font, fill=255) draw.text((81,50), textRate(currPIOutBytes), font=font, fill=255)
# Batman Clients clients = subprocess.check_output("batctl meshif " + batman + " tl | egrep -v '(MainIF|" + primary_mac + ")' | egrep -o '([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})' | wc -l", shell=True).split().pop() draw.text((0,48), "Clients", font=fontverysmall, fill=255) draw.text((10,55), clients.decode("utf-8"), font=fontverysmall, fill=255)
#max rates draw.text((36,0), "VPN", font=fontsmall, fill=255) draw.text((26,10), textRate(inMax), font=fontsmall, fill=255) draw.text((26,20), textRate(outMax), font=fontsmall, fill=255)
draw.text((90,0), "Wifi", font=fontsmall, fill=255) draw.text((81,10), textRate(PIinMax), font=fontsmall, fill=255) draw.text((81,20), textRate(PIoutMax), font=fontsmall, fill=255)
disp.image(image) disp.display()</file>
- ~/ansible/roles/oled/templates/config.j2
# For more options and information see # http://rpf.io/configtxt # Some settings may impact device functionality. See link above for details # uncomment if you get no picture on HDMI for a default "safe" mode #hdmi_safe=1 # uncomment this if your display has a black border of unused pixels visible # and your display can output without overscan #disable_overscan=1 # uncomment the following to adjust overscan. Use positive numbers if console # goes off screen, and negative if there is too much border #overscan_left=16 #overscan_right=16 #overscan_top=16 #overscan_bottom=16 # uncomment to force a console size. By default it will be display's size minus # overscan. #framebuffer_width=1280 #framebuffer_height=720 # uncomment if hdmi display is not detected and composite is being output #hdmi_force_hotplug=1 # uncomment to force a specific HDMI mode (this will force VGA) #hdmi_group=1 #hdmi_mode=1 # uncomment to force a HDMI mode rather than DVI. This can make audio work in # DMT (computer monitor) modes #hdmi_drive=2 # uncomment to increase signal to HDMI, if you have interference, blanking, or # no display #config_hdmi_boost=4 # uncomment for composite PAL #sdtv_mode=2 #uncomment to overclock the arm. 700 MHz is the default. #arm_freq=800 # Uncomment some or all of these to enable the optional hardware interfaces # Django : 2019-09-11 # default: # dtparam=i2c_arm=on dtparam=i2c_arm=on #dtparam=i2s=on #dtparam=spi=on # Uncomment this to enable the lirc-rpi module #dtoverlay=lirc-rpi # Additional overlays and parameters are documented /boot/overlays/README # Enable audio (loads snd_bcm2835) dtparam=audio=on [pi4] # Enable DRM VC4 V3D driver on top of the dispmanx display stack dtoverlay=vc4-fkms-v3d max_framebuffers=2 [all] #dtoverlay=vc4-fkms-v3d
- ~/ansible/roles/oled/templates/oled-bandwidth.j2
# Django : 2019-09-11 [Unit] # see man systemd.unit Description=Starting OLED-Trafic output Documentation=https://wiki.mailserver.guru/doku.php/centos:ansible:ffmuc-rpb4-ol After=network.target [Service] # see man systemd.service, systemd.exec ExecStart=/usr/bin/python3 /usr/local/src/raspberry-oled-bandwidth/bandwidth.py StandardOutput=syslog StandardError=syslog [Install] WantedBy=default.target
- ~/ansible/roles/final/tasks/main.yml
--- # Reboot nach Abschluss der Konfiguration unseres Offloaders - include: reboot.yml # /etc/hosts anpassen ... #YAML Ende Syntax
- ~/ansible/roles/final/tasks/reboot.yml
--- - name: "Reboot nach Abschluss der Konfiguration unseres Offloaders" # https://docs.ansible.com/ansible/latest/modules/reboot_module.html reboot: