Router Banana Pi R64 — Debian, Wireguard, RKN

Der Banana Pi 64 ist ein Einplatinencomputer ähnlich dem Raspberry Pi, jedoch mit mehreren Ethernet-Ports, was es ermöglicht, ihn zu einem Router auf Basis einer allgemeinen Linux-Distribution zu machen.

Router Banana Pi R64 — Debian, Wireguard, RKN

Ja, es gibt bereits Openwrt, aber es hat seine eigenen Eigenheiten, sowohl GUI als auch CLI; es gibt Mikrotik, aber auch dort gibt es ein eigenes GUI/CLI, und Wireguard funktioniert nicht sofort... Im Allgemeinen möchte man einen Router mit flexiblen Einstellungen, der dennoch im Rahmen des Standard-Linux bleibt, mit dem man jeden Tag arbeitet.

In diesem Artikel werde ich unter den Begriffen BPI, R64, Einplatinencomputer das Gleiche verstehen — das eigentliche Einplatinenmodell Banana Pi R64.

Auswahl des Images. Booten über eMMC

Die erste Fähigkeit, die man beim Arbeiten mit SBC im Allgemeinen und mit R64 im Besonderen erlernen muss, ist, das Betriebssystem zu laden und die Möglichkeit zu haben, mit ihm zu interagieren. Da der R64 keinen Anschluss für einen Monitor (z.B. HDMI) hat. Wenn alles ausfällt — Wifi, Ethernet-Netzwerk, Bluetooth, USB funktionieren nicht mehr, bleibt nur UART, über dessen Schnittstelle man immer überprüfen kann, was schief gelaufen ist, sowie bei Bedarf ein paar Befehle aus der Konsole auszuführen.

Algorithmus zum Anschließen an R64 über USB-UART:

  • Laufen Sie zum Elektronikgeschäft und holen Sie sich ein USB-UART-Kabel (PL2303, Serial-to-USB)
  • Schließen Sie ein Ende des USB-Kabels an den Computer an und das andere, UART, an R64, mit drei von vier Drähten, wie auf dem Bild unten.
  • Starten Sie in der Computer-Konsole sudo minicom

Danach erscheint in den meisten Fällen die Konsole des Einplatinencomputers = Erfolg.
Weitere Informationen finden Sie unter hier.

Router Banana Pi R64 — Debian, Wireguard, RKN

Am einfachsten ist es, das Betriebssystem von einer SD-Karte zu booten: laden Sie das Image herunter dem Link und spielen Sie es auf:

unzip -p 2019-08-23-ubuntu-16.04-lite-preview-bpi-r64-sd-emmc.img.zip | pv | sudo dd of=\/dev\/mmcblk0 bs=10M status=noxfer

Stecken Sie die Karte in den SD-Slot des R64, schalten Sie ein und beobachten Sie über die angeschlossene Konsole den Start von U-Boot, gefolgt vom Standard-Linux-Start.

Eine alternative Bootoption ist das Booten von der bereits im R64 integrierten 8-GB-Karte, die als eMMC bezeichnet wird. Folgen Sie der Anleitung im Wiki, um das Image auf das Gerät zu kopieren.
/dev/mmcblk0 в BPI, перегружаемся, вытаскиваем SD-карту, включаем BPI снова… и не работает. Как туда-сюда Boot-Auswahl zupf nicht daran.

Der Punkt ist, dass mindestens für BPI ein spezielles Flag gesetzt werden muss, um von dem internen Flashlaufwerk booten zu können:

root@bpi-r64:~# .\/mmc extcsd read \/dev\/mmcblk1 | grep 'PARTITION_CONFIG'\nBootkonfigurationsbytes [PARTITION_CONFIG: 0x00]\nroot@bpi-r64:~# .\/mmc bootpart enable 1 1 \/dev\/mmcblk1\nroot@bpi-r64:~# .\/mmc extcsd read \/dev\/mmcblk1 | grep 'PARTITION_CONFIG'\nBootkonfigurationsbytes [PARTITION_CONFIG: 0x48]

Weiterhin muss der spezielle Boot-Bereich den Preloader aufnehmen.

root@bpi-r64:~# echo 0 > /sys/block/mmcblk0boot0/force_ro 
root@bpi-r64:~# dd if=preloader_evb7622_64_foremmc.bin of=/dev/mmcblk0boot0

Der Hersteller R64 (China) hat dieses Binärprogramm veröffentlicht. hier. Was es macht, ist unbekannt (quellcode gibt es nicht), aber ohne es funktioniert es ebenfalls nicht.

Im Grunde, nach diesem Schritt beginnen die Images auch von eMMC zu booten. Wenn man jedoch versuchen möchte, alles von Grund auf zu erstellen, muss man noch einige Dateien (Preloader für die SD-Karte, ATF, u-boot) aufzeichnen, nur um zum Laden des Kernels zu gelangen. Dieses Thema ist bis heute entwickelt sich, aber für uns ist das Wichtigste, dass es funktioniert.

Derzeit verwende ich das Booten über eMMC ehrlich gesagt nicht, SD-Karten sind ausreichend, aber ich habe viel Zeit damit verbracht, damit es funktioniert, daher sollte es in dem Artikel sein.

Auswahl des Betriebssystems. Armbian

Die erste angewandte Aufgabe ist der Start von VPN, natürlich Wireguard. Sofort stellte sich heraus, dass es seitens des Kernels nicht kompiliert wurde und keine Header vorhanden sind. Ich habe den Kernel neu kompiliert und, aus Gewohnheit mit x86, das Kernelmodul mit DKMS erstellt. Allerdings hat mich die Kompilierungsgeschwindigkeit für kleine Hilfsprogramme auf arm64 unangenehm überrascht. Und dann wurde ein weiteres Kernelmodul benötigt, usw. Im Allgemeinen scheint es, dass alles, was mit dem Kernel zusammenhängt, besser auf einem warmen, nostalgischen x86-Laptop kompiliert wird, dann einfach per Kopie auf die R64 übertragen wird, neu gestartet wird und getestet wird.

Anders verhält es sich mit dem Userspace. In meinem Fall mit der Wahl Debian sind bereits alle für die Architektur arm64 verfügbaren Pakete auf packages.debian.org und es ist nicht nötig, etwas neu zu kompilieren.

Um kein weiteres Rad zu erfinden, habe ich portiert Armbian auf BPI R64.
Genauer gesagt: Der Userspace-Teil ist Armbian, und der Kernel stammt aus dem Repository Frank. Das aktuellste Image kann heruntergeladen werden. hier.

Alle Aktivitäten zur Entwicklung der Software für R64 finden statt auf dem Forum. Im Grunde bemüht sich der Hersteller, den Router für Openwrt populär zu machen, aber dank der Aktivitäten des Entwicklers Frank aus Deutschland finden alle Funktionen schnell im Kernel für Debian Anwendung. Erstaunlicherweise ist Frank in jedem Bereich des Forums aktiv.

Organisation des Arbeitsplatzes: Kabel

Separat möchte ich erzählen, wie man während der Entwicklung/Testphase ein SBC (nicht nur BPI) auf dem Tisch platziert, ohne ein Ethernet-Kabel von der Internetquelle quer durch den Raum/das Büro ziehen zu müssen. Schließlich muss einerseits das Gerät mit dem Internet verbunden werden, andererseits kann in diesem Gerät alles kaputtgehen, insbesondere das Wifi.

Zunächst wollte ich einen günstigen USB-Wifi "Stick" kaufen, ihn in den einzigen Port des BPI stecken und mich von Kabeln verabschieden. Dazu erwarb ich den günstigen TP-LINK TL-WN725N USB 2.0, aber sehr schnell wurde klar, dass er nicht funktionieren würde: Für den Stick wird ein Kernel-Treiber benötigt, der dort natürlich nicht vorhanden war (später habe ich den benötigten RTL8XXXU-Treiber zusammengebaut, aber das ist trotzdem unpraktisch). Und das Ethernet-Kabel hat für eine Weile das Aussehen des Raumes gestört.

Letztendlich gelang es mir, das Kabel mithilfe von Tenda MW3 (Wifi Mesh-System) loszuwerden: Ich platzierte einfach einen Würfel unter dem Tisch und verband den BPI mit einem ein Meter langen Ethernet-Kabel mit dem LAN-Port des Würfels. Erfolg.

Wireguard, RKN, Bird

Eine der Wünsche, für die ich Banana PI verwende - freien Zugang zu von RKN gesperrten Websites zu haben, insbesondere damit Telegram und Anrufe in Slack funktionieren. Zu diesem Thema wurden bereits Artikel auf Habré vorgeschlagen: eins, zwei, drei.

Die Implementierung einer solchen Lösung habe ich mit Ansible realisiert: Link.

Es wird angenommen, dass der VPS unter Ubuntu 18.04 läuft. Die Funktionalität habe ich bei zwei Hosting-Anbietern in Europa überprüft: Amazon und Digital Ocean.

Also, wir haben das oben genannte Armbian auf R64 installiert, es ist per SSH unter dem Namen hm-bananapi-1 verfügbar und hat Zugang zum Internet. Wir setzen nacheinander Ansible, Automatisierungsskripte ein und starten die Installation direkt auf R64:

# зависимости для Debian-based дистрибутивов
$ sudo apt install --no-install-recommends python3-pip python3-setuptools python3-wheel git
$ which pip3
/usr/bin/pip3

# ansible с pybook, скриптование на Python
$ pip3 install https://github.com/muravjov/ansible/archive/ansible-2.10.0.dev0-pybook2019.tar.gz

$ export PATH=~/.local/bin:$PATH
$ which ansible-playbook
/home/sa/.local/bin/ansible-playbook

$ git clone https://github.com/muravjov/ansible-bpi-r64.git
$ cd ansible-bpi-r64

$ git submodule update --init

# убеждаемся в доступности hm-bananapi-1
$ ssh hm-bananapi-1 which python3
/usr/bin/python3

# собственно установка
$ ansible-playbook ./router.py -l hm-bananapi-1

Als nächstes müssen wir unseren VPN analog auf dem VPS bereitstellen:

ansible-playbook ./router.py -l current-vpn

Hier ist das Argument immer current-vpn, während der Name des VPS in einer Variablen konfiguriert wird (in diesem Fall paris-vpn-aws-t2-micro-1):

$ grep current_vpn group_vars/all 
current_vpn: paris-vpn-aws-t2-micro-1
#current_vpn: frankfurt-vpn-d0-starter-1

Ach ja, vor all diesen Operationen müssen die Geheimnisse (insbesondere die Wireguard-Schlüssel) im Ordner ./secretsgeneriert werden, das Verzeichnis sollte so aussehen so.

Ansible-Automatisierung auf Python

Man kann feststellen, dass anstelle des YAML-Formats die Ansible-Befehle in Python-Skripten kodiert sind. Zum Vergleich, wie man den Bird-Daemon auf die gewöhnliche Weise startet:

- name: start bird
  systemd:
    name: bird
    state: started
    enabled: yes

und wie dasselbe über Python:

mit Zuordnung:
    append("name", "start bird")
    mit Zuordnung("systemd"):
        append("name",  "bird")
        append("state", "started")
        append("enabled", "ja")

Das Schreiben von Ansible-Befehlen in Python ermöglicht die Wiederverwendung von Code und eröffnet die vollständigen Möglichkeiten einer allgemeinen Programmiersprache. Zum Beispiel die Installation von bird auf R64 und VPS:

install_bird("router/bird.conf.j2")
install_bird("vpn/bird.conf.j2")

Code der Funktion ansehen install_bird().

Dieses Feature mit dem Namen pybook wurde hier. Eine Dokumentation zu pybook gibt es bisher nicht, ich werde diesen Mangel später beheben.

Was denkt upstream darüber.

Monitoring. Prometheus

Insgesamt: Telegram funktioniert, LinkedIn und Pornhub auch, insgesamt ist die Benutzererfahrung — in Ordnung. Aber alles kann kaputtgehen, und auch chinesische Hardware.

Kernel-Updates können ebenfalls interessant sein: Zum Beispiel wollte ich den Kernel von 5.4 auf 5.6 aktualisieren, nun, da ist Wireguard ja schon dabei, keine Patches nötig... Gesagt, getan: Ich habe die Patches mühsam von 5.4 auf 5.6 übertragen, der Kernel lief, das Tunnel zu VPS ist pingbar, aber bird kann sich nicht verbinden mit dem Fehler "BGP Error"... "In Panik zurückgerollt" (c) auf 5.4; den Umzug auf 5.6 habe ich in die TODO-Liste verschoben.

Deshalb habe ich zusätzlich zur Installation des Routers und VPS Monitoring (auf x86 Ubuntu 18.04) hinzugefügt, das auf einem separaten Host mit den folgenden Komponenten installiert wird:

  • prometheus, alertmanager, blackbox_exporter – alles in Docker
  • Alarme werden über einen Bot metalmatze/alertmanager-bot – ebenfalls in Docker – in einen Telegram-Kanal gesendet.
  • Tor für den Bot, damit der Bot in der Lage ist, Situationen zu alerten, in denen das Internet funktioniert, Telegram jedoch trotzdem nicht funktioniert und der Bot sich selbst nicht verbinden kann.
  • Anwendungs- Alarme: NodeVPNTroubles (kein Ping zum VPS), BirdVPNTroubles (keine Bird-Session), AntifilterDownloadTroubles (Fehler beim Download gesperrter IP-Adressen), SiteTroubles (das unglückliche Telegram ist nicht verfügbar)
  • Systemalarme, zum Beispiel, HostGrowingDiskReadLatency (billige SD-Karte wird nicht mehr gelesen)

Beispiel für die Installation des Monitorings:

ansible-playbook ./monitoring.py -l monitoring-preprod

Die Auto Discovery für Prometheus ist auf den Ordner /etc/prometheus/auto_http eingestellt, ein Beispiel für die Hinzufügung eines Hosts zum Monitoring (standardmäßig werden Hosts nicht überwacht):

bash << 'EOF'
HOSTNAME=hm-bananapi-1
IP_ADDRESS=`ssh -G $HOSTNAME | awk '/^hostname / { print $2 }'`

ssh monitoring-preprod sudo sponge /etc/prometheus/auto_http/$HOSTNAME.json << EOF2
[
  {
    "targets": ["$IP_ADDRESS:9100"],
    "labels": {
      "env": "prod",
      "hostname": "$HOSTNAME"
    }
  }
]
EOF2
EOF

TODO: 2 Anbieter, 2 BPI, Anycast Failover

Zusätzlich habe ich geplant, mich mit zwei Anbietern zu verbinden, damit das Internet auch bei Problemen mit einem Anbieter oder wenn man vergisst, für das Internet zu bezahlen, usw. weiterhin funktioniert, und um andere menschliche Faktoren zu berücksichtigen.

Die fortschrittlichste Benutzererfahrung zum Thema Multi-WAN ist beschrieben hier für das System Mwan3 unter Openwrt. Diese Lösung bietet zahlreiche Funktionen, aber die Einrichtung und der Betrieb von Multi-WAN sind insgesamt ziemlich aufwendig. Ein Beispiel: Wenn man von zwei IP-Adressen gleichzeitig auf bestimmte Websites zugreift, könnte das problematisch sein, und sie funktionieren nicht mehr => "Internet funktioniert nicht".

Angesichts dieser Erfahrung habe ich beschlossen, dass Multihoming vorerst keine Priorität hat, nur Failover. Obwohl es scheint, dass in den neuesten Linux-Versionen alles mit einem Befehl der Art funktionieren sollte:

ip route add default 
    nexthop via 192.168.1.1 weight 10 
    nexthop via 192.168.2.1 weight 5

Um einen einzigen Fehlerpunkt zu vermeiden, verwenden wir 2 BPI, die jeweils mit einem Anbieter verbunden sind, verbinden sie miteinander und machen die Verbindung zueinander dynamisch durch Bird/OSPF.

Dann kündigen wir auf jedem den gleichen IP-Adresse an, falls der Dienst verfügbar ist (Internet, DNS). Das heißt, wir setzen die Standardroute nicht selbst, sondern über Bird. Die Lösung habe ich mir abgeschaut. hier .

Diese Funktionalität habe ich bisher nicht implementiert, der heimtückische Coronavirus hat hier alles durcheinandergebracht (nicht alles kam von AliExpress an; ein weiterer Online-Shop, Layta, versprach die Lieferung innerhalb einer Woche, aber es sind bereits über einen Monat vergangen; der zweite Anbieter konnte das Kabel vor dem Lockdown nicht verlegen, er schaffte es nur, ein Loch in die Wand für das Kabel zu bohren).

Wie man ein R64 bestellt

Die Platine im offiziellen Geschäft SinoVoip.
Es ist auch besser, gleich zu bestellen:

  • Stromversorgung + den Steckertyp EU oder US angeben
  • Wärmeabführung: Kühler/Lüfter; da sowohl die CPU als auch der Switch-Chip heiß werden
  • eine Antenne für WLAN, zum Beispiel

Es gibt ein Problem — die Versandkosten sind seit einiger Zeit im offiziellen Geschäft unangemessen hoch geworden. Managerin Judy Huang versicherte mir, dass es keinen Fehler gab, und ich könne ePacket für 5 $ wählen, aber ich sah, dass es für Russland nur EMS für >33 $ gab. Unangenehm, aber nicht kritisch. Und wenn ich ein anderes Land für die Lieferung wählte (ich habe alle Kontinente durchprobiert), hätte die Lieferung etwa 5 $ gekostet. Russophob...? Aber dann fand ich heraus, dass die Versandkosten für Frankreich ebenfalls etwa 30 $ betragen, und war beruhigt.

Letztendlich schlug Judy vor, die Bestellung aufzugeben, aber nicht zu bezahlen (Hinweis: weniger auf die Karte legen, damit die automatische Zahlung nicht durchgeht); mir zu schreiben, und sie würde die Versandkosten auf einen normalen Wert senken. Erfolg.

Probleme

Nicht alles funktioniert bisher perfekt.

Leistung

Die Ansible=Python-Befehle werden langsam ausgeführt, selbst die leeren Befehle benötigen 20-30 Sekunden; das ist deutlich länger als auf dem x86-Laptop. Zunächst sind sie relativ schnell, etwa 3 Sekunden, und verlangsamen sich dann abrupt. Vielleicht liegt das an der Überhitzung der CPU (Throttling). Der Go-Code läuft ebenfalls lange:

# запрос метрик для прометея из node_exporter на Go
$ time curl -s http://172.30.1.1:9100/metrics > /dev/null

real    0m6,118s
user    0m0,005s
sys     0m0,009s

# однако температура 51 градус, не так и много
sa@bananapir64:~$ cat /sys/devices/virtual/thermal/thermal_zone0/temp
51700

Wifi

Wifi funktioniert, aber auf Armbian hört es nach etwa einem Tag auf, zu arbeiten, es steht:

sa@bananapir64:~$ dmesg | grep -E 'mt7622_wmac.*timeout'
[470303.802539] mt7622_wmac 18000000.wmac: Nachricht 38 (seq 3) Zeitüberschreitung
[470314.042508] mt7622_wmac 18000000.wmac: Nachricht 50 (seq 4) Zeitüberschreitung
...

Ein Neustart hilft nur. Ich muss weiter untersuchen.

Ethernet

Ethernet funktioniert, aber nach ~einem Tag hören die Pakete (DHCP) von R64 auf zu kommen.
Es hilft, die Schnittstelle neu zu starten:

ifdown br0; sleep 30; ifup br0

Der Treiber ist neu, ist noch nicht in den Kernel aufgenommen worden, ich hoffe, der Chinese Landen Chao wird es vollenden.

Quelle: habr.com

60GB SSD 8Gb DDR4