Router Banana Pi R64 — Debian, Wireguard, RKN

Banana Pi 64 este un computer single-board de tip Raspberry Pi, dar cu mai multe porturi Ethernet, ceea ce permite transformarea acestuia într-un router bazat pe un distribuitor Linux de uz general.

Router Banana Pi R64 — Debian, Wireguard, RKN

Da, există deja OpenWRT, dar are propriile particularități, cu GUI și CLI proprii; există Mikrotik, dar din nou, are propriile GUI/CLI, și Wireguard nu funcționează din cutie... În general, se dorește un router cu setări flexibile, rămânând în același timp în cadrul unui Linux standard, cu care lucrezi zi de zi.

În acest articol sub denumirile BPI, R64, și computerul single-board, mă voi referi la același lucru — anume la computerul single-board Banana Pi R64.

Alegerea imaginii. Încărcarea prin eMMC

Cel mai important abilități pe care trebuie să le dobândești atunci când lucrezi cu SBC în general, și cu R64 în particular, este să înveți să încarci un sistem de operare pe el și să ai posibilitatea de a interacționa cu el, deoarece R64 nu are un port pentru monitor (HDMI, de exemplu). Când totul se oprește — Wifi, rețeaua Ethernet, Bluetooth, USB și altele nu mai funcționează, există UART, prin intermediul căruia poți întotdeauna vedea ce nu a mers bine și, dacă este necesar, să rulezi câteva comenzi din consolă.

Algoritmul de conectare la R64 prin USB-UART:

  • mergem în magazinul de componente electronice pentru un cablu USB-UART (PL2303, Serial-to-USB)
  • conectăm un capăt USB la computer și celălalt, UART, la R64, cu trei fire din patru, ca în imaginea de mai jos
  • în consola computerului rulăm sudo minicom

După aceasta, în majoritatea cazurilor, consola computerului va apărea = succes.
Mai multe detalii pot fi văzute aici.

Router Banana Pi R64 — Debian, Wireguard, RKN

Apoi, cel mai simplu este să încarci sistemul de operare de pe un card SD: descărcăm de la linkul imaginea și o scriem:

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

introducem cardul în slotul SD al R64, pornim, și observăm prin consola conectată încărcarea inițială a uboot, iar apoi a sistemului Linux standard.

O alternativă de încărcare — folosind cardul de 8 Gb, încorporat în R64, numit eMMC. După instrucțiunile de pe wiki, copiem imaginea pe dispozitiv
/dev/mmcblk0 в BPI, перегружаемся, вытаскиваем SD-карту, включаем BPI снова… и не работает. Как туда-сюда Boot select nu mișca.

Problema este că, cel puțin pentru BPI, este necesar să setăm un steag special pentru a putea încărca de pe memoria flash internă:

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

Apoi, în secțiunea specială de boot trebuie să scriem preloaderul

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

Producătorul R64 (China) a pus acest binar la dispoziție aici. Ce face nu se știe (nu sunt surse), dar fără el nu va funcționa niciodată.

În general, după aceasta, imaginile încep să se încarce și din eMMC. Dacă vrei să înțelegi și să creezi imagini de la zero, atunci pentru ambele cazuri (SD/eMMC) trebuie să mai scrii încă câteva fișiere (preloader pentru cardul SD, ATF, u-boot), doar ca să ajungi la încărcarea nucleului. Această temă este încă se dezvoltă, dar pentru noi este important că funcționează și atât.

Acum, mărturisesc că nu folosesc încărcarea pe eMMC, cardurile SD sunt suficiente, dar am petrecut destul de mult timp pentru a face să funcționeze, așa că să rămână în articol.

Alegerea sistemului de operare. Armbian

Prima sarcină practică - să pornesc VPN-ul, desigur Wireguard. Imediat am descoperit că nu este compilat din partea nucleului, iar anteturile lipsesc. Am recompilat nucleul și, din obișnuință, am compilat modulul nucleului folosind DKMS. Totuși, viteza de compilare pe arm64 chiar și pentru utilitare mici m-a surprins neplăcut. Apoi a fost necesar un alt modul de nucleu, etc. În general, se pare că tot ce ține de nucleu este mai bine să compilezi pe un laptop x86 confortabil, apoi să transferi pur și simplu pe R64, să te repornești și să testezi.

Altceva este partea utilizatorului. În cazul meu, alegând Debian, totul pentru arhitectura arm64 este deja disponibil pe packages.debian.org și nu trebuie recompilat nimic.

Pentru a nu inventa altă bicicletă, codul HSSP de la Cypress pe Arduino, am folosit Arduino Uno pentru a mă conecta la conectorul ISSP al tastaturii. Armbian pe BPI R64.
Mai exact, partea utilizatorului - Armbian, iar nucleul provine din repository-ul Frank-ului. Cel mai recent imagine poate fi descărcată aici.

Toată activitatea de dezvoltare a părții software a R64 se desfășoară pe forum. În general, producătorul însuși își propune să promoveze routerul sub OpenWrt, dar datorită activității dezvoltatorului Frank din Germania, toate caracteristicile ajung rapid în nucleul pentru Debian. Uimitor, dar Frank este activ în fiecare ramură a forumului.

Organizarea spațiului de lucru: cabluri

Doresc să explic cum, în timpul dezvoltării/testării, să amplasezi SBC (nu doar BPI) pe birou astfel încât să nu fie necesar să tragi un cablu Ethernet de la sursa de internet prin toată camera/biroul. Problema este că, pe de o parte, trebuie să îi asiguri internet dispozitivului, iar pe de altă parte, în acest dispozitiv se pot produce defecțiuni, și în primul rând Wifi.

Inițial am decis să cumpăr un USB-Wifi "dongle" ieftin, să-l conectez în singurul port de pe BPI și să uit de cabluri. Pentru asta am achiziționat un TP-LINK TL-WN725N USB 2.0 ieftin, dar foarte curând a devenit evident că nu va funcționa: pentru a face dongle-ul să funcționeze este nevoie de un driver kernel, care, evident, nu era acolo (mai târziu am compilat driverul necesar RTL8XXXU, dar tot a fost nepractic). Și cablul Ethernet strica aspectul camerei pentru o vreme.

În cele din urmă, am reușit să scape de cablu cu ajutorul Tenda MW3 (sistem Wifi mesh): pur și simplu am amplasat un cub sub birou și l-am conectat pe BPI la portul LAN al acestuia cu un cablu Ethernet de un metru. Succes.

Wireguard, RKN, Bird

Una dintre dorințele mele pentru care folosesc Banana PI este accesul liber la site-urile blocate de RKN, în special pentru a putea folosi Telegram și apeluri în Slack. Pe această temă au fost propuse deja articole pe Хабре: unu, doi, trei.

Implementarea exact a acestei soluții a fost realizată cu ajutorul Ansible: linkul.

Se presupune că VPS-ul funcționează pe Ubuntu 18.04. Am verificat funcționalitatea pe două gazde din Europa: Amazon și Digital Ocean.

Așadar, am instalat Armbian-ul menționat mai sus pe R64, disponibil prin ssh cu numele hm-bananapi-1 și are acces la internet. Implementăm treptat ansible, scripturi de automatizare și începem instalarea pe 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

Apoi trebuie să desfășurăm VPN-ul nostru pe VPS în mod similar:

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

Aici argumentul este întotdeauna current-vpn, iar efectiv numele VPS-ului se configurează în variabilă (în acest caz acesta este 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

Ah da, înainte de toate aceste operațiuni, trebuie să generezi secrete (în special cheile Wireguard) în folderul ./secrets, directorul trebuie să arate . Cu ajutorul acestuia, se pot instala un cluster Kafka pe Kubernetes cu doar câteva comenzi:.

Automatizarea Ansible pe Python

Se poate observa că, în loc de formatul YAML, comenzile Ansible sunt codificate în scripturi Python. Spre comparație, cum să pornești demonul bird în mod normal:

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

și cum să faci același lucru prin Python:

cu mapare:
    append("name", "start bird")
    cu mapare("systemd"):
        append("name",  "bird")
        append("state", "started")
        append("enabled", "yes")

Scrierea comenzilor Ansible în cod Python permite reutilizarea codului și, în general, deschide toate posibilitățile unui limbaj de programare de uz general. De exemplu, instalarea bird pe R64 și VPS:

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

vizualizați codul funcției install_bird().

Această caracteristică numită pybook a fost implementată aici. Documentația pentru pybook nu este disponibilă deocamdată, voi corecta această omitere ulterior.

Ce părere are upstream despre aceasta.

Monitorizare. Prometheus

Concluzie: telegramul funcționează, linkedin și pornhub de asemenea, în general experiența utilizatorului este acceptabilă. Dar totul poate cădea, iar echipamentele chinezești și ele.

Actualizările kernel-ului pot fi, de asemenea, interesante: de exemplu, am vrut să actualizez kernel-ul de la 5.4 => 5.6, deoarece Wireguard este inclus, nu trebuie să fac patch-uri... Așa că am zis și făcut: am mutat cu grijă patch-urile de la 5.4 la 5.6, kernel-ul a pornit, tunelul către VPS este ping-at, dar bird nu poate conecta din cauza erorii "BGP Error"... "În groază am revenit înapoi" (c) la 5.4; migrarea la 5.6 am amânat-o în TODO.

Așadar, pe lângă instalarea router-ului și VPS-ului, am adăugat monitorizarea (pe x86 Ubuntu 18.04), care este instalată pe un host separat cu următoarele componente:

  • prometheus, alertmanager, blackbox_exporter — toate în Docker
  • alertele sunt trimise într-un canal Telegram folosind bot-ul metalmatze/alertmanager-bot — de asemenea în Docker
  • tor pentru bot, astfel încât bot-ul să poată alerta situații când internetul există, dar Telegram totuși nu funcționează și botul însuși nu se poate conecta
  • alerte de aplicație: NodeVPNTroubles (fără ping către VPS), BirdVPNTroubles (fără sesiune Bird), AntifilterDownloadTroubles (eroare la descărcarea IP-urilor blocate), SiteTroubles (Telegramul nedisponibil)
  • alerte sistemice, de exemplu, HostGrowingDiskReadLatency (card SD ieftin care încetează să fie citit)

Exemplu de instalare a monitorizării:

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

Auto Discovery pentru Prometheus este configurat pe folder-ul /etc/prometheus/auto_http, exemplu de adăugare a unui host în monitorizare (prin default host-urile nu sunt monitorizate):

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 furnizori, 2 BPI, failover anycast

Pe lângă toate acestea, am planificat să mă conectez la doi furnizori, astfel încât internetul să continue să funcționeze chiar și în cazul în care unul dintre furnizori întâmpină probleme cu rețeaua sau uită să plătească pentru internet etc., și alți factori umani.

Cea mai avansată experiență a utilizatorului pe tema multi-wan este descrisă aici pentru sistemul Mwan3 pe Openwrt. Această soluție are o funcționalitate bogată, dar configurarea și utilizarea pentru multi-wan sunt destul de complicate. Un exemplu: dacă accesați anumite site-uri simultan din două adrese IP, s-ar putea să nu le placă, iar ele vor înceta să funcționeze => "internetul nu funcționează".

Având în vedere această experiență, am decis că multihoming nu este o prioritate pentru moment, ci doar failover. Deși, se pare că în versiunile recente de linux totul ar trebui să funcționeze cu o singură comandă de tipul:

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

Așadar, pentru a evita un punct unic de defectare, vom folosi 2 BPI, fiecare conectat la un furnizor, le conectăm între ele și facem legătura dintre ele prin rutare dinamică folosind bird/OSPF.

Apoi, pe fiecare vom anunța aceeași adresă IP în cazul în care serviciul este disponibil (internet, DNS). Adică vom stabili ruta implicită nu noi, ci prin intermediul bird. Soluția am văzut-o aici .

Această funcționalitate nu am realizat-o încă, virusul COVID-19 a intervenit și aici (nu toate produsele au ajuns de pe AliExpress; un alt magazin online, Layta, a promis livrarea în o săptămână, dar au trecut deja mai mult de o lună; al doilea furnizor nu a reușit să-și întindă cablul înainte de carantină, a reușit doar să facă o gaură în perete pentru cablu).

Cum să comand R64

Placa în sine este disponibilă în magazinul oficial SinoVoip.
De asemenea, ar fi bine să comandați din start:

  • alimentare + menționați standardul conectorului EU sau SUA
  • răcire: radiatoare/ventilatoare; pentru că și CPU-ul se încălzește, și cipul switch-ului
  • o antenă pentru wifi, de exemplu

Există un detaliu — prețul livrării a devenit nejustificat de mare în magazinul oficial. Managera Judy Huang m-a îndemnat că nu este o eroare și se poate alege ePacket pentru $5, dar am văzut că pentru Rusia este doar EMS pentru >33$. Neplăcut, dar nu critic. De fapt, dacă alegi orice altă țară pentru livrare (am verificat toate continentele), livrarea va fi ~5$. Rusofobii?.. Dar apoi am aflat că pentru Franța prețul livrării este de asemenea ~30$, și m-am liniștit.

În cele din urmă, Judy a propus să facă comanda, dar să nu plătesc (hint: să pun pe card mai puțin, pentru a nu trece automat plata); să-i scriu, și ea va reduce prețul livrării la un nivel normal. Succes.

Probleme

Nu totul funcționează perfect încă.

Performanță

Comenzile Ansible=Python se execută lent, chiar și cele goale, timp de 20-30 de secunde; mult mai mult decât pe laptopul x86. La început, ele se execută suficient de repede, în aproximativ 3 secunde, apoi încetinesc brusc. Poate că acest lucru se întâmplă din cauza supraîncălzirii CPU-ului (throttling). Codul scris în Go funcționează, de asemenea, lent:

# запрос метрик для прометея из 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 funcționează, dar pe Armbian, după aproximativ o zi, încetează să mai funcționeze, apare mesajul:

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

Numai un restart ajută. Trebuie să investighez mai departe să mă documentez.

Ethernet

Ethernet funcționează, dar după aproximativ o zi, pachetele (DHCP) de la R64 încetează să mai vină.
Un restart al interfeței ajută:

ifdown br0; sleep 30; ifup br0

Driverul este nou, nu a fost acceptat încă în kernel, sper că chinezul Landen Chao va finaliza.

Sursa: habr.com

Cumpără un hosting fiabil pentru site-uri cu protecție DDoS, servere VPS VDS 🔥 Cumpără un hosting fiabil pentru site-uri cu protecție DDoS, servere VPS VDS | ProHoster