knb:raspberry

Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.

Link zu dieser Vergleichsansicht

Beide Seiten der vorigen Revision Vorhergehende Überarbeitung
Nächste Überarbeitung
Vorhergehende Überarbeitung
knb:raspberry [2020/11/30 13:55] – Djangoknb:raspberry [2026/11/02 19:25] (aktuell) – Ins Archiv verschoben: archiv:knb:raspberry wartung
Zeile 1: Zeile 1:
-{{htmlmetatags>metatag-robots=(index,follow)  +====== Archiviert: Offloader auf Basis eines Raspberry PI 4B (FASTD) ======
-metatag-description=(Offloader auf Basis eines Raspberry PI 4B) +
-metatag-keywords=(Freifunk,Offloader,Raspberry PI 4B,Pi4,ffmuc,Raspbian,awlnx)  +
-}} +
-====== Offloader auf Basis eines Raspberry PI 4B ====== +
-{{:ffmuc_logo.png?nolink&150|Bild: Freifunk München Logo}}+
  
 +Diese Anleitung ist veraltet und liegt jetzt im Archiv: [[:archiv:knb:raspberry]].
  
-<WRAP center round important 80%> +Für den Raspberry Pi 4 gibt es ein fertiges Freifunk-München-Image: [[:knb:rpb4]].
-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> +
- +
-<WRAP center round tip 80%> +
-Diese Anleitung funktioniert auf quasi allen Linux basierten Betriebssystemen, mit ein paar Anpassungen. +
-</WRAP> +
- +
-Mit dem [[https://www.raspberrypi.org/documentation/hardware/raspberrypi/bcm2711/rpi_DATA_2711_1p0_preliminary.pdf|Raspberry PI 4]] ist es das erste Mal möglich, einen Offloader sinnvoll auf einem PI zu betreiben. Denn in dieser Version bietet der Ethernet Anschluss genug Durchsatz und die CPU ist leistungsfähig genug um eine ordentliche fastd Performance zu bieten. Dies ist bei den Vorgänger Modellen leider **nicht** der Fall. +
- +
-<WRAP center round important 80%> +
-Für kabelgebundene Clients und/oder Meshing per Kabel benötigt ihr einen VLAN-fähigen Switch! +
-</WRAP> +
- +
- +
-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. +
- +
-{{:knb:raspberry:raspi-lab.jpg?395 |}} +
-{{:knb:raspberry:rpi.jpg?405|}} \\ +
-{{:knb:raspberry:19-06-26_14-06-10_2041.jpg?405|}} +
- +
-Nachdem es kein fertiges Gluon Image für das Raspberry PI 4B gibt im Moment, installieren wir erstmal strikt nach Anleitung das aktuelle Raspbian. +
- +
-Außerdem ermöglicht uns der Einsatz von Raspbian, dass wir alle normalen Anwendungen wie Webserver, Chatserver oder den Unifi-Controller einfach installieren können. +
- +
-<WRAP center round tip 80%> +
-Auf dem FFBSeeCamp 2019 gab es auch einen [[http://cloud.ffmuc.net/s/WGPPJyLyERQ2Xd7|Vortrag zum Thema]].\\ +
- +
-Vom CCC gibt es dazu auch einen **//recent audio-only feed//** [[https://player.fm/series/chaos-computer-club-recent-audio-only-feed/raspberry-pi4-als-offloader-tc19|Raspberry PI4 als Offloader (tc19)]]. +
-</WRAP> +
- +
- +
-Eine Anleitung dazu findet ihr auf der [[https://www.raspberrypi.org/documentation/installation/installing-images/README.md|offiziellen Raspbian Seite]]. +
- +
-Am Ende der Prozedur, empfiehlt es sich auf der Boot Partition einfach eine leere Datei mit dem Namen "ssh" anzulegen. Das aktiviert den SSH Daemon und man kann bequem per Putty, OpenSSH oder sonstigen Clients remote auf das PI zugreifen. +
- +
-<WRAP center round tip 80%> +
-Der Benutzername lautet "pi" und das Passwort "raspberry".  +
-Unbedingt ändern! Sonst kommen Leute aus dem Internet auf euer Raspberry! +
-</WRAP> +
- +
-<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 +
-Anschließend starten wir den Raspberry 1x neu! +
-   # systemctl reboot +
-</WRAP> +
- +
-===== Ansible-Playbook gesteuerter Bau des Offloaders ===== +
-Wer nicht  die nachfolgenden gut dokumentierten Schritte per Hand ausführen möchte, kann sich auch mit Hilfe von **[[https://www.ansible.com/|Ansible]]** binnen 20 Minuten automatisiert einen Offloader Menügeführt und scriptiert erstellen lassen.  +
- +
-<WRAP center round tip 80%> +
-Das entsprechende **[[https://wiki.mailserver.guru/doku.php/centos:ansible:ffmuc-rpb4-ol|HOWTO]]** findet man in **[[https://wiki.mailserver.guru|Djangos WIKI]]**. +
-</WRAP> +
- +
-===== BATMAN ===== +
- +
- +
-Nachdem ihr euch eingeloggt habt, wechseln wir zum Root User und laden das BATMAN Kernelmodul herunter. Das wird gebraucht um nachher das Routing innerhalb des Freifunknetzes zu übernehmen. +
- +
-Am Besten schaut ihr vorher, welches die [[https://downloads.open-mesh.org/batman/releases/|aktuelle BATMAN Version]] ist.  +
-<code> +
-pi@raspberrypi:~ $ sudo su - +
-root@raspberrypi:~# cd /usr/src/ +
-root@raspberrypi:/usr/src# wget https://downloads.open-mesh.org/batman/releases/batman-adv-2019.2/batman-adv-2019.2.tar.gz +
-root@raspberrypi:/usr/src# tar xzf batman-adv-2019.2.tar.gz +
-</code> +
- +
-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. +
- +
-<code> +
-root@raspberrypi:/usr/src# apt update && apt install dkms raspberrypi-kernel-headers +
-</code> +
- +
-Anschließend müssen wir auf Grund dessen, dass der Raspberry PI Kernel crosscompiled wurde die make Skripte neu generieren. +
- +
-<code> +
-root@raspberrypi:/usr/src# cd linux-headers-$(uname -r) +
-root@raspberrypi:/usr/src/linux-headers-4.19.50-v7l+# make scripts +
-</code> +
- +
-<WRAP center round tip 80%> +
-Es kann passieren, dass hier nach einiger Zeit mit der Fehlermeldung \\ +
-"scripts/sortextable.c:31:10: fatal error: tools/be_byteshift.h: No such file or directory" \\ +
-abgebrochen wird, das stellt aber kein Problem dar. +
-</WRAP> +
- +
-Nun nachdem die Vorbereitungen getroffen sind, zurück zu BATMAN. Und dem Anlegen der dkms.conf. +
- +
-<code> +
-root@raspberrypi:/usr/src/linux-headers-4.19.50-v7l+# cd ../batman-adv-2019.2/ +
-root@raspberrypi:/usr/src/batman-adv-2019.2# vi dkms.conf +
-</code> +
- +
-Der Inhalt der dkms.conf sieht wie folgt aus: +
-<code> +
-PACKAGE_NAME=batman-adv +
-PACKAGE_VERSION=2019.2 +
- +
-DEST_MODULE_LOCATION=/extra +
-BUILT_MODULE_NAME=batman-adv +
-BUILT_MODULE_LOCATION=net/batman-adv +
- +
-MAKE="'make'" +
-CLEAN="'make' clean" +
- +
-AUTOINSTALL="yes" +
-</code> +
- +
-Die Datei speichern und schon sind wir bereit für das erste Mal bauen des Kernelmodules. +
- +
-<code> +
-root@raspberrypi:/usr/src/batman-adv-2019.2# dkms add -m batman-adv -v 2019.2 +
-root@raspberrypi:/usr/src/batman-adv-2019.2# dkms build -m batman-adv -v 2019.2 +
-root@raspberrypi:/usr/src/batman-adv-2019.2# dkms install -m batman-adv -v 2019.2 +
-</code> +
- +
-Als nächstes müssen wir dafür sorgen, dass das Kernelmodul beim Boot auch geladen wird. Dazu müssen wir die Datei "/etc/modules-load.d/batman-adv.module.conf" wie folgt anpassen. +
- +
-<code> +
-root@raspberrypi:/usr/src/batman-adv-2019.2# vi /etc/modules-load.d/batman-adv.module.conf +
-</code> +
- +
-<code> +
-# +
-# Load batman-adv module on system boot +
-# +
-batman-adv +
-dummy +
-</code> +
- +
-Nun kann man entweder rebooten oder die Module manuell laden. +
-<code> +
-root@raspberrypi:/usr/src/batman-adv-2019.2# modprobe dummy  +
-root@raspberrypi:/usr/src/batman-adv-2019.2# modprobe batman_adv +
-</code> +
- +
-Um BATMAN verwalten zu können müssen wir nun noch "batctl" installieren. +
- +
-<code> +
-root@raspberrypi:/usr/src/batman-adv-2019.2# apt install batctl +
-</code> +
- +
-Dann überprüfen wir ob alles korrekt geladen ist. +
- +
-<code> +
-root@raspberrypi:/usr/src/batman-adv-2019.2# batctl ra +
-</code> +
-<code> +
-Active routing protocol configuration: +
- +
-Selected routing algorithm (used when next batX interface is created): +
- => BATMAN_IV +
- +
-Available routing algorithms: +
- * BATMAN_IV +
- * BATMAN_V +
-</code> +
- +
-Nachdem wir BATMAN_V bei uns verwenden, sehen wir dass aktuell der falsche Routing Algorithmus ausgewählt ist. Das korrigieren einmal sofort manuell. +
- +
-<code> +
-root@raspberrypi:/usr/src/batman-adv-2019.2# batctl ra BATMAN_V +
-</code> +
- +
-Nun kommen wir zur Interface Konfiguration. In diesem Beispiel, werden wir das Raspberry PI im Segment "welt" ansiedeln, deswegen heißen auch die Interfaces entsprechend. +
- +
-<code> +
-root@raspberrypi:/usr/src/batman-adv-2019.2# apt install bridge-utils +
-</code> +
- +
-<file bash /etc/network/interfaces> +
-# 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: +
- +
-auto eth0 +
-iface eth0 inet dhcp +
- +
-auto br-welt +
-iface br-welt inet dhcp +
-        bridge-ports bat-welt +
-        pre-up /usr/sbin/batctl ra BATMAN_V +
-        pre-up /sbin/ip link add dummy-welt 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-welt +
-        pre-up /sbin/ip link set dummy-welt up +
-        pre-up /usr/sbin/batctl -m bat-welt if add dummy-welt +
-        pre-up /sbin/ip link set bat-welt up +
-        pre-up /usr/sbin/batctl -m bat-welt 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-welt +
-        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-welt +
- +
-</file> +
- +
-Im 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. +
- +
-===== FASTD ===== +
- +
-<WRAP center round important 80%> +
-Bitte informiert euch vorher in welches Segment ihr wollt, dementsprechend muss der FASTD Port angepasst werden! +
-</WRAP> +
- +
-{{tablelayout?rowsHeaderSource=Auto}} +
-^ Domain          ^ FASTD Port  ^ +
-| ffmuc_muc_cty   | 30002  | +
-| ffmuc_muc_nord  | 30003  | +
-| ffmuc_muc_ost   | 30004  | +
-| ffmuc_muc_sued  | 30005  | +
-| ffmuc_muc_west  | 30006  | +
-| ffmuc_uml_nord  | 30007  | +
-| ffmuc_uml_ost   | 30008  | +
-| ffmuc_uml_sued  | 30009  | +
-| ffmuc_uml_west  | 30010  | +
-| ffmuc_gauting   | 30012  | +
-| ffmuc_freising  | 30013  | +
-| ffmuc_welt      | 30011  | +
- +
- +
-Um zum Freifunk München Netz verbinden zu können, brauchen wir nun noch fastd. +
- +
-Diesen installieren wir einfach per apt +
-<code> +
-root@raspberrypi:~# apt install fastd +
-</code> +
- +
-Und anschließend generieren wir uns einen Key, den wir zum Verbinden und verschlüsseln benötigen. +
- +
-<code> +
-root@raspberrypi:~# fastd --generate-key +
-</code> +
- +
-<code> +
-2019-07-05 10:57:41 +0100 --- Info: Reading 32 bytes from /dev/random... +
-Secret: 1843fd17494d265d65f9563e3655728dbf1c8f7fb04365a9ab733f4debdb8f51 +
-Public: 7703d5f1766c11cc701cc039af1913faef216ced7b33dd18f87e57c172e0324e +
-</code> +
- +
-Wir benötigen davon nur den Secret Key. Anschließend erzeugen wir die Konfiguration. +
- +
-<code> +
-root@raspberrypi:~# mkdir /etc/fastd/welt +
-root@raspberrypi:~# vi /etc/fastd/welt/fastd.conf +
-</code> +
- +
-   # vi /etc/fastd/welt/fastd.conf +
- +
-<file bash/etc/fastd/welt/fastd.conf > +
-# +
-# welt FASTd configuration +
-# +
- +
-log to syslog level info; +
- +
-interface "fastd-welt"; +
- +
-method "salsa2012+umac"; +
-method "null"; +
- +
-secret "1843fd17494d265d65f9563e3655728dbf1c8f7fb04365a9ab733f4debdb8f51"; +
-mtu 1406; +
- +
-status socket "/var/run/fastd.welt.sock"; +
- +
-on up " +
-        batctl ra BATMAN_V +
-        ip link set $INTERFACE down +
-        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 $INTERFACE +
-        ip link set $INTERFACE up +
-        batctl -m bat-welt if add $INTERFACE +
- +
-"; +
- +
-on down " +
-        batctl -m bat-welt if del $INTERFACE +
-"; +
-peer group "ffmuc" { +
-        peer limit 1; +
-         +
-         peer "gw04.in.ffmuc.net" { +
-                key "179c91d4b3b6676d032b622809bbdfa563c70f8873fb2b8c1e62d61020acd550"; +
-                remote "gw04.ext.ffmuc.net" port <Port siehe oben - z.B. 30004>; +
-        } +
- +
-        peer "gw05.in.ffmuc.net" { +
-                key "f26f70fea16e0708c1899ac373b24881b16b9cbfba9d24703617e98a260abb72"; +
-                remote "gw05.ext.ffmuc.net" port <Port siehe oben - z.B. 30004>; +
-        } +
-} +
-</file> +
- +
-Nun aktivieren wir "fastd" für den Boot. +
- +
-<code> +
-root@raspberrypi:~# systemctl enable fastd@welt +
-</code> +
- +
-===== ext-respondd ===== +
- +
-<WRAP center round important 80%> +
-Dieser Teil ist wichtig, da es sein kann dass ihr gegen die Nutzungsbedingungen einiger Communities verstoßt, wenn ihr euch nicht als Knoten im Netz meldet. Außerdem trägt es generell zur Netzhygiene bei, wenn alle Knoten in den Statistiken auftauchen. +
-</WRAP> +
- +
- +
-Nachdem wir auch auf der Knotenkarte auftauchen wollen, installieren wir auch noch ext-respondd +
- +
-<code> +
-root@raspberrypi:~# apt install git python3-netifaces +
-root@raspberrypi:~# git clone https://github.com/freifunkMUC/ext-respondd /opt/ext-respondd/ +
-root@raspberrypi:~# cp /opt/ext-respondd/ext-respondd.service.example /etc/systemd/system/ext-respondd.service +
-root@raspberrypi:~# systemctl daemon-reload +
-root@raspberrypi:~# systemctl enable ext-respondd +
-</code> +
- +
-Dann müssen wir auch noch die Konfigurationsdateien von ext-respondd anpassen.  +
- +
-<WRAP center round tip 80%> +
-Bitte tragt die Daten inklusive dem Segmentnamen korrekt ein. Eine Übersicht der Segmentnamen gibt es [[https://ffmuc.net/wiki/doku.php?id=knb:raspberry#fastd|hier]]. +
- +
-</WRAP> +
-<code> +
-root@raspberrypi:~# vi /opt/ext-respondd/alias.json +
-</code> +
- +
-Die Dateien sind selbsterklärend, einfach die nötigen Infos eintragen. +
-<code> +
-{ +
-  "nodeinfo": { +
-    "hostname": "aw-raspi-4", +
-    "hardware": { +
-      "model": "Raspberry Pi 4B" +
-    }, +
-    "owner": { +
-      "contact": "awlnx @ chat.ffmuc.net" +
-    }, +
-    "system": { +
-      "site_code": "<segmentname>", +
-      "role": "client" +
-    } +
-  }, +
-  "firstseen": "2015-04-12T15:41:01" +
-} +
-</code> +
- +
-<code> +
-root@raspberrypi:~# vi /opt/ext-respondd/config.json +
-</code> +
- +
-<code> +
-{ +
-  "batman": "bat-welt", +
-  "bridge": "br-welt", +
-  "mesh-vpn": [ "fastd-welt" ], +
-  "wan": "eth0", +
-  "rate_limit": 30, +
-  "rate_limit_burst": 10 +
-} +
-</code> +
- +
-===== Checken der Konfiguration ===== +
- +
-Anschließend rebooten wir einmal und wenn alles stimmt sollte der Knoten auf der Karte erscheinen und "batctl" folgendes liefern, der Neighbor kann je nach GW ein anderer sein: +
- +
-<code> +
-root@raspberrypi:~# batctl -m bat-welt n +
-[B.A.T.M.A.N. adv 2019.1, MainIF/MAC: dummy-welt/dc:a6:32:00:6b:59 (bat-welt/86:6e:aa:be:bb:94 BATMAN_V)] +
-IF             Neighbor              last-seen +
-f2:00:22:10:00:00    0.060s (        1.0) [fastd-welt] +
-</code> +
- +
-Nun sollet ihr eine IPv6 Adresse aus dem gewählten Segment auf eurem Interface sehen. +
-<code> +
-root@raspberrypi:~# ip -br a | grep br-welt +
-br-welt          UP             10.80.203.128/21 2001:608:a01:109:dea6:32ff:fe00:6b59/64 fe80::dea6:32ff:fe00:6b59/64  +
- +
-</code> +
- +
-===== Meshing per Kabel ===== +
- +
-Falls ihr per Kabel meshen wollt, ist dies nur sinnvoll per VLAN möglich.  +
- +
-Dazu müsst ihr zuerst ein VLAN Interface in /etc/network/interfaces anlegen und dieses an das BATMAN Interface hängen. +
-<file bash /etc/network/interfaces> +
-auto eth0.666 +
-iface eth0.666 inet manual +
-      post-up /usr/sbin/batctl ra BATMAN_V +
-      post-up /usr/sbin/batctl -m bat-welt if add eth0.666 +
-</file> +
- +
-<WRAP center round important 80%> +
-Beachtet bitte, das Setup funktioniert nur in Umgebungen ohne VXLAN Meshing. Mit VXLAN Meshing braucht es auch noch ein VXLAN Interface.  +
- +
-Mehr dazu siehe unten. +
-</WRAP> +
- +
- +
-==== Mesh per vxlan==== +
- +
-<WRAP center round tip 80%> +
-Für andere Communities benötigt ihr die entsprechenden VXLAN IDs zum Meshen +
-</WRAP> +
- +
- +
-Um meshing per Kabel nutzen zu können, muss bei manchen Communities (wie bei FFMUC) VXLAN benutzt werden. +
- +
-Bei uns gibt es momentan folgende VXLAN IDs, diese werden von GLUON dynamisch aus dem domain_seed erzeugt. +
-{{tablelayout?rowsHeaderSource=Auto}} +
-^ Domain          ^ vxlan id  ^ +
-| ffmuc_muc_cty   | 10758607  | +
-| ffmuc_muc_nord  | 15521492  | +
-| ffmuc_muc_ost   | 2948862   | +
-| ffmuc_muc_sued  | 8599288   | +
-| ffmuc_muc_west  | 7318933   | +
-| ffmuc_uml_nord  | 5705961   | +
-| ffmuc_uml_ost   | 4892713   | +
-| ffmuc_uml_sued  | 16544703  | +
-| ffmuc_uml_west  | 16677749  | +
-| ffmuc_gauting   | 16175732  | +
-| ffmuc_freising  | 12937858  | +
-| ffmuc_welt      | 16306234  | +
- +
-<WRAP center round tip 80%> +
-Um die VXLAN ID aus einem domain_seed zu berechnen haben wir ein kleines {{ :knb:raspberry:get_vxlan_id.tar.gz |Python Skript}} geschrieben. +
- +
-<code>python3 get_vxlan_id_from_domain_seed.py domain_seed</code> +
-</WRAP> +
- +
-Die Konfiguration in /etc/network/interfaces sieht so aus, um per VLAN666 VXLAN Meshing für das Segment Welt zu machen. Wie ihr seht, wird dafür die ID aus der obigen Tabelle benötigt. +
- +
-<file bash /etc/network/interfaces> +
-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 /usr/sbin/batctl ra BATMAN_V +
-        post-up /usr/sbin/batctl -m bat-welt if add vxlan-mesh +
-        down ip link set vxlan-mesh down +
-        post-down ip link del vxlan-mesh || true +
-</file> +
- +
-Damit das vxlan-mesh Interface auch der bevorzugte Meshingpoint in BATMAN_V wird noch folgendes in die /etc/rc.local hinzufügen. +
- +
-<file bash /etc/rc.local> +
-echo 1000000 > /sys/devices/virtual/net/vxlan-mesh/batman_adv/throughput_override  +
-</file> +
-Danach rebooten oder das Interface hochfahren. Wenn alles geklappt hat und ihr bereits einen Router zum Meshen in diesem VLAN habt, sollte danach folgendes in batctl zu sehen sein. +
- +
-<code> +
-root@raspberrypi:~# batctl -m bat-welt n +
-[B.A.T.M.A.N. adv 2018.3, MainIF/MAC: vxlan-mesh/4a:af:0b:bf:44:0c (bat-welt/dc:a6:32:00:6b:59 BATMAN_V)] +
-IF             Neighbor              last-seen +
-52:98:0e:9b:5f:9c    0.470s (        1.0) [vxlan-mesh] +
-f2:00:22:10:00:00    0.420s (        1.0) [fastd-welt] +
-</code> +
-Sollte sich kein Client am Mesh VLAN befinden, wird die vxlan-mesh Zeile nicht angezeigt. +
- +
-Außerdem sollten die Interfaces wie folgt aussehen: +
-<code> +
-root@ffoff:~# batctl -m bat-welt if +
-dummy-welt: active +
-vxlan-mesh: active +
-fastd-welt: active +
-</code> +
- +
-Leider ist der Link zum Gateway auf der Map nicht zu sehen. +
-===== Wifi Clients ===== +
- +
-Dazu müssen wir hostapd installieren und konfigurieren; bei der Vergabe der **SSID** ist zu beachten: +
- +
-{{page>:includes:ssid&nodeader&nofooter}}  +
- +
-Die Liste der SSIDs findet ihr hier: +
-{{page>:includes:segmente&nodeader&nofooter}}  +
-  +
- +
-<code> +
-root@raspberrypi:~# apt install hostapd +
-root@raspberrypi:~# echo 'DAEMON_OPTS="-d"' >> /etc/default/hostapd  +
-root@raspberrypi:~# vi /etc/hostapd/hostapd.conf +
- +
-</code> +
- +
-   vi /etc/hostapd/hostapd.conf +
-<file bash /etc/hostapd/hostapd.conf> +
-ssid=muenchen.freifunk.net/welt +
- +
-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> +
- +
-Danach hostapd für den Systemstart aktivieren und starten. +
- +
-<code> +
-root@raspberrypi:~# systemctl unmask hostapd +
-root@raspberrypi:~# systemctl enable hostapd +
-root@raspberrypi:~# systemctl start hostapd +
-</code> +
- +
-Das Wlan0 muss nun noch in die Bridge gepackt werden. Dazu passen wir die /etc/rc.local an. +
-<code> +
-#!/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-welt wlan0 +
-exit 0 +
-</code> +
- +
-Am Besten nochmal rebooten um sicher zugehen dass alles passt, danach einfach mit dem ClientWifi verbinden. +
- +
-===== LAN Clients ===== +
-Diese sind im Grunde ganz einfach, ihr erstellt ein VLAN Interface in der /etc/network/interfaces. Und verbindet dieses mit der Bridge, schon könnt ihr per getaggtem VLAN euer Clientnetz bereitstellen. +
- +
-Hier ein Beispiel mit VLAN333, erst das VLAN Interface definieren und dann in der vorhandenen Bridge hinzufügen. +
- +
-   vi /etc/network/interfaces +
-<file bash /etc/network/interfaces> +
-auto eth0.333 +
-iface eth0.333 inet manual +
- +
-auto br-welt +
-iface br-welt inet dhcp +
-        bridge-ports bat-welt eth0.333 +
-</file> +
- +
- +
-===== Geschwindigkeiten ===== +
- +
-Nun zur wichtigsten Frage, welche Performance kann man erwarten.  +
- +
-Hier ein paar Speedtest Ergebnisse: +
- +
-WiFi Client an VDSL 100: \\ +
-{{:knb:raspberry:screenshot_2019-07-05_at_13.10.16.png?400|}} +
- +
-Kabel Client an VDSL 100: \\ +
-{{:knb:raspberry:screenshot_2019-07-01_at_10.56.01.png?800|}} +
- +
-Kabel Client an 1Gbit/s Glas: \\ +
-{{:knb:raspberry:screenshot_2019-07-01_at_10.58.31.png?800|}} +
- +
-   $ wget -O /dev/null https://speed.hetzner.de/10GB.bin --report-speed=bits +
- +
-<code>--2019-07-01 09:12:45-- https://speed.hetzner.de/10GB.bin +
-Resolving speed.hetzner.de (speed.hetzner.de)... 88.198.248.254 +
-Connecting to speed.hetzner.de (speed.hetzner.de)|88.198.248.254|:443... connected. +
-HTTP request sent, awaiting response... 200 OK +
-Length: 10485760000 (9.8G) [application/octet-stream] +
-Saving to: ‘/dev/null’ +
-/dev/null            2%[===>           ] 288.96M   115Mb/s    eta 14m 34s +
-</code> +
- +
-===== Ändern des Hostnamen ===== +
-Hat man mehr als einen Raspberry in seinem Netzwerk am laufen, so kann es mitunter sehr schnell unübersichtlich werden, wenn alle Geräte den gleichen Hostnamen verwenden und z.B. mit diesen an einem zentralen DHCP-Server melden und eine IP-Adresse beziehen. Wir wollen daher den Hostnamen auf den wer setzen, den wir für unseren Offloader beim Setzen des Nodenamen zuvor bei der Definition des **[[#ext-respondd|ext-respondd]]** beim Parameter ''**site_code**'' gesetzt hatten. In nachfolgendem Konfigurationsbeispiel verwenden wir mal den Site_code/Hostname //ff-django-raspi//. +
- +
-  pi@raspberrypi:~ $ sudo su - +
-  root@raspberrypi:~# hostnamectl set-hostname ff-django-raspi +
-  root@raspberrypi:~# vi /etc/hosts +
-<file /etc/hosts>127.0.0.1 localhost +
-::1 localhost ip6-localhost ip6-loopback +
-ff02::1 ip6-allnodes +
-ff02::2 ip6-allrouters +
- +
-127.0.1.1 ff-django-raspi</file> +
-   +
-  root@raspberrypi:~# hostnamectl +
-<code>   Static hostname: ff-django-raspi +
-         Icon name: computer +
-        Machine ID: b08567d7855541cf8110f09e88638c58 +
-           Boot ID: b35eb62018fc4446b8252eb2f2ae9ff5 +
-  Operating System: Raspbian GNU/Linux 10 (buster) +
-            Kernel: Linux 4.19.66-v7l+ +
-      Architecture: arm</code> +
- +
-Wenn wir uns nun neu mit unserem Offloader verbinden, wird der nunmehr richtige Freifunk-Node-Name auch als Hostname verwendet. +
-  pi@ff-django-raspi:~ $ +
- +
- +
- +
-===== Uplink per LTE via iOS Gerät ===== +
- +
-Nebenbei gibt es noch die Möglichkeit, Tethering mit iOS Geräten zu machen. Dazu muss usbmuxd installiert werden. Und in der /etc/network/interfaces ein Interface angelegt werden. +
- +
-<code> +
-root@raspberrypi:~# apt install usbmuxd libimobiledevice6 +
-root@raspberrypi:~# vi /etc/network/interfaces +
-</code> +
- +
-/etc/network/interfaces +
-<code> +
-allow-hotplug eth1 +
-iface eth1 inet dhcp +
-</code> +
- +
-Am Besten rebootet ihr jetzt 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 "Ja". +
- +
-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: +
-{{:knb:raspberry:pi-mobile.jpg?800|}} +
- +
-===== OLED Display ===== +
-{{:knb:raspberry:19-07-25_20-38-58_2285.jpg?233|Bild: Raspberry Reise-Offloader}} +
-{{:knb:raspberry:screenshot_2019-07-21_at_11.41.52.png?400|Bild: Testaufbau des Raspberry mit dem OLED}} +
- +
-In dem Beispiel verwenden wir ein OLED Display von [[https://www.az-delivery.de/products/0-96zolldisplay|AZDelivery]] mit 128x64 Pixeln. Das schöne an dem Display ist, es funktioniert auch mit 5V und ist damit noch einfacher anzuschließen. +
-==== Anschluss/Verkabelung ==== +
-Angeschlossen wird das Ganze wie folgt: +
-<html> +
-<table><tr><th> OLED Pin &nbsp;</th><th>  <a href="https://pinout.xyz/pinout/pin3_gpio2#">GPIO Pin</a> &nbsp;</th><th>Notes</th></tr><tr><td>Vcc</td><td>4</td><td>5V</td></tr><tr><td>Gnd</td><td>6</td><td>Ground</td></tr><tr><td>SCL</td><td>5</td><td>I2C SCL</td></tr><tr><td>SDA</td><td>3</td><td>I2C SCA</td></tr></table> +
-</html> +
- +
-==== I2C-Bus aktivieren ==== +
-Als nächstes aktivieren wir die I2C Schnittstelle und installieren die notwendige Software. +
- +
-  root@raspberrypi:~# echo i2c-bcm2708 >> /etc/modules +
-  root@raspberrypi:~# echo i2c-dev >> /etc/modules +
- +
-  root@raspberrypi:~# apt install python3-dev python3-smbus i2c-tools python3-pil python3-pip python3-setuptools python3-rpi.gpio +
- +
- +
-Bevor wir nun einen Reboot durchführen kontrollieren wir noch, ob in der //**/boot/config.txt**// das I2C-Interface auch gestartet wird. +
-   root@raspberrypi:~# vim /boot/config.txt +
-<code>... +
- +
-# Uncomment some or all of these to enable the optional hardware interfaces +
-# Django : 2019-09-11 - für OLED Display Support aktiviert +
-# default: # dtparam=i2c_arm=on +
-dtparam=i2c_arm=on +
- +
-...</code> +
- +
-Nun am Besten einmal rebooten.  +
- +
-==== Funktionstest ==== +
-Danach überprüfen wir ob das Display erkannt wird. +
-  root@raspberrypi:~# i2cdetect -y 1 +
-<code>     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f +
-00:          -- -- -- -- -- -- -- -- -- -- -- -- --  +
-10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --  +
-20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --  +
-30: -- -- -- -- -- -- -- -- -- -- -- -- 3c -- -- --  +
-40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --  +
-50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --  +
-60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --  +
-70: -- -- -- -- -- -- -- --    +
-</code> +
- +
-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. +
-<code> +
-root@raspberrypi:~# apt install git fonts-freefont-ttf +
-root@raspberrypi:~# cd /usr/local/src/ +
-root@raspberrypi:~# git clone https://github.com/adafruit/Adafruit_Python_SSD1306.git +
-root@raspberrypi:~# cd Adafruit_Python_SSD1306 +
-root@raspberrypi:~# python3 setup.py install +
-</code> +
- +
-Anschließend können wir mit ein paar Beispielen probieren ob das Display korrekt funktioniert. +
-  root@raspberrypi:~# cd examples +
-  root@raspberrypi:~# python3 /usr/local/src/Adafruit_Python_SSD1306/examples/stats.py +
- +
-Auf dem Display werden ein paar Systemdaten angezeigt: +
- +
-{{ :knb:raspberry:oled_01.png?125 |Bild: Anzeige von Systemdaten auf dem OLED nach Start des Scripts stats.py}} +
- +
-==== Script installieren und anpassen ==== +
-Nachdem alles alles soweit funktioniert, können wir als nächstes das Bandbreiten Skript installieren, welches auch gleichzeitig die verbundenen BATMAN Clients anzeigt. +
- +
-Anschließend das [[https://github.com/awlx/raspberry-oled-bandwidth|Python Skript]], welches das Display steuert installieren und anpassen. +
-  root@raspberrypi:~# cd /usr/local/src +
-  root@raspberrypi:~# git clone https://github.com/awlx/raspberry-oled-bandwidth +
-  root@raspberrypi:~# cd raspberry-oled-bandwidth +
- +
-Nun passen wir in dem Script folgende Variabelen unseren Gegebenheiten an: +
-  * ''**wifi**'' : Die definierte Schnittstelle unseres WiFi-Devices +
-  * ''**vpn**'' : [[#fastd|VPN Definitionen]] +
-  * ''**batman**'' : [[#batman|BATMAN Definitionen]] +
-  * ''**primary_mac**'' : MAC des Ethernet-Ports unseres Raspberry 4 '' # ip addr show eth0 | grep link/ether '' +
- +
-  root@raspberrypi:~# vim /usr/local/src/raspberry-oled-bandwidth/bandwidth.py +
- +
-<file python /usr/local/src/raspberry-oled-bandwidth/bandwidth.py># +
-# 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 = 'fastd-welt' +
-batman = 'bat-welt' +
-# Django : 2019-09-14 +
-# default: primary_mac = 'dc:a6:32:00:6b:59' +
-primary_mac = 'dc:a6:32:01:7f:f0' +
- +
-# 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 = 24 +
- +
-# 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 '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 ((x, height - barHeight, x + 10, height -1), outline=255, fill=255) +
-    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 -m " + 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> +
- +
-Nun können das Script erst einmal manuell anstarten und prüfen ob die gewünschten Informationen richtig angezeigt werden. +
-  root@raspberrypi:~# /usr/bin/python3 /usr/local/src/raspberry-oled-bandwidth/bandwidth.py +
- +
-{{ :knb:raspberry:oled_03.jpg?direct&200 |Bild: OLED mit Anzeige der Verbindungsdaten}} +
- +
-Um nun nicht jedes mal beim Starten des Offloaders/Gateways manuell starten müssen, legen wir uns noch ein **systemd**-Script an. +
-   root@raspberrypi:~# vim /etc/systemd/system/oled-bandwidth.service +
- +
-<file bash /etc/systemd/system/oled-bandwidth.service># Django : 2019-09-11 +
-[Unit] +
-After=network.target +
- +
-[Service] +
-ExecStart=/usr/bin/python3 /usr/local/src/raspberry-oled-bandwidth/bandwidth.py +
- +
-[Install] +
-WantedBy=default.target +
-</file> +
- +
-Anschließend Informieren wir unser System über unser definiertes Daemon-Startscript und aktivieren dies auch gleich noch.  +
-   root@raspberrypi:~# systemctl daemon-reload +
-   root@raspberrypi:~# systemctl enable oled-bandwidth.service +
- +
-Zu guter letzte rebooten wir nun unseren Rechner. +
-   root@raspberrypi:~# systemctl reboot +
- +
-{{ :knb:raspberry:oled_04.jpg?nolink&550 |Bild: OLED in Betrieb}} +
  
  • knb/raspberry.1606744540.txt.gz
  • Zuletzt geändert: 2020/11/30 13:55
  • von Django