Unterschiede
Hier werden die Unterschiede zwischen zwei Versionen angezeigt.
| Beide Seiten der vorigen Revision Vorhergehende Überarbeitung Nächste Überarbeitung | Vorhergehende Überarbeitung | ||
| knb:rpb4_wg [2020/12/17 11:00] – [Konfigurations-/Netzzwerkcheck] Django | knb:rpb4_wg [2026/11/02 19:25] (aktuell) – Ins Archiv verschoben: archiv:knb:rpb4_wg wartung | ||
|---|---|---|---|
| Zeile 1: | Zeile 1: | ||
| - | {{htmlmetatags> | + | ====== |
| - | metatag-description=(Offloader auf Basis eines Raspberry PI 4B - WireGuard) | + | |
| - | metatag-keywords=(Freifunk, | + | |
| - | }} | + | |
| - | ====== Offloader auf Basis eines Raspberry PI 4B (WireGuard) | + | |
| - | {{: | + | |
| + | Diese Anleitung ist veraltet und liegt jetzt im Archiv: [[: | ||
| - | <WRAP center round tip 60%> | + | Für den Raspberry Pi 4 gibt es ein fertiges |
| - | <WRAP center round alert 90%> | + | |
| - | Disclaimer: Die Anleitung ist nur für Leute, die sich bereits mit dem Thema Linux auseinander gesetzt haben oder sich intensiv damit beschäftigen wollen! | + | |
| - | </ | + | |
| - | + | ||
| - | <WRAP center round info 90%> | + | |
| - | Diese Anleitung funktioniert auf quasi allen Linux basierten Betriebssystemen, | + | |
| - | \\ | + | |
| - | In den nachfolgenden Beispielen zu den Shell-/ | + | |
| - | * Ein vorangestelltes Dollarzeichen **'' | + | |
| - | * Ein vorangestelltes Raute-Symbol **''#'' | + | |
| - | \\ | + | |
| - | Sollten trotz des eingehenden Studiums dieser Anleitung dennoch Fragen offen bleiben, oder unvorhergesehenen Problemstellungen auftreten, findet man im **[[https:// | + | |
| - | </ | + | |
| - | </ | + | |
| - | + | ||
| - | Mit dem [[https:// | + | |
| - | + | ||
| - | <WRAP center round important 60%> | + | |
| - | Für kabelgebundene Clients und/oder Meshing per Kabel benötigt ihr einen VLAN-fähigen Switch! | + | |
| - | </ | + | |
| - | + | ||
| - | Angeboten wird das PI in einer 1GB, 2GB und 4GB RAM Variante. Will man wirklich nur einen reinen Offloader ohne Zusatzfunktionen betreiben, reicht im Grunde die 1GB Version. Allerdings ist mehr RAM immer besser ;) und man weiß ja nicht, was man im Endeffekt noch alles darauf betreiben will. | + | |
| - | + | ||
| - | {{: | + | |
| - | {{: | + | |
| - | {{: | + | |
| - | + | ||
| - | ===== Raspberry Pi OS ===== | + | |
| - | Nachdem es aktuell((Stand: | + | |
| - | + | ||
| - | Eine Anleitung zur manuellen Installation findet man auf der **[[https:// | + | |
| - | + | ||
| - | ==== Download ==== | + | |
| - | Wir laden uns also das betreffende ZIP-Archiv auf unseren Rechner. | + | |
| - | $ wget https:// | + | |
| - | + | ||
| - | 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 raspbian_lite_latest | + | |
| - | + | ||
| - | 4522df4a29f9aac4b0166fbfee9f599dab55a997c855702bfe35329c13334668 | + | |
| - | + | ||
| - | Die Zeichenfolge überprüfen wir nun mit den Angaben auf der Seite: https:// | + | |
| - | {{ : | + | |
| - | + | ||
| - | Da sich beide SHA-Werte **__nicht__** unterscheiden können wir das herunter geladene ZIP-Archiv nun entpacken. | + | |
| - | $ unzip 2020-08-20-raspios-buster-armhf-lite.zip | + | |
| - | + | ||
| - | < | + | |
| - | inflating: 2020-08-20-raspios-buster-armhf-lite.img | + | |
| - | </ | + | |
| - | + | ||
| - | ==== Kopieren des Images auf die MicroSD-Karte ==== | + | |
| - | Nun können wir das Image auf die MicroSD-Karte, | + | |
| - | # tail -f / | + | |
| - | bzw. | + | |
| - | $ sudo tail -f / | + | |
| - | + | ||
| - | < | + | |
| - | Sep 5 21:10:57 BOFHs-X230 kernel: [12795.868313] mmcblk0: mmc0:aaaa SC16G 14.8 GiB | + | |
| - | Sep 5 21:10:57 BOFHs-X230 kernel: [12795.871017] | + | |
| - | Sep 5 21:10:58 BOFHs-X230 kernel: [12796.199093] FAT-fs (mmcblk0p1): | + | |
| - | Sep 5 21:10:58 BOFHs-X230 systemd[1]: Finished Clean the / | + | |
| - | Sep 5 21:10:58 BOFHs-X230 udisksd[976]: | + | |
| - | Sep 5 21:10:58 BOFHs-X230 kernel: [12796.302402] EXT4-fs (mmcblk0p2): | + | |
| - | Sep 5 21:10:58 BOFHs-X230 kernel: [12796.303545] EXT4-fs (mmcblk0p2): | + | |
| - | Sep 5 21:10:58 BOFHs-X230 systemd[1]: Finished Clean the / | + | |
| - | Sep 5 21:10:58 BOFHs-X230 udisksd[976]: | + | |
| - | Sep 5 21:11:09 BOFHs-X230 gnome-terminal-[8119]: | + | |
| - | + | ||
| - | In dem gezeigtem Fall handelt | + | |
| - | + | ||
| - | # dd if=~/ | + | |
| - | bzw. | + | |
| - | $ sudo dd if=/ | + | |
| - | + | ||
| - | 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 **''/ | + | |
| - | # touch / | + | |
| - | bzw. | + | |
| - | $ touch / | + | |
| - | + | ||
| - | Anschließend können wir nach einem Unmounten des Gerätes **''/ | + | |
| - | + | ||
| - | ===== Vorbereitende Konfigurationsschritte ===== | + | |
| - | ==== Ändern des Default-Passwortes und kopieren des SSH-Public-Keys auf den Raspberry 4 ==== | + | |
| - | + | ||
| - | <WRAP center round important 80%> | + | |
| - | Der Benutzername lautet **'' | + | |
| - | </ | + | |
| - | + | ||
| - | 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 **'' | + | |
| - | $ ssh -l pi raspberry-ansible -o IdentitiesOnly=yes " | + | |
| - | | + | |
| - | + | ||
| - | 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 " | + | |
| - | | + | |
| - | + | ||
| - | In dem folgenden Konfigurationsbeispiel vergeben wir für den Benutzer **'' | + | |
| - | + | ||
| - | < | + | |
| - | ECDSA key fingerprint is SHA256: | + | |
| - | Are you sure you want to continue connecting (yes/ | + | |
| - | Warning: Permanently added ' | + | |
| - | pi@192.168.0.25' | + | |
| - | Current password: raspberry | + | |
| - | New password: gECzebzn7GYSLvXueECAxeGm7l7 | + | |
| - | Retype new password: gECzebzn7GYSLvXueECAxeGm7l7 | + | |
| - | passwd: password updated successfully | + | |
| - | Changing password for pi. | + | |
| - | / | + | |
| - | / | + | |
| - | / | + | |
| - | pi@192.168.0.25' | + | |
| - | + | ||
| - | Number of key(s) added: 1 | + | |
| - | + | ||
| - | Now try logging into the machine, with: " | + | |
| - | and check to make sure that only the key(s) you wanted were added. | + | |
| - | </ | + | |
| - | + | ||
| - | $ ssh raspberry-ansible | + | |
| - | + | ||
| - | < | + | |
| - | <font style=" | + | |
| - | + | ||
| - | 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 / | + | |
| - | + | ||
| - | 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=" | + | |
| - | </ | + | |
| - | </ | + | |
| - | + | ||
| - | Mit Hilfe des Befehls **'' | + | |
| - | ==== Installation von VIM ==== | + | |
| - | Für die weiteren Konfigurationsschritte werden Root-Rechte benötigen, schlüpfen wir also als erstes in dessen Rolle: | + | |
| - | $ sudo su - | + | |
| - | < | + | |
| - | Use raspi-config to set the country before use. | + | |
| - | + | ||
| - | root@raspberrypi: | + | |
| - | + | ||
| - | Anschließend installieren wir uns am besten die weiterentwickelte Variante **vim** des Standard-Editors **vi** - wir wollen uns ja später die Arbeit nicht unnötig schwer machen. | + | |
| - | # apt install vim -y | + | |
| - | + | ||
| - | ==== Änderung des Hostnamens ==== | + | |
| - | Damit unser neuer Offloader auch sauber mit seinem Namen angesprochen und dieser Name dann auch weiterverwendet werden kann, passen wir diesen nun erst einmal an. In unserem Konfigurationsbeispiel soll dies der Name **'' | + | |
| - | + | ||
| - | Nun setzen wir den Hostnamen wie folgt: | + | |
| - | # hostnamectl set-hostname rpb4-wg-ol | + | |
| - | + | ||
| - | Damit beim späteren Wechsel der Userrechte zu keiner Warnmeldung kommt, da der Hostname nicht aufgelöst werden konnte, korrigieren wir gleich noch die Konfigurationsdatei **''/ | + | |
| - | # vim / | + | |
| - | <file bash / | + | |
| - | :: | + | |
| - | ff02:: | + | |
| - | ff02:: | + | |
| - | + | ||
| - | # Django : 2020-12-16 | + | |
| - | # default: 127.0.1.1 raspberrypi | + | |
| - | 127.0.1.1 rpb4-wg-ol | + | |
| - | </ | + | |
| - | + | ||
| - | <WRAP center round tip 80%> | + | |
| - | Will man später nachvollziehen, | + | |
| - | </ | + | |
| - | + | ||
| - | ==== Entsperren des WiFi-Unterstützung ==== | + | |
| - | + | ||
| - | <WRAP center round alert 80%> | + | |
| - | Möchte man vom Raspberry später auch ein WLAN ausstrahlen lassen so ist es zwingend von Nöten, dass WIFI explizit via **rfkill** freizugeben! | + | |
| - | Hier loggen wir uns per SSH ein und setzen folgenden Befehl ab: | + | |
| - | # rfkill unblock wifi | + | |
| - | Zum Aktivieren ist noch ein Reboot unseres Raspberry 4 nötig! | + | |
| - | # systemctl reboot | + | |
| - | </ | + | |
| - | + | ||
| - | ==== Initialer Update/ | + | |
| - | Doch bevor wir unseren Raspberry 4 neu starten nehmen wir noch einen Update bzw. Upgrade aller installierten Pakete und -quellen vor! | + | |
| - | # apt-get update | + | |
| - | + | ||
| - | # apt-get upgrade -y | + | |
| - | + | ||
| - | Nun ist es an der Zeit, das wir unseren Kleinstrechner **rpb4-wg-ol** neu zu starten. | + | |
| - | # systemctl reboot | + | |
| - | + | ||
| - | ===== BATMAN ===== | + | |
| - | Für das Routing der Layer-2-Verbindungen innerhalb des Freifunknetzes wird als Mesh-Protokoll **[[https:// | + | |
| - | + | ||
| - | <WRAP center round tip 60%> | + | |
| - | Am Besten vergewissern wir uns noch vorab, welches die [[https:// | + | |
| - | Ende Dezember 2020 wäre dies die Version **[[https:// | + | |
| - | </ | + | |
| - | + | ||
| - | ==== Download und entpacken ==== | + | |
| - | Nach dem erfolgten Neustart des Rechners melden wir uns wieder mit Hilfe der **SSH** an unserem Ziel-Host an. | + | |
| - | $ ssh -l pi 192.168.0.25 | + | |
| - | + | ||
| - | Für die weiteren Konfigurationsschritte werden wie gewohnt Root-Rechte benötigt. | + | |
| - | $ sudo su - | + | |
| - | + | ||
| - | Nachdem wir uns eingeloggt haben, wechseln wir in das Zielverzeichnis **''/ | + | |
| - | # cd /usr/src/ | + | |
| - | + | ||
| - | # wget https:// | + | |
| - | + | ||
| - | # tar xzf batman-adv-2020.4.tar.gz | + | |
| - | + | ||
| - | ==== Kernelmodule ==== | + | |
| - | Nachdem das Kernelmodul manuell gebaut wird, wollen wir natürlich dass das auch Bestand hat, wenn ein Kernelupdate eingespielt wird. Dazu brauchen wir nun einige Pakete, die wir erst einmal installieren werden. | + | |
| - | # apt update && apt install dkms raspberrypi-kernel-headers | + | |
| - | + | ||
| - | Anschließend müssen wir auf Grund dessen, dass der Raspberry PI Kernel crosscompiled wurde, die make Skripte neu generieren. | + | |
| - | # cd linux-headers-$(uname -r) | + | |
| - | + | ||
| - | # make scripts | + | |
| - | + | ||
| - | <WRAP center round alert 60%> | + | |
| - | Es kann passieren, dass hier nach einiger Zeit mit der nachfolgenden Fehlermeldung abgebrochen wird, das stellt aber kein Problem dar: | + | |
| - | + | ||
| - | < | + | |
| - | <font style=" | + | |
| - | < | + | |
| - | # | + | |
| - | ^~~~~~~~~~~~~~~~~~~~~~</ | + | |
| - | compilation terminated. | + | |
| - | make[1]: *** [scripts/ | + | |
| - | make: *** [Makefile: | + | |
| - | </ | + | |
| - | </ | + | |
| - | </ | + | |
| - | + | ||
| - | Da nun alle nötigen vorbereitenden Installations- und Konfigurationsschritte abgearbeitet wurden, machen wir uns an das Anlegen der für B.A.T.M.A.N. notwendigen Konfigurationsdatei **'' | + | |
| - | # cd ../ | + | |
| - | + | ||
| - | # vim dkms.conf | + | |
| - | + | ||
| - | Der Inhalt der dkms.conf sieht wie folgt aus: | + | |
| - | <file bash / | + | |
| - | PACKAGE_NAME=batman-adv | + | |
| - | PACKAGE_VERSION=2020.4 | + | |
| - | + | ||
| - | DEST_MODULE_LOCATION=/ | + | |
| - | BUILT_MODULE_NAME=batman-adv | + | |
| - | BUILT_MODULE_LOCATION=net/ | + | |
| - | + | ||
| - | MAKE="' | + | |
| - | CLEAN="' | + | |
| - | + | ||
| - | AUTOINSTALL=" | + | |
| - | </ | + | |
| - | Zum Speichern und Verlassen des Editors **vim** benutzen wir den **Vim**-Syntax **'' | + | |
| - | + | ||
| - | Nun sind wir mit unserer Konfiguration soweit dass wir die B.A.T.M.A.N-Kernelmodule bauen können. | + | |
| - | # dkms add -m batman-adv -v 2020.4 | + | |
| - | + | ||
| - | # dkms build -m batman-adv -v 2020.4 | + | |
| - | + | ||
| - | # dkms install -m batman-adv -v 2020.4 | + | |
| - | + | ||
| - | Als nächstes müssen wir dafür sorgen, dass die beiden Kernelmodule **batman-adv** und **dummy** beim Booten des Systems auch geladen werden. Dazu müssen wir die Datei "/ | + | |
| - | # vim / | + | |
| - | + | ||
| - | <file bash / | + | |
| - | # | + | |
| - | # Load batman-adv module on system boot | + | |
| - | # | + | |
| - | batman-adv | + | |
| - | dummy | + | |
| - | </ | + | |
| - | + | ||
| - | Zum Aktivieren kann man nun entweder rebooten oder die Module wie nachfolgend gezeigt manuell laden. | + | |
| - | # modprobe dummy | + | |
| - | + | ||
| - | # modprobe batman_adv | + | |
| - | + | ||
| - | Wollen wir überprüfen ob beide Module geladen sind, können wir dies mit den folgenden Befehl(en) abfragen: | + | |
| - | # lsmod | grep dummy && lsmod | grep batman_adv | + | |
| - | + | ||
| - | < | + | |
| - | batman_adv | + | |
| - | bridge | + | |
| - | cfg80211 | + | |
| - | + | ||
| - | ==== Installation und Konfiguration von batctl ==== | + | |
| - | Um BATMAN verwalten zu können müssen wir nun noch " | + | |
| - | # apt-key adv --keyserver hkp:// | + | |
| - | + | ||
| - | # apt-key adv --keyserver hkp:// | + | |
| - | + | ||
| - | # echo "deb http:// | + | |
| - | + | ||
| - | # apt update | + | |
| - | + | ||
| - | # apt-get -t buster-backports install batctl | + | |
| - | + | ||
| - | Anschließend überprüfen wir ob alles korrekt geladen wurde. | + | |
| - | # batctl ra | + | |
| - | < | + | |
| - | => BATMAN_IV | + | |
| - | + | ||
| - | Available routing algorithms: | + | |
| - | * BATMAN_IV | + | |
| - | * BATMAN_V</ | + | |
| - | + | ||
| - | Nachdem bei [[https:// | + | |
| - | # batctl ra BATMAN_V | + | |
| - | + | ||
| - | Eine erneute Abfrage zeigt nun auf den korrekten Routing Algorithmus **BATMAN_V**. | + | |
| - | # batctl ra | + | |
| - | < | + | |
| - | => BATMAN_V | + | |
| - | + | ||
| - | Available routing algorithms: | + | |
| - | * BATMAN_IV | + | |
| - | * BATMAN_V</ | + | |
| - | + | ||
| - | Nun kommen wir zur Interface Konfiguration. In diesem Beispiel, werden wir das Raspberry PI im Segment " | + | |
| - | # apt install bridge-utils -y | + | |
| - | + | ||
| - | Wir können mit nachfolgendem Befehl noch überprüfen, | + | |
| - | # batctl -v | + | |
| - | + | ||
| - | batctl debian-2020.4-1~bpo10+1 [batman-adv: | + | |
| - | + | ||
| - | Da beides in der Version **2020.4** vorliegt, können wir mit der weiteren Installation und Konfiguration wie gewohnt fortfahren. | + | |
| - | + | ||
| - | ==== Interface-Konfiguration ==== | + | |
| - | Die Konfiguration selbst nehmen wir über die Datei **''/ | + | |
| - | # vim / | + | |
| - | + | ||
| - | <file bash / | + | |
| - | + | ||
| - | # Please note that this file is written to be used with dhcpcd | + | |
| - | # For static IP, consult / | + | |
| - | + | ||
| - | # Include files from / | + | |
| - | # Django : 2020-12-15 | + | |
| - | # default: source-directory / | + | |
| - | + | ||
| - | auto eth0 | + | |
| - | iface eth0 inet dhcp | + | |
| - | + | ||
| - | auto br-welt | + | |
| - | iface br-welt inet dhcp | + | |
| - | bridge-ports bat-welt | + | |
| - | pre-up / | + | |
| - | pre-up /sbin/ip link add dummy-welt type dummy | + | |
| - | pre-up /sbin/ip link set address $(ip -br l | grep eth0 | egrep -o ' | + | |
| - | pre-up /sbin/ip link set dummy-welt up | + | |
| - | pre-up / | + | |
| - | pre-up /sbin/ip link set bat-welt up | + | |
| - | pre-up / | + | |
| - | pre-up /sbin/ip link set address $(ip -br l | grep eth0 | egrep -o ' | + | |
| - | post-up /sbin/ip link set address $(ip -br l | grep eth0 | egrep -o ' | + | |
| - | </ | + | |
| - | + | ||
| - | In diesem Beispiel setzen wir die MAC Addresse für BATMAN fest auf die MAC von eth0, damit wir später auch Statistiken etc abrufen können. | + | |
| - | Anschließend starten wir den Raspberry einmal neu! | + | |
| - | # systemctl reboot | + | |
| - | + | ||
| - | ===== WIREGUARD ===== | + | |
| - | ==== Grundlagen / Hintergründe ==== | + | |
| - | Für die Verbindung unseres Offloaders/ | + | |
| - | + | ||
| - | <WRAP center round important 80%> | + | |
| - | Für die Definition und Einrichtung des WireGuard-VPN-Tunnels werden abhängig vom gewählten Segment folgende Daten und Informationen benötigt: | + | |
| - | * **Domain** : Domain/ | + | |
| - | * **Endpoint** : Hostname des VPN-Endpunktes / Gateway. | + | |
| - | * **Port** : Port am Gateway | + | |
| - | * **(remote) publickey** : Öffentliche Schlüssel des VPN-Gatway-Endpunktes | + | |
| - | * **lokale link-local-Adresse** : IPv6 Adresse des VPN-Endpunktes am Offloader | + | |
| - | * **(client) privatekey** : Private :!: Schlüssel für den WireGuard-Endpunkt am Offloader | + | |
| - | * **(client) publickey** : Öffentliche Schlüssel für den WireGuard-Endpunkt am Offloader | + | |
| - | + | ||
| - | Bitte informiert euch vorher in welches Segment ihr wollt, dementsprechend müssen die Daten aus nachstehender Tabelle entnommen bzw. lokal generiert werden! | + | |
| - | </ | + | |
| - | {{tablelayout? | + | |
| - | ^ Domain | + | |
| - | | ffmuc_muc_cty | + | |
| - | | ffmuc_muc_cty | + | |
| - | | ffmuc_muc_nord | + | |
| - | | ffmuc_muc_nord | + | |
| - | | ffmuc_muc_ost | + | |
| - | | ffmuc_muc_ost | + | |
| - | | ffmuc_muc_sued | + | |
| - | | ffmuc_muc_sued | + | |
| - | | ffmuc_muc_west | + | |
| - | | ffmuc_muc_west | + | |
| - | | ffmuc_uml_nord | + | |
| - | | ffmuc_uml_nord | + | |
| - | | ffmuc_uml_ost | + | |
| - | | ffmuc_uml_ost | + | |
| - | | ffmuc_uml_sued | + | |
| - | | ffmuc_uml_sued | + | |
| - | | ffmuc_uml_west | + | |
| - | | ffmuc_uml_west | + | |
| - | | ffmuc_welt | + | |
| - | | ffmuc_welt | + | |
| - | | ffmuc_gauting | + | |
| - | | ffmuc_gauting | + | |
| - | | ffmuc_freising | + | |
| - | | ffmuc_freising | + | |
| - | + | ||
| - | ==== Installation ==== | + | |
| - | Das zu **WireGuard** gehörige Programm **'' | + | |
| - | # apt install wireguard --assume-yes | + | |
| - | + | ||
| - | + | ||
| - | ==== Konfiguration ==== | + | |
| - | In unserem Konfigurationsbeispiel wollen wir unseren Offloader im Segment **ffmuc_welt** betreiben und uns mit dem Gateway **gw04** von Freifunk München verbinden. Demnach lauten die Daten für den VPN-Tunnelendpunkt: | + | |
| - | + | ||
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | </ | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | </ | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | </ | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | </ | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | </ | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | </ | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | </tr> | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | </tr> | + | |
| - | </ | + | |
| - | </ | + | |
| - | + | ||
| - | Wir erzeugen nun im ersten Schritt das Schlüsselpaar (private-/ | + | |
| - | # wg genkey | tee / | + | |
| - | + | ||
| - | Im Konfigurationsverzeichnis von WireGuard finden wir nun beide Schlüssel. Die Dateiberechtigungen passen wir gleich mal noch an, damit nur der User **root** auf diese zugreifen kann. | + | |
| - | # chmod 600 / | + | |
| - | + | ||
| - | Die link-local IPv6-Adresse unseres lokalen VPN-Entpunktes ermitteln wir mit Hilfe folgenden Befehls, nachdem wir den public.key zuvor erfolgreich erstellt hatten. | + | |
| - | # cat / | + | |
| - | + | ||
| - | In unserem Konfigurationsbeispiel ergibt sich also aus dem öffentlichen Schlüssel **'' | + | |
| - | + | ||
| - | Zusammengefasst haben wir also nunmehr folgende Konfigurationsparameter: | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | </ | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | </ | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | </ | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | </ | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | </ | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | </ | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | </tr> | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | </tr> | + | |
| - | </ | + | |
| - | </ | + | |
| - | + | ||
| - | <WRAP center round important 60%> | + | |
| - | + | ||
| - | **WICHTIG**: | + | |
| - | Der private Schlüssel unseres Clients (privatekey) ist natürlich nicht publik zu machen und ist nur hier im Rahmen dieses How2s abgedruckt, damit die weitere Konfiguration leichter zu verstehen ist. Im Relalife-Betrieb hüten wir diesen Schlüssel natürlich wie immer "wie unseren Augapfel" | + | |
| - | </ | + | |
| - | + | ||
| - | Damit nun das Gateway auch VPN-Verbindungen unseres WireGuard-clients akzeptieren kann benötigt dieses natürlich unseren **public-key**, | + | |
| - | # wget -q -O- --post-data=' | + | |
| - | + | ||
| - | {" | + | |
| - | + | ||
| - | Die Bestätigung **''" | + | |
| - | + | ||
| - | Damit nun der Broker vor dem Starten unseres Tunnels auch immer unseren öffentlichen Schlüssel hat, stellen wir nun noch sicher, dass dieser automatisiert vor dem Starten des WireGuard-Daemon einmal zum Broker|Gateway übertragen wird. Hierzu legen wir uns ein systemd-Startscript an. | + | |
| - | # vim / | + | |
| - | + | ||
| - | <file bash / | + | |
| - | [Unit] | + | |
| - | # see man systemd.unit | + | |
| - | Description=Inform tunnel about our wireguard-public key | + | |
| - | Documentation=https:// | + | |
| - | Bevore=wg-quick.target | + | |
| - | + | ||
| - | [Service] | + | |
| - | # see man systemd.service, | + | |
| - | ExecStart=/ | + | |
| - | StandardOutput=syslog | + | |
| - | StandardError=syslog | + | |
| - | + | ||
| - | [Install] | + | |
| - | WantedBy=default.target | + | |
| - | </ | + | |
| - | + | ||
| - | Damit systemd von unserem neuen Startscript Kenntnis hat, führen wir einen relaod des selbigen durch. | + | |
| - | # systemctl daemon-reload | + | |
| - | + | ||
| - | Zum Starten verwenden wir den bekannten Mechanismus von **'' | + | |
| - | # systemctl start broker.service | + | |
| - | + | ||
| - | Damit der Daemon beim Neustart entsprechend automatisch gestartet wird, setzen wir den Dienst auf **enabled** | + | |
| - | # systemctl enable broker.service | + | |
| - | + | ||
| - | Created symlink / | + | |
| - | + | ||
| - | Was unser Client noch benötigt ist eine rudimentäre Konfigurationsdatei für unseren WireGuard-client, | + | |
| - | # vim / | + | |
| - | <file bash / | + | |
| - | [Interface] | + | |
| - | PrivateKey = WOzTMy6u2Tad4hqBK9jn1KR5aMiu1ZDcD0KLHWlK9nY= | + | |
| - | Address = fe80:: | + | |
| - | + | ||
| - | [Peer] | + | |
| - | PublicKey = TszFS3oFRdhsJP3K0VOlklGMGYZy+oFCtlaghXJqW2g= | + | |
| - | AllowedIPs = fe80:: | + | |
| - | Endpoint = gw04.ext.ffmuc.net: | + | |
| - | PersistentKeepalive = 2 | + | |
| - | </ | + | |
| - | + | ||
| - | Als ersten Test starten wir nun den WireGuard-Tunnel und fahren diesen mit Hilfe des Befehls **'' | + | |
| - | + | ||
| - | # wg-quick up wg-welt | + | |
| - | < | + | |
| - | [#] wg setconf wg-welt / | + | |
| - | [#] ip link set mtu 1412 up dev wg-welt | + | |
| - | [#] ip -6 route add fe80:: | + | |
| - | </ | + | |
| - | + | ||
| - | Den Status unseres WireGuard-clients können wir mit Hilfe der Option **show** beim Aufruf von **'' | + | |
| - | # wg show | + | |
| - | oder einfach nur | + | |
| - | # wg | + | |
| - | zeigen uns den Status des VPN-Tunnels: | + | |
| - | < | + | |
| - | <font style=" | + | |
| - | <font style=" | + | |
| - | <font style=" | + | |
| - | <font style=" | + | |
| - | + | ||
| - | <font style=" | + | |
| - | <font style=" | + | |
| - | <font style=" | + | |
| - | <font style=" | + | |
| - | <font style=" | + | |
| - | <font style=" | + | |
| - | </ | + | |
| - | + | ||
| - | Da sowohl bei **'' | + | |
| - | Wir sollten auch nun den Tunnelenpunkt am Gateway anpingen können. In unserem Konfiguratiosnbeispiel wäre dies demnach die Ziel-IP-Adresse **'' | + | |
| - | # ping6 -c4 fe80:: | + | |
| - | < | + | |
| - | 64 bytes from fe80:: | + | |
| - | 64 bytes from fe80:: | + | |
| - | 64 bytes from fe80:: | + | |
| - | 64 bytes from fe80:: | + | |
| - | + | ||
| - | --- fe80:: | + | |
| - | 4 packets transmitted, | + | |
| - | rtt min/ | + | |
| - | + | ||
| - | Möchten wir den Tunnel wieder per Hand stoppen, verwenden wir die Option **down** beim Aufruf des Befehls **'' | + | |
| - | # wg-quick down wg-welt | + | |
| - | + | ||
| - | [#] ip link delete dev wg-welt | + | |
| - | + | ||
| - | Zum Starten und Stoppen verwenden wir aber besser die Mechanismen von **'' | + | |
| - | # systemctl start wg-quick@wg-welt | + | |
| - | + | ||
| - | Der Stop des WireGuard-Deamon erfolgt entsprechend mit: | + | |
| - | # systemctl stop wg-quick@wg-welt | + | |
| - | + | ||
| - | Den Status des WireGuard-Client-daemon fragen wir mit der Option **status** ab. | + | |
| - | # systemctl status wg-quick@wg-welt | + | |
| - | + | ||
| - | < | + | |
| - | <font style=" | + | |
| - | | + | |
| - | | + | |
| - | Docs: man: | + | |
| - | | + | |
| - | | + | |
| - | | + | |
| - | | + | |
| - | | + | |
| - | Process: 6664 ExecStart=/ | + | |
| - | Main PID: 6664 (code=exited, | + | |
| - | + | ||
| - | Dec 16 18:20:05 rpb4-wg-ol systemd[1]: Starting WireGuard via wg-quick(8) for wg/ | + | |
| - | Dec 16 18:20:05 rpb4-wg-ol wg-quick[6664]: | + | |
| - | Dec 16 18:20:05 rpb4-wg-ol wg-quick[6664]: | + | |
| - | Dec 16 18:20:05 rpb4-wg-ol wg-quick[6664]: | + | |
| - | Dec 16 18:20:05 rpb4-wg-ol wg-quick[6664]: | + | |
| - | Dec 16 18:20:05 rpb4-wg-ol systemd[1]: Started WireGuard via wg-quick(8) for wg/ | + | |
| - | </ | + | |
| - | + | ||
| - | Damit der Daemon beim Neustart entsprechend automatisch gestartet wird, setzen wir den Dienst auf **enabled** | + | |
| - | # systemctl enable wg-quick@wg-welt | + | |
| - | + | ||
| - | Created symlink / | + | |
| - | + | ||
| - | + | ||
| - | ==== WireGuard-Healthcheck ==== | + | |
| - | Im Betrieb kann es ab und an passieren, dass der WireGuard-Tunnel zusammenbricht, | + | |
| - | + | ||
| - | Da wir das ntürlich nict manuell erledigen wollen und können, legen wir uns ein kleines bash-Script hierzu an. | + | |
| - | # vim / | + | |
| - | + | ||
| - | <file bash / | + | |
| - | # Django : 2020-12-15 | + | |
| - | + | ||
| - | # Check connectivity to supernode | + | |
| - | HTTP_STATUS_CODE=(`curl --silent --interface wg-welt --get --ipv6 --connect-timeout 5 --write-out ' | + | |
| - | if [ ${HTTP_STATUS_CODE} != " | + | |
| - | logger -t checkuplink "curl --silent --interface wg-welt --get --ipv6 --connect-timeout 5 --write-out ' | + | |
| - | logger -t checkuplink "... better we restart the wireguard-tunnel!" | + | |
| - | ip link set nomaster bat-welt dev vxlan-mesh &> /dev/null | + | |
| - | ip link del dev mesh-vpn &> /dev/null | + | |
| - | ip link del wg-welt &> /dev/null | + | |
| - | systemctl stop wg-quick@wg-welt | + | |
| - | systemctl restart networking | + | |
| - | logger -t checkuplink " | + | |
| - | / | + | |
| - | logger -t checkuplink " | + | |
| - | systemctl start wg-quick@wg-uplink | + | |
| - | logger -t checkuplink " | + | |
| - | vxlan | + | |
| - | else | + | |
| - | #logger -t checkuplink " | + | |
| - | fi | + | |
| - | </ | + | |
| - | + | ||
| - | Zum Ausführen statten wir das Script mit den **'' | + | |
| - | # chmod +x / | + | |
| - | + | ||
| - | Damit das Script nun münütlich ausgeführt wird, legen wir noch einen hierzu benötigten Eintrag in der **''/ | + | |
| - | # vim / | + | |
| - | + | ||
| - | <file bash / | + | |
| - | # 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 / | + | |
| - | # that none of the other crontabs do. | + | |
| - | + | ||
| - | SHELL=/ | + | |
| - | PATH=/ | + | |
| - | + | ||
| - | # Example of job definition: | + | |
| - | # .---------------- minute (0 - 59) | + | |
| - | # | .------------- hour (0 - 23) | + | |
| - | # | | .---------- day of month (1 - 31) | + | |
| - | # | | | .------- month (1 - 12) OR jan, | + | |
| - | # | | | | .---- day of week (0 - 6) (Sunday=0 or 7) OR sun, | + | |
| - | # | | | | | | + | |
| - | # * * * * * user-name command to be executed | + | |
| - | 17 * * * * root | + | |
| - | 25 6 * * * root test -x / | + | |
| - | 47 6 * * 7 root test -x / | + | |
| - | 52 6 1 * * root test -x / | + | |
| - | # | + | |
| - | + | ||
| - | # Django : 2020-12-15 | + | |
| - | # check wireguard-connection | + | |
| - | * * * * * root / | + | |
| - | </ | + | |
| - | + | ||
| - | Sollte der WireGuard-Tunnel nun zusammenbrechen, | + | |
| - | + | ||
| - | < | + | |
| - | Dec 16 19:40:10 rpb4-wg-ol checkuplink "... better we restart the wireguard-tunnel!" | + | |
| - | Dec 16 19:40:12 rpb4-wg-ol checkuplink " | + | |
| - | Dec 16 19:40:16 rpb4-wg-ol checkuplink " | + | |
| - | Dec 16 19:40:18 rpb4-wg-ol checkuplink " | + | |
| - | + | ||
| - | ===== Mesh per vxlan ===== | + | |
| - | ==== Hintergründe ==== | + | |
| - | WireGuard selbst transportiert lediglich Layer-3-Verbindungen und keine Layer-2-Verbindungen, | + | |
| - | + | ||
| - | <WRAP center round alert 60%> | + | |
| - | **WICHTIG**: | + | |
| - | Die hierzu nötige **vxlan id** darf nicht mit der VX-LAN-ID verwechselt werden, die wir ggf. später zum Meshen hinter unserem Offloader anbieten möchten. | + | |
| - | </ | + | |
| - | + | ||
| - | ==== Berechnung der vxlan id ==== | + | |
| - | Die **vxlan id** berechnet sich aus dem **'' | + | |
| - | + | ||
| - | <WRAP center round tip 90%> | + | |
| - | Um die VXLAN ID aus einem domain_seed zu berechnen haben wir ein kleines **'' | + | |
| - | + | ||
| - | <file python get_vxlan_id_from_domain_seed.py> | + | |
| - | domain_seed = sys.argv[1] | + | |
| - | + | ||
| - | def domain_seed_bytes(key, | + | |
| - | import hashlib | + | |
| - | ret = '' | + | |
| - | v = '' | + | |
| - | i = 0 | + | |
| - | + | ||
| - | while len(ret) < 2 * length: | + | |
| - | i = i + 1 | + | |
| - | hash_this = v + key + domain_seed + str(i) | + | |
| - | v = hashlib.md5(hash_this.encode(' | + | |
| - | ret = ret + v | + | |
| - | + | ||
| - | return ret[: 2 * length] | + | |
| - | + | ||
| - | stuff = int(domain_seed_bytes(' | + | |
| - | print(stuff)</ | + | |
| - | </ | + | |
| - | + | ||
| - | Im Beispiel Vom Segment **[[https:// | + | |
| - | + | ||
| - | $ python3 get_vxlan_id_from_domain_seed.py 1f0b31cecdf980317f453b162ac476ee09cf9997b03e684d4f2f484e75d9cd26 | + | |
| - | + | ||
| - | 4831583 | + | |
| - | + | ||
| - | ==== Konfiguration ==== | + | |
| - | Zum Aktivieren der Mesh-Verbindung per vxlan legen wir uns nun ein kleines Bash-Script an. | + | |
| - | # vim / | + | |
| - | + | ||
| - | <file bash / | + | |
| - | # Django : 2020-12-15 | + | |
| - | + | ||
| - | # Bring up VXLAN | + | |
| - | ip link add mesh-vpn type vxlan id 4831583 local fe80:: | + | |
| - | ip link set up dev mesh-vpn | + | |
| - | + | ||
| - | # Bind mesh-vpn to BATMAN-Device | + | |
| - | / | + | |
| - | + | ||
| - | # If we have a BATMAN_V env we need to correct the throughput value now | + | |
| - | / | + | |
| - | </ | + | |
| - | + | ||
| - | Damit das Script später direkt ausgeführt werden kann statten wir es noch mit den **'' | + | |
| - | # chmod +x / | + | |
| - | + | ||
| - | Damit das vxlan-Meshing automatisch beim Starten unseres Offloaders gestartet wird, legen wir uns auch hier ein entsprechendes systemd-Startscript an. | + | |
| - | # vim / | + | |
| - | <file bash / | + | |
| - | [Unit] | + | |
| - | # see man systemd.unit | + | |
| - | Description=Bringing up VXLAN Interface | + | |
| - | Documentation=https:// | + | |
| - | After=wg-quick@wg-welt.service | + | |
| - | + | ||
| - | [Service] | + | |
| - | # see man systemd.service, | + | |
| - | Type=oneshot | + | |
| - | ExecStart=/ | + | |
| - | StandardOutput=syslog | + | |
| - | StandardError=syslog | + | |
| - | + | ||
| - | [Install] | + | |
| - | WantedBy=multi-user.target | + | |
| - | </ | + | |
| - | + | ||
| - | Wie schon zuvor bei unserem Broker-Informations-systemd-Startscript informieren wir hier nun systemd über unsere neue systemd-Startupdatei. | + | |
| - | # systemctl daemon-reload | + | |
| - | + | ||
| - | Nun können wir das vxlan-Meshing via systemd starten. | + | |
| - | # systemctl start vxlan.service | + | |
| - | + | ||
| - | Für den automatischen Start beim Hochfahren unseres Offloaders aktivieren wir nun noch das entsprechende Script. | + | |
| - | # systemctl enable vxlan.service | + | |
| - | + | ||
| - | Created symlink / | + | |
| - | + | ||
| - | ===== ext-respondd ===== | + | |
| - | + | ||
| - | <WRAP center round important 80%> | + | |
| - | Dieser Teil ist wichtig, da es sein kann dass man gegen die Nutzungsbedingungen seiner Community verstößt, wenn man sich nicht als Knoten im Netz meldet. Außerdem trägt es generell zur Netzhygiene bei, wenn alle Knoten in den Statistiken auftauchen. | + | |
| - | </ | + | |
| - | + | ||
| - | ==== Werteermittlung ==== | + | |
| - | Wir ermitteln also am einfachsten die Geo-Koordinaten aus der Freifunk München Karte: https:// | + | |
| - | + | ||
| - | {{ :knb:raspberry: | + | |
| - | + | ||
| - | + | ||
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | </ | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | </ | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | </ | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | </ | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | </ | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | </ | + | |
| - | </ | + | |
| - | </ | + | |
| - | + | ||
| - | + | ||
| - | ==== Installation ==== | + | |
| - | Nachdem wir auch auf der Knotenkarte auftauchen wollen, installieren wir auch noch ext-respondd. | + | |
| - | + | ||
| - | # apt install git python3-netifaces -y | + | |
| - | # git clone https:// | + | |
| - | # cp / | + | |
| - | # systemctl daemon-reload | + | |
| - | # systemctl enable ext-respondd | + | |
| - | + | ||
| - | ==== Konfiguration ==== | + | |
| - | Bevor wir den Daemon starten, müssen wir diesen noch die Konfigurationsdateien von ext-respondd entsprechend anpassen. | + | |
| - | + | ||
| - | <WRAP center round tip 60%> | + | |
| - | **WICHTIG: | + | |
| - | </ | + | |
| - | + | ||
| - | Wir tragen demnach folgende Daten ein: | + | |
| - | \\ | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | </ | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | </ | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | </ | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | </ | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | </ | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | </ | + | |
| - | </ | + | |
| - | </ | + | |
| - | + | ||
| - | # vim / | + | |
| - | <file json / | + | |
| - | " | + | |
| - | " | + | |
| - | " | + | |
| - | " | + | |
| - | }, | + | |
| - | " | + | |
| - | " | + | |
| - | }, | + | |
| - | " | + | |
| - | " | + | |
| - | " | + | |
| - | }, | + | |
| - | " | + | |
| - | " | + | |
| - | " | + | |
| - | } | + | |
| - | }, | + | |
| - | " | + | |
| - | } | + | |
| - | </ | + | |
| - | + | ||
| - | # vim / | + | |
| - | <file json opt/ | + | |
| - | " | + | |
| - | " | + | |
| - | " | + | |
| - | " | + | |
| - | " | + | |
| - | " | + | |
| - | } | + | |
| - | </ | + | |
| - | + | ||
| - | ==== Daemon starten ==== | + | |
| - | Nun starten wir unseren Daemon **ext-respondd**. | + | |
| - | # systemctl start ext-respondd.service | + | |
| - | + | ||
| - | Den Status des Daemon fragen wir wie folgt ab. | + | |
| - | # systemctl status ext-respondd.service | + | |
| - | + | ||
| - | < | + | |
| - | <font style=" | + | |
| - | | + | |
| - | | + | |
| - | Main PID: 2184 (python3) | + | |
| - | Tasks: 1 (limit: 4915) | + | |
| - | | + | |
| - | | + | |
| - | + | ||
| - | Dec 16 20: | + | |
| - | Dec 16 20:40:11 rpb4-wg-ol ext-respondd.py[2184]: Warning - option -m was deprecated and will be removed in the future | + | |
| - | Dec 16 20:40:31 rpb4-wg-ol ext-respondd.py[2184]: Warning - option -m was deprecated and will be removed in the future | + | |
| - | Dec 16 20:40:31 rpb4-wg-ol ext-respondd.py[2184]: | + | |
| - | Dec 16 20:40:31 rpb4-wg-ol ext-respondd.py[2184]: | + | |
| - | Dec 16 20:40:31 rpb4-wg-ol ext-respondd.py[2184]: | + | |
| - | Dec 16 20:40:31 rpb4-wg-ol ext-respondd.py[2184]: | + | |
| - | Dec 16 20:40:31 rpb4-wg-ol ext-respondd.py[2184]: | + | |
| - | </ | + | |
| - | + | ||
| - | Nach kurzer Zeit taucht unser Node dann auch auf der Karte auf. | + | |
| - | {{ : | + | |
| - | + | ||
| - | + | ||
| - | ===== Konfigurations-/ | + | |
| - | Nun wollen wir auch prüfen welche Verbindungen unser Offloader hält. | + | |
| - | + | ||
| - | # ip addr show dev br-welt | + | |
| - | < | + | |
| - | link/ether dc: | + | |
| - | inet 10.80.204.2/ | + | |
| - | | + | |
| - | inet6 2001: | + | |
| - | | + | |
| - | inet6 fe80:: | + | |
| - | | + | |
| - | + | ||
| - | Wie sehen also, dass unser Node die Adressen **'' | + | |
| - | Das Gleiche erreichen wir mit Hilfe dieses Befehls: | + | |
| - | # ip -br a | grep br-welt | + | |
| - | + | ||
| - | br-welt | + | |
| - | + | ||
| - | Wir sehen somit die Adressen auf unseren Interfaces aus dem gewählten Segment. | + | |
| - | + | ||
| - | Als nächstes prüfen wir, ob die beiden Interfaces **'' | + | |
| - | # batctl meshif bat-welt if | + | |
| - | + | ||
| - | dummy-welt: active | + | |
| - | mesh-vpn: active | + | |
| - | + | ||
| - | Den **Neighbor** unseres Nodes finden wir wie folgt heraus: | + | |
| - | # batctl meshif bat-welt n | + | |
| - | < | + | |
| - | IF | + | |
| - | 8a: | + | |
| - | + | ||
| - | Zu guter Letzt sehen wir uns noch die Gateway-Liste an über bzw. mit denen unser Offloader verbunden ist. | + | |
| - | # batctl meshif bat-welt gwl | + | |
| - | < | + | |
| - | Router | + | |
| - | * f2: | + | |
| - | f2: | + | |
| - | + | ||
| - | ===== Meshing per Kabel ===== | + | |
| - | Möchte man per Kabel meshen, so ist dies auf Grund dessen, dass unser Raspberry nur eine Netzwerkschnittstelle hat, im Grunde nur per **VLAN** realisierbar. | + | |
| - | + | ||
| - | Dazu ist es erforderlich, | + | |
| - | # vim / | + | |
| - | + | ||
| - | <file bash / | + | |
| - | auto eth0.666 | + | |
| - | iface eth0.666 inet manual | + | |
| - | post-up / | + | |
| - | post-up / | + | |
| - | </ | + | |
| - | + | ||
| - | <WRAP center round important 65%> | + | |
| - | **Bitte beachten**: \\ | + | |
| - | Das Setup funktioniert nur in Umgebungen ohne VXLAN Meshing. Mit VXLAN Meshing braucht es auch noch ein VXLAN Interface. Details hierzu finden sich im Nachgang! | + | |
| - | </ | + | |
| - | ===== Mesh per vxlan ===== | + | |
| - | <WRAP center round tip 65%> | + | |
| - | Für andere Communities benötigt man die entsprechenden VXLAN IDs zum Meshen - also bei Bedarf bei der lokalen Community nachhaken! | + | |
| - | </ | + | |
| - | + | ||
| - | Um meshing per Kabel nutzen zu können, muss bei manchen Communities (wie zum Beispiel bei FFMUC) VXLAN benutzt werden. | + | |
| - | + | ||
| - | Bei uns gibt es momentan folgende VXLAN IDs, diese werden von GLUON dynamisch aus dem domain_seed erzeugt. | + | |
| - | + | ||
| - | ^ Domain | + | |
| - | | ffmuc_muc_cty | + | |
| - | | ffmuc_muc_nord | + | |
| - | | ffmuc_muc_ost | + | |
| - | | ffmuc_muc_sued | + | |
| - | | ffmuc_muc_west | + | |
| - | | ffmuc_uml_nord | + | |
| - | | ffmuc_uml_ost | + | |
| - | | ffmuc_uml_sued | + | |
| - | | ffmuc_uml_west | + | |
| - | | ffmuc_gauting | + | |
| - | | ffmuc_freising | + | |
| - | | ffmuc_welt | + | |
| - | + | ||
| - | <WRAP center round tip 80%> | + | |
| - | Um die VXLAN ID aus einem domain_seed zu berechnen haben wir ein kleines {{ : | + | |
| - | + | ||
| - | < | + | |
| - | </ | + | |
| - | + | ||
| - | Die Konfiguration in / | + | |
| - | + | ||
| - | <file bash / | + | |
| - | auto eth0.666 | + | |
| - | iface eth0.666 inet manual | + | |
| - | pre-up /sbin/ip link add vxlan-mesh type vxlan id 16306234 group ff02::15c dstport 4789 port 32768 61000 no udpcsum udp6zerocsumtx udp6zerocsumrx dev eth0.666 || true | + | |
| - | up /sbin/ip link set vxlan-mesh up | + | |
| - | post-up / | + | |
| - | post-up / | + | |
| - | down ip link set vxlan-mesh down | + | |
| - | post-down ip link del vxlan-mesh || true | + | |
| - | </ | + | |
| - | + | ||
| - | Damit das vxlan-mesh Interface auch der bevorzugte Meshingpoint in BATMAN_V wird noch folgendes in die **''/ | + | |
| - | # vim / | + | |
| - | + | ||
| - | <file bash / | + | |
| - | # | + | |
| - | # 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 [ " | + | |
| - | printf "My IP address is %s\n" " | + | |
| - | fi | + | |
| - | + | ||
| - | # Django : 2020-12-15 | + | |
| - | / | + | |
| - | + | ||
| - | exit 0 | + | |
| - | </ | + | |
| - | Zum Aktivieren unserer Konfigurationsänderung fahren wir entweder das Netzwerkiinterface hoch oder starten unseren Offloader einfach einmal neu: | + | |
| - | # systemctl reboot | + | |
| - | + | ||
| - | Wenn alles geklappt hat und ihr bereits einen Router zum Meshen in diesem VLAN habt, sollte danach folgendes in batctl zu sehen sein. | + | |
| - | | + | |
| - | + | ||
| - | < | + | |
| - | IF | + | |
| - | 8e: | + | |
| - | a2: | + | |
| - | 9a: | + | |
| - | 6a: | + | |
| - | + | ||
| - | Sollte sich kein Client am Mesh VLAN befinden, wird die vxlan-mesh Zeile nicht angezeigt. | + | |
| - | + | ||
| - | Außerdem sollten die Interfaces wie folgt aussehen: | + | |
| - | # batctl -m bat-welt if | + | |
| - | + | ||
| - | dummy-welt: active | + | |
| - | vxlan-mesh: active | + | |
| - | fastd-welt: active | + | |
| - | + | ||
| - | Leider ist der Link zum Gateway auf der Map nicht zu sehen. | + | |
| - | + | ||
| - | ===== Wifi Clients ===== | + | |
| - | Soll der Offloader auch ein WiFI-Clientnetz ausstrahlen, | + | |
| - | + | ||
| - | {{page>: | + | |
| - | + | ||
| - | Die Liste der SSIDs findet ihr hier: | + | |
| - | {{page>: | + | |
| - | ==== Installation ==== | + | |
| - | # apt install hostapd -y | + | |
| - | # echo ' | + | |
| - | + | ||
| - | ==== Konfiguartion ==== | + | |
| - | Nun legen wir uns eine entsprechende KOnfigurationsdatei an. | + | |
| - | # vim / | + | |
| - | + | ||
| - | <file bash / | + | |
| - | + | ||
| - | ssid=muenchen.freifunk.net/ | + | |
| - | + | ||
| - | 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 | + | |
| - | </ | + | |
| - | + | ||
| - | Anschließend ativieren und starten wir den **'' | + | |
| - | # systemctl unmask hostapd | + | |
| - | # systemctl enable hostapd | + | |
| - | # systemctl start hostapd | + | |
| - | + | ||
| - | Das Netzwerkinterface **'' | + | |
| - | # vim / | + | |
| - | <file bash / | + | |
| - | # | + | |
| - | # 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 [ " | + | |
| - | printf "My IP address is %s\n" " | + | |
| - | fi | + | |
| - | # Django : 2020-12-15 | + | |
| - | sleep 10; /sbin/brctl addif br-welt wlan0 | + | |
| - | + | ||
| - | exit 0 | + | |
| - | </ | + | |
| - | + | ||
| - | Am Besten nochmal rebooten um sicher zugehen dass alles passt, danach einfach mit dem ClientWifi verbinden. | + | |
| - | # systemctl reboot | + | |
| - | + | ||
| - | ===== LAN Clients ===== | + | |
| - | Will man LAN Clients versorgen, so erstellt man am einfachsten ein VLAN getaggtes Clientnetz. Dazu erstellt man in der Konfigurationsdatei **''/ | + | |
| - | # vim / | + | |
| - | <file bash / | + | |
| - | auto eth0.333 | + | |
| - | iface eth0.333 inet manual | + | |
| - | + | ||
| - | auto br-welt | + | |
| - | iface br-welt inet dhcp | + | |
| - | bridge-ports bat-welt eth0.333 | + | |
| - | </ | + | |
| - | + | ||
| - | ===== Geschwindigkeiten ===== | + | |
| - | + | ||
| - | Nun zur wichtigsten Frage, welche Performance kann man erwarten. | + | |
| - | + | ||
| - | Hier ein paar Speedtest Ergebnisse: | + | |
| - | + | ||
| - | WiFi Client an VDSL 100: \\ | + | |
| - | {{ : | + | |
| - | + | ||
| - | Kabel Client an VDSL 100: \\ | + | |
| - | {{ : | + | |
| - | + | ||
| - | Kabel Client an 1Gbit/s Glas: \\ | + | |
| - | {{ : | + | |
| - | + | ||
| - | $ wget -O /dev/null https:// | + | |
| - | + | ||
| - | < | + | |
| - | Resolving speed.hetzner.de (speed.hetzner.de)... 88.198.248.254 | + | |
| - | Connecting to speed.hetzner.de (speed.hetzner.de)|88.198.248.254|: | + | |
| - | HTTP request sent, awaiting response... 200 OK | + | |
| - | Length: 10485760000 (9.8G) [application/ | + | |
| - | Saving to: ‘/ | + | |
| - | / | + | |
| - | </ | + | |
| - | + | ||
| - | ===== Uplink per LTE via iOS Gerät ===== | + | |
| - | Nebenbei gibt es noch die Möglichkeit, | + | |
| - | # apt install usbmuxd libimobiledevice6 -y | + | |
| - | # vim / | + | |
| - | + | ||
| - | <file bash / | + | |
| - | allow-hotplug eth1 | + | |
| - | iface eth1 inet dhcp | + | |
| - | + | ||
| - | ... | + | |
| - | </ | + | |
| - | + | ||
| - | Am Besten rebootet man den Raspberry Offloader einmal. Danach steckt ihr euer iOS Gerät per USB an während ihr im Hotspot Menü seid und werdet gefragt, ob das PI Zugriff bekommen kann. Das beantwortet ihr mit " | + | |
| - | + | ||
| - | Euer PI bezieht sich nun eine IP per DHCP vom iOS Gerät und kann darüber Verbindungen zu den Freifunk Gateways aufbauen. | + | |
| - | + | ||
| - | Und so sieht ein Mobile PI mit iPad als Uplink aus: | + | |
| - | + | ||
| - | {{ : | + | |
| - | + | ||
| - | ===== OLED Display ===== | + | |
| - | {{: | + | |
| - | {{: | + | |
| - | + | ||
| - | Im nachfolgenden Beispiel verwenden wir ein OLED Display von [[https:// | + | |
| - | ==== Anschluss/ | + | |
| - | Angeschlossen wird das Ganze wie folgt: | + | |
| - | < | + | |
| - | < | + | |
| - | </ | + | |
| - | + | ||
| - | ==== I2C-Bus aktivieren ==== | + | |
| - | Als nächstes aktivieren wir die I2C Schnittstelle und installieren die notwendige Software. | + | |
| - | + | ||
| - | # echo i2c-bcm2708 >> / | + | |
| - | # echo i2c-dev >> / | + | |
| - | + | ||
| - | # apt install python3-dev python3-smbus i2c-tools python3-pil python3-pip python3-setuptools python3-rpi.gpio -y | + | |
| - | + | ||
| - | Bevor wir nun einen Reboot durchführen kontrollieren wir noch, ob in der // | + | |
| - | | + | |
| - | < | + | |
| - | + | ||
| - | # Uncomment some or all of these to enable the optional hardware interfaces | + | |
| - | # Django : 2020-12-15 - für OLED Display Support aktiviert | + | |
| - | # default: # dtparam=i2c_arm=on | + | |
| - | dtparam=i2c_arm=on | + | |
| - | + | ||
| - | ...</ | + | |
| - | + | ||
| - | Nun am Besten einmal rebooten. | + | |
| - | # systemctl reboot | + | |
| - | + | ||
| - | ==== Funktionstest ==== | + | |
| - | Danach überprüfen wir ob das Display erkannt wird. | + | |
| - | # i2cdetect -y 1 | + | |
| - | < | + | |
| - | 00: -- -- -- -- -- -- -- -- -- -- -- -- -- | + | |
| - | 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- | + | |
| - | 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- | + | |
| - | 30: -- -- -- -- -- -- -- -- -- -- -- -- 3c -- -- -- | + | |
| - | 40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- | + | |
| - | 50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- | + | |
| - | 60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- | + | |
| - | 70: -- -- -- -- -- -- -- -- | + | |
| - | </ | + | |
| - | + | ||
| - | Wie man sieht meldet sich das Display unter der Adresse **3c**. | + | |
| - | + | ||
| - | ==== Installation der Software-Bibliotheken ==== | + | |
| - | Jetzt installieren wir die notwendige Python Library um das Display ansteuern zu können. | + | |
| - | # apt install git fonts-freefont-ttf -y | + | |
| - | # cd / | + | |
| - | # git clone https:// | + | |
| - | # cd Adafruit_Python_SSD1306 | + | |
| - | # python3 setup.py install | + | |
| - | + | ||
| - | Anschließend können wir mit ein paar Beispielen probieren ob das Display korrekt funktioniert. | + | |
| - | # cd examples | + | |
| - | # python3 / | + | |
| - | + | ||
| - | Auf dem Display werden ein paar Systemdaten angezeigt: | + | |
| - | + | ||
| - | {{ : | + | |
| - | + | ||
| - | ==== Script installieren und anpassen ==== | + | |
| - | Nachdem alles alles soweit funktioniert, | + | |
| - | + | ||
| - | Anschließend das [[https:// | + | |
| - | # cd / | + | |
| - | # git clone https:// | + | |
| - | # cd raspberry-oled-bandwidth | + | |
| - | + | ||
| - | Nun passen wir in dem Script folgende Variabelen unseren Gegebenheiten an: | + | |
| - | * '' | + | |
| - | * '' | + | |
| - | * '' | + | |
| - | * '' | + | |
| - | + | ||
| - | # vim / | + | |
| - | + | ||
| - | <file python / | + | |
| - | # Inspired by https:// | + | |
| - | # | + | |
| - | # 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 = ' | + | |
| - | vpn = ' | + | |
| - | batman = ' | + | |
| - | # Django : 2020-12-15 | + | |
| - | # default: primary_mac = ' | + | |
| - | primary_mac = ' | + | |
| - | + | ||
| - | # We assume 100mbit/s max bandwidth | + | |
| - | maxRateIn = 10000000 | + | |
| - | maxRateOut = 10000000 | + | |
| - | PImaxRateIn = 10000000 | + | |
| - | PImaxRateOut = 10000000 | + | |
| - | + | ||
| - | ### DO NOT EDIT BELOW THIS POINT ### | + | |
| - | + | ||
| - | # Raspberry Pi pin configuration: | + | |
| - | # Django : 2020-15-12 | + | |
| - | # default: RST = 24 | + | |
| - | RST = ' | + | |
| - | + | ||
| - | # 128x64 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 ' | + | |
| - | width = disp.width | + | |
| - | height = disp.height | + | |
| - | image = Image.new(' | + | |
| - | + | ||
| - | # Get drawing object to draw on image. | + | |
| - | draw = ImageDraw.Draw(image) | + | |
| - | + | ||
| - | font = ImageFont.truetype('/ | + | |
| - | fontsmall = ImageFont.truetype('/ | + | |
| - | fontverysmall = ImageFont.truetype('/ | + | |
| - | fontmedium = ImageFont.truetype('/ | + | |
| - | + | ||
| - | #Display Image | + | |
| - | disp.image(image) | + | |
| - | disp.display() | + | |
| - | + | ||
| - | # | + | |
| - | + | ||
| - | def get_network_bytes(interface): | + | |
| - | for line in open('/ | + | |
| - | if interface in line: | + | |
| - | data = line.split(' | + | |
| - | rx_bytes, tx_bytes = (data[0], data[8]) | + | |
| - | return (int(rx_bytes), | + | |
| - | + | ||
| - | def drawBar (x, barHeight): | + | |
| - | # parameters are x, y, end x, end y | + | |
| - | # draw.rectangle ((x, height - barHeight, x + 10, height -1), outline=255, | + | |
| - | draw.rectangle ((x, 32 - barHeight, x + 8, height - 32), outline=255, | + | |
| - | + | ||
| - | def drawBarLOW (x, barLOWHeight): | + | |
| - | # parameters are x, y, end x, end y | + | |
| - | draw.rectangle ((x, 32 + barLOWHeight, | + | |
| - | + | ||
| - | def textRate(rate): | + | |
| - | # rate -> raw bitrate | + | |
| - | # Returns: SI formatted bitrate | + | |
| - | if rate == 0: | + | |
| - | return " | + | |
| - | rate = rate * 8 | + | |
| - | size_name = ( | + | |
| - | " | + | |
| - | i = int(math.floor(math.log(rate , 1024))) | + | |
| - | p = math.pow(1024, | + | |
| - | 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, | + | |
| - | + | ||
| - | 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(' | + | |
| - | 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, | + | |
| - | PIoutMax = max(PIoutMax, | + | |
| - | + | ||
| - | #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, | + | |
| - | draw.text((26, | + | |
| - | + | ||
| - | draw.text((81, | + | |
| - | draw.text((81, | + | |
| - | + | ||
| - | # Batman Clients | + | |
| - | clients = subprocess.check_output(" | + | |
| - | draw.text((0, | + | |
| - | draw.text((10, | + | |
| - | + | ||
| - | #max rates | + | |
| - | draw.text((36, | + | |
| - | draw.text((26, | + | |
| - | draw.text((26, | + | |
| - | + | ||
| - | draw.text((90, | + | |
| - | draw.text((81, | + | |
| - | draw.text((81, | + | |
| - | + | ||
| - | disp.image(image) | + | |
| - | disp.display() | + | |
| - | + | ||
| - | </ | + | |
| - | + | ||
| - | Nun können das Script erst einmal manuell anstarten und prüfen ob die gewünschten Informationen richtig angezeigt werden. | + | |
| - | # / | + | |
| - | + | ||
| - | {{ : | + | |
| - | + | ||
| - | Um nun nicht jedes mal beim Starten des Offloaders/ | + | |
| - | # vim / | + | |
| - | + | ||
| - | <file bash / | + | |
| - | [Unit] | + | |
| - | After=network.target | + | |
| - | + | ||
| - | [Service] | + | |
| - | ExecStart=/ | + | |
| - | + | ||
| - | [Install] | + | |
| - | WantedBy=default.target | + | |
| - | </ | + | |
| - | + | ||
| - | Anschließend Informieren wir unser System über unser definiertes Daemon-Startscript und aktivieren dies auch gleich noch. | + | |
| - | # systemctl daemon-reload | + | |
| - | # systemctl enable oled-bandwidth.service | + | |
| - | + | ||
| - | Zu guter letzte rebooten wir nun unseren Rechner. | + | |
| - | # systemctl reboot | + | |
| - | + | ||
| - | {{ : | + | |
| - | + | ||
| - | ===== links ===== | + | |
| - | // | + | |