Banana Pi 64 è un computer a scheda singola simile al Raspberry Pi, ma con più porte Ethernet, il che consente di utilizzarlo come router basato su una distribuzione Linux di uso generale.

Sì, esiste già Openwrt, ma ha le sue peculiarità, il proprio GUI e CLI; c'è Mikrotik, ma anche questo ha il suo GUI/CLI, e Wireguard non funziona out of the box... In generale, si desidera un router con impostazioni flessibili, rimanendo nell'ambito di un Linux standard, con cui si lavora quotidianamente.
Nell'articolo con i nomi BPI, R64, computer a scheda singola, intenderò la stessa cosa: il computer a scheda singola Banana Pi R64.
Scelta dell'immagine. Avvio tramite eMMC
La prima abilità da acquisire quando si lavora con in generale, e con R64 in particolare, è imparare a caricarvi un sistema operativo e avere la possibilità di interagire con esso, poiché R64 non ha una porta per monitor (HDMI, ad esempio). Quando tutto si interrompe — il Wifi smette di funzionare, la rete Ethernet, Bluetooth, USB e altro; c'è UART, attraverso l'interfaccia della quale è sempre possibile vedere cosa è andato storto e anche eseguire alcuni comandi dalla console, se necessario.
Procedura per connettersi a R64 via USB-UART:
- andiamo nel negozio di componenti elettronici per un cavo USB-UART (PL2303, Serial-to-USB)
- colleghiamo un'estremità USB al computer e l'altra, UART, a R64, usando tre fili su quattro, come mostrato nell'immagine qui sotto
- nella console del computer avviamo
sudo minicom
Dopo di ciò, nella maggior parte dei casi apparirà la console del computer a scheda singola = successo.
Puoi vedere maggiori dettagli .

In seguito, è più semplice caricare il sistema operativo da una scheda SD: scarichiamo da l'immagine e la scriviamo:
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=noxferinseriamo la scheda nello slot SD di R64, accendiamo, osserviamo tramite la console collegata l'avvio prima di uboot, poi l'avvio standard di Linux.
Un'alternativa per l'avvio è l'uso della eMMC da 8 Gb già incorporata in R64. Seguendo le istruzioni nella wiki, copiamo l'immagine sul dispositivo
/dev/mmcblk0 в BPI, перегружаемся, вытаскиваем SD-карту, включаем BPI снова… и не работает. Как туда-сюда Selezione avvio non toccare.
Il fatto è che, almeno per BPI, è necessario impostare un flag speciale per poter avviare dalla memoria flash interna:
root@bpi-r64:~# .\/mmc extcsd read \/dev\/mmcblk1 | grep 'PARTITION_CONFIG'\nByte di configurazione di avvio [PARTITION_CONFIG: 0x00]\nroot@bpi-r64:~# .\/mmc bootpart enable 1 1 \/dev\/mmcblk1\nroot@bpi-r64:~# .\/mmc extcsd read \/dev\/mmcblk1 | grep 'PARTITION_CONFIG'\nByte di configurazione di avvio [PARTITION_CONFIG: 0x48]Successivamente, è necessario scrivere il preloader in una partizione boot speciale
root@bpi-r64:~# echo 0 > /sys/block/mmcblk0boot0/force_ro
root@bpi-r64:~# dd if=preloader_evb7622_64_foremmc.bin of=/dev/mmcblk0boot0Il produttore R64 (Cina) ha rilasciato questo binario . Non si sa cosa faccia (non ci sono sorgenti), ma senza di esso non funzionerebbe.
In sostanza, dopo questo, le immagini iniziano a caricarsi anche da eMMC. Se si desidera approfondire e creare immagini da zero, per entrambi i casi (SD/eMMC) è necessario registrare ulteriori file (preloader per la scheda SD, ATF, u-boot), solo per arrivare al caricamento del kernel. Questo argomento è ancora , ma per noi è importante che funzioni, e va bene.
Attualmente non utilizzo il boot da eMMC, a dire il vero, le schede SD sono sufficienti, ma ho speso tanto tempo affinché funzionasse, quindi dovrebbe rimanere nell'articolo.
Scelta del sistema operativo. Armbian
Il primo compito pratico è avviare una VPN, naturalmente Wireguard. Subito si è scoperto che non era compilato a livello di kernel e che non c'erano intestazioni. Ho ricompilato il kernel e, per abitudine da x86, ho compilato il modulo del kernel usando DKMS. Tuttavia, la velocità di compilazione su arm64 persino di piccole utilità mi ha sorpreso spiacevolmente. E poi è richiesto un altro modulo del kernel, e così via. Insomma, tutto ciò che riguarda il kernel è meglio compilarlo su un vecchio laptop x86, poi trasferirlo su R64 tramite semplice copiatura, riavviarsi e testarlo.
Un'altra questione è la parte userspace. Nel mio caso scegliendo Debian, tutto per l'architettura arm64 è già presente su packages.debian.org e non è necessario ricompilare nulla.
Per non creare un'altra bicicletta, io su BPI R64.
In realtà, la parte userspace è Armbian, mentre il kernel proviene dal repository -a. L'immagine più aggiornata può essere scaricata .
Tutta l'attività di sviluppo della parte software di R64 è condotta su . In effetti, il produttore stesso cerca di promuovere il router con Openwrt, ma grazie all'attività dello sviluppatore Frank dalla Germania, tutte le funzionalità riescono rapidamente a entrare nel kernel per Debian. È sorprendente, ma Frank è attivo in ogni sezione del forum.
Organizzazione dello spazio di lavoro: cavi
Voglio raccontare separatamente come durante lo sviluppo/testing posizionare SBC (non solo BPI) sulla scrivania in modo da non dover portare il cavo Ethernet da una fonte Internet attraverso tutta la stanza/ufficio. Il fatto è che da un lato è necesario fornire internet alla macchina, mentre dall'altro lato questa stessa macchina potrebbe avere malfunzionamenti, e prima di tutto il Wifi.
Inizialmente ho deciso di acquistare una cheap USB-Wifi "stick", collegarlo all'unica porta disponibile sul BPI e dimenticare i cavi. Per questo ho comprato un economico TP-LINK TL-WN725N USB 2.0, ma ben presto è diventato chiaro che non avrebbe funzionato: per far funzionare la chiavetta era necessario un driver del kernel, che naturalmente non era disponibile (più tardi ho assemblato il driver RTL8XXXU necessario, ma rimaneva comunque poco pratico). E il cavo Ethernet rovinava l'aspetto della stanza per un certo periodo.
Alla fine sono riuscito a liberarmi del cavo grazie al Tenda MW3 (sistema Wifi mesh): ho semplicemente posizionato un cubo sotto il tavolo e ho collegato il BPI alla porta LAN di quest'ultimo con un cavo Ethernet di un metro. Successo.
Wireguard, RKN, Bird
Una delle mie necessità per cui utilizzo il Banana PI è avere accesso ai siti bloccati dall'RKN, in particolare perché Telegram e le chiamate su Slack funzionino. A proposito di questo, sono già stati proposti articoli su Habr: , , .
Ho implementato esattamente questa soluzione utilizzando Ansible: .
Si presume che VPS funzioni con Ubuntu 18.04. Ho verificato il funzionamento su due host in Europa: Amazon e Digital Ocean.
Quindi, abbiamo installato l'Armbian menzionato sopra su R64, disponibile via ssh con il nome hm-bananapi-1 e ha accesso a internet. Procediamo a distribuire gradualmente ansible, gli script di automazione e avviamo l'installazione su 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-1Dopo, dobbiamo distribuire in modo analogo sul VPS il nostro VPN:
ansible-playbook ./router.py -l current-vpnQui l'argomento è sempre current-vpn, mentre il nome effettivo del VPS è configurato nella variabile (in questo caso si tratta di 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-1Ah già, prima di tutte queste operazioni è necessario generare i segreti (in particolare le chiavi Wireguard) nella cartella ./secrets, la directory dovrebbe apparire .
Automazione Ansible in Python
Si può notare che invece del formato YAML i comandi Ansible sono codificati in script Python. Per confronto, come avviare il demone bird nel modo tradizionale:
- name: start bird
systemd:
name: bird
state: started
enabled: yese come fare la stessa cosa attraverso Python:
with mapping:
append("name", "start bird")
with mapping("systemd"):
append("name", "bird")
append("state", "started")
append("enabled", "yes")Scrivere comandi Ansible in codice Python consente di riutilizzare il codice e apre a tutte le possibilità del linguaggio di programmazione generale. Ad esempio, l'installazione di bird su R64 e VPS:
install_bird("router/bird.conf.j2")
install_bird("vpn/bird.conf.j2")vedere il codice della funzione .
Questa funzionalità chiamata pybook è stata implementata Non c'è ancora documentazione su pybook, poi sistemerò questa mancanza.
Cosa ne pensa al riguardo.
Monitoraggio. Prometheus
In sintesi: Telegram funziona, LinkedIn e Pornhub anche, in generale l'esperienza utente è ok. Ma tutto può rompersi, e anche l'hardware cinese.
Gli aggiornamenti del kernel possono essere interessanti: ad esempio, ho voluto aggiornare il kernel da 5.4 a 5.6, beh, lì c'è Wireguard pronto all'uso, non c'è bisogno di patchare... Detto fatto: ho trasferito meticolosamente le patch da 5.4 a 5.6, il kernel si è avviato, il tunnel verso il VPS risponde al ping, ma bird non riesce a collegarsi con l'errore "BGP Error"... "Inorridito, sono tornato indietro" (c) a 5.4; ho rimandato il passaggio a 5.6 in TODO.
Quindi, oltre all'installazione del router e del VPS, ho aggiunto il monitoraggio (su x86 Ubuntu 18.04), che viene installato su un host separato con i seguenti componenti:
- prometheus, alertmanager, blackbox_exporter — tutto in docker
- Gli avvisi vengono inviati a un canale Telegram tramite un bot metalmatze/alertmanager-bot — anche questo in docker
- tor per il bot, in modo che il bot possa avvisare situazioni in cui Internet è disponibile, ma Telegram non funziona ancora, e il bot stesso non riesce a connettersi
- avvisi applicativi : NodeVPNTroubles (nessun ping verso il VPS), BirdVPNTroubles (nessuna sessione Bird), AntifilterDownloadTroubles (errore nel download di IP bloccati), SiteTroubles (Telegram sfortunato non è accessibile)
- avvisi di sistema, ad esempio, HostGrowingDiskReadLatency (una scheda SD economica smette di essere leggibile)
Esempio di installazione del monitoraggio:
ansible-playbook ./monitoring.py -l monitoring-preprodAuto Discovery per Prometheus è configurato sulla cartella /etc/prometheus/auto_http, esempio di aggiunta di un host al monitoraggio (di default gli host non sono monitorati):
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
EOFTODO: 2 fornitori, 2 BPI, failover anycast
In aggiunta a tutto, ho pianificato di collegarmi a due fornitori, in modo che Internet continui a funzionare, anche se uno dei fornitori ha problemi di rete, o se dimenticano di pagare per Internet e altro ancora, e anche il fattore umano.
L'esperienza utente più avanzata sul tema multi-wan è descritta per il sistema Mwan3 sotto Openwrt. Questa soluzione ha una ricca funzionalità, ma la configurazione e l'uso per il multi-wan sono piuttosto complicati. Solo un esempio: se si accede a determinati siti da due indirizzi IP contemporaneamente, potrebbero non gradirlo, smetteranno di funzionare => "Internet non funziona".
Considerando questa esperienza, ho deciso che il multihoming non è ancora una priorità, solo il failover. Tuttavia, sembra che nelle ultime versioni di Linux tutto dovrebbe funzionare con un solo comando del tipo:
ip route add default
nexthop via 192.168.1.1 weight 10
nexthop via 192.168.2.1 weight 5Quindi, per non avere un singolo punto di errore, prendiamo 2 BPI, collegando ciascuno a un provider, connettendoli tra loro e rendendo la comunicazione tra di loro basata su routing dinamico tramite bird/OSPF.
Successivamente, su ciascuno annunciamo lo stesso indirizzo IP nel caso in cui il servizio sia disponibile (internet, DNS). Cioè, impostiamo la rotta predefinita non noi stessi, ma tramite bird. Ho trovato questa soluzione. .
Questa funzionalità non l'ho ancora implementata, il subdolo coronavirus ha giocato un brutto tiro (non tutto è arrivato da AliExpress; un altro negozio online, Layta, prometteva la consegna in una settimana, ma è passato più di un mese; il secondo provider non ha fatto in tempo a tirare il cavo prima della quarantena, ha solo forato il muro per il cavo).
Come ordinare R64
La scheda stessa nel negozio ufficiale .
È meglio ordinarlo subito:
- + comunicare lo standard della presa UE o USA
- dissipatore: radiatori/ventilatori; perché sia la CPU che il chip dello switch si surriscaldano
- un'antenna per il wifi,
C'è un problema: il costo della spedizione è diventato irragionevolmente alto nel negozio ufficiale. La Manager Judy Huang mi ha rassicurato che non c'erano errori e che potevo scegliere l'ePacket per $5, ma ho visto che per la Russia c'era solo EMS per >33$. Scomodo, ma non critico. Inoltre, se scelgo qualsiasi altro paese per la spedizione (ho esaminato tutti i continenti), la spedizione è circa $5. Russofobi? Ma poi ho trovato che anche per la Francia il costo della spedizione era di circa $30, e mi sono rasserenato.
Alla fine, Judy ha proposto di effettuare l'ordine, ma di non pagare (hint: mettere meno sulla carta in modo che il pagamento non avvenisse automaticamente); scrivermi e mi avrebbe abbassato il costo della spedizione a un prezzo normale. Successo.
Problemi
Non tutto funziona ancora perfettamente.
Prestazioni
I comandi Ansible=Python vengono eseguiti lentamente, anche quelli vuoti, tra 20-30 secondi; molto più a lungo rispetto al laptop x86. Inoltre, inizialmente vengono eseguiti piuttosto velocemente, ~3 secondi, quindi rallentano bruscamente. Potrebbe accadere a causa del surriscaldamento della CPU (throttling). Anche il codice scritto in Go funziona lentamente:
# запрос метрик для прометея из 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
51700Wifi
Il Wifi funziona, ma su Armbian smette di funzionare dopo circa un giorno, scrivendo:
sa@bananapir64:~$ dmesg | grep -E 'mt7622_wmac.*timeout'
[470303.802539] mt7622_wmac 18000000.wmac: Messaggio 38 (seq 3) timeout
[470314.042508] mt7622_wmac 18000000.wmac: Messaggio 50 (seq 4) timeout
...Solo il riavvio aiuta. Bisogna continuare .
Ethernet
L'Ethernet funziona, ma dopo circa un giorno i pacchetti (DHCP) da R64 smettono di arrivare.
Aiuta il riavvio dell'interfaccia:
ifdown br0; sleep 30; ifup br0Il driver è nuovo, non è ancora stato integrato nel kernel, spero che il cinese Landen Chao .
Fonte: habr.com
