Banana Pi 64 é um computador de placa única do tipo Raspberry Pi, mas com várias portas Ethernet, permitindo transformá-lo em um roteador baseado em uma distribuição Linux de uso geral.

Sim, já existe OpenWrt, mas ele tem suas peculiaridades, sua própria GUI e CLI; há Mikrotik, mas ele também possui sua própria GUI/CLI, e o Wireguard não funciona fora da caixa… No geral, procura-se um roteador com configurações flexíveis, mantendo-se dentro do padrão do Linux com o qual trabalha todos os dias.
Nos artigos com os títulos BPI, R64 e placa única, vou me referir à mesma coisa — à própria placa única Banana Pi R64.
Escolha da imagem. Inicialização via eMMC.
A primeira habilidade que deve ser adquirida ao trabalhar com no geral, e com o R64 em particular, é aprender a carregar o sistema operacional e ter a possibilidade de interagir com ele, já que o R64 não possui uma porta para monitor (HDMI, por exemplo). Quando tudo falha — Wifi, rede Ethernet, Bluetooth, USB e outros entram em colapso; existe o UART, através do qual sempre se pode verificar o que deu errado, além de executar alguns comandos no console, se necessário.
Algoritmo de conexão ao R64 via USB-UART:
- corremos para a loja de componentes eletrônicos atrás de um cabo USB-UART (PL2303, Serial-to-USB)
- conectamos uma extremidade USB ao computador e a outra, UART, ao R64, usando três fios de quatro, como na imagem abaixo.
- no console do computador, executamos
sudo minicom
Após isso, na maioria dos casos, um console da placa única aparecerá = sucesso.
Detalhes podem ser vistos .

Em seguida, a maneira mais simples de carregar o sistema operacional é a partir de um cartão SD: baixamos pela imagem e a gravamos:
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=noxferinserimos o cartão no slot SD do R64, ligamos e observamos pelo console conectado o carregamento primeiro do uboot, depois do carregamento padrão do Linux.
Uma alternativa de inicialização — usando um cartão eMMC de 8 GB já embutido no R64. Seguindo as instruções da wiki, regravamos a imagem no dispositivo.
/dev/mmcblk0 в BPI, перегружаемся, вытаскиваем SD-карту, включаем BPI снова… и не работает. Как туда-сюда Seleção de inicialização não toque.
O fato é que pelo menos para o BPI é necessário definir uma flag especial para ter a possibilidade de inicializar a partir da memória flash interna:
root@bpi-r64:~# .\/mmc extcsd read \/dev\/mmcblk1 | grep 'PARTITION_CONFIG'\nBytes de configuração de inicialização [PARTITION_CONFIG: 0x00]\nroot@bpi-r64:~# .\/mmc bootpart enable 1 1 \/dev\/mmcblk1\nroot@bpi-r64:~# .\/mmc extcsd read \/dev\/mmcblk1 | grep 'PARTITION_CONFIG'\nBytes de configuração de inicialização [PARTITION_CONFIG: 0x48]Em seguida, é necessário gravar o preloader em uma partição de boot especial.
root@bpi-r64:~# echo 0 > /sys/block/mmcblk0boot0/force_ro
root@bpi-r64:~# dd if=preloader_evb7622_64_foremmc.bin of=/dev/mmcblk0boot0O fabricante R64 (China) lançou este binário . O que ele faz não é conhecido (não há código fonte), mas sem ele também não funcionará.
Em geral, após isso, as imagens começam a carregar também do eMMC. Se alguém quiser entender e criar imagens do zero, para ambos os casos (SD/eMMC) é preciso gravar mais alguns arquivos (preloader para o cartão SD, ATF, u-boot), apenas para chegar ao carregamento do kernel. Este tópico ainda é , mas para nós o principal é que está funcionando e tudo bem.
Atualmente, honestamente, não estou usando o carregamento via eMMC, cartões SD são suficientes, mas gastei bastante tempo para fazê-lo funcionar, então vou mantê-lo no artigo.
Escolha do sistema operacional. Armbian
A primeira tarefa prática é iniciar um VPN, naturalmente usando Wireguard. Notei imediatamente que do lado do kernel ele não está compilado, e não há cabeçalhos. Recompilei o kernel e, por hábito do x86, compilei o módulo do kernel usando DKMS. No entanto, a velocidade de compilação em arm64 mesmo para utilitários pequenos me surpreendeu negativamente. E depois, mais um módulo do kernel foi necessário, e assim por diante. Em geral, conclui-se que tudo relacionado ao kernel é melhor compilar no notebook x86 aquecido, em seguida, transferir para o R64 por simples cópia, reiniciar e testar.
Outra questão é a parte do userspace. No meu caso, escolhendo Debian, tudo para a arquitetura arm64 já está disponível em packages.debian.org e não há necessidade de recompilar nada.
Para não criar mais uma bicicleta, eu para o BPI R64.
Na verdade, assim: a parte userspace é Armbian, e o kernel é obtido do repositório -o. A imagem mais recente pode ser baixada .
Toda a atividade de desenvolvimento da parte de software do R64 está acontecendo em . De fato, o próprio fabricante está tentando popularizar o roteador rodando Openwrt, mas graças à atividade do desenvolvedor Frank da Alemanha, todos os recursos rapidamente aparecem no kernel para Debian. É surpreendente, mas Frank está ativo em todo fórum.
Organização do espaço de trabalho: cabos
Quero falar separadamente sobre como, durante o desenvolvimento/testes, colocar o SBC (não apenas BPI) na mesa de forma que não precise levar um cabo Ethernet de sua fonte de internet pela sala/escritório. O fato é que, de um lado, é necessário garantir internet para o hardware, e, do outro lado, esse mesmo hardware pode falhar, e, em primeiro lugar, o Wifi.
Primeiro, decidi comprar um cheap USB-Wifi "dongle", conectá-lo à única porta da BPI e esquecer os cabos. Para isso, comprei um TP-LINK TL-WN725N USB 2.0 barato, mas logo ficou claro que não funcionaria: para o funcionamento do dongle era necessário um driver de kernel que, naturalmente, não estava lá (depois consegui compilar o driver RTL8XXXU necessário, mas ainda assim não é prático). E o cabo Ethernet estragava a aparência do quarto por um tempo.
No final, consegui me livrar do cabo com a ajuda do Tenda MW3 (sistema Wifi mesh): simplesmente coloquei um cubo embaixo da mesa e conectei a BPI à porta LAN do último com um cabo Ethernet de um metro. Sucesso.
Wireguard, RKN, Bird
Uma das minhas vontades de usar o Banana PI é ter acesso livre a sites bloqueados pelo RKN, em particular, para que o Telegram e as chamadas no Slack funcionem. Já foram propostas artigos sobre esse tema no Habr: , , .
A implementação exatamente dessa solução foi realizada com a ajuda do Ansible: .
Pressupõe-se que o VPS esteja rodando Ubuntu 18.04. Testei a funcionalidade em dois provedores na Europa: Amazon e Digital Ocean.
Então, instalamos o Armbian mencionado acima no R64, que está disponível por ssh sob o nome hm-bananapi-1 e tem acesso à internet. Vamos implantar o ansible, os scripts de automação e iniciar a instalação propriamente dita no 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-1Em seguida, precisamos implantar nosso VPN no VPS da mesma forma:
ansible-playbook ./router.py -l current-vpnAqui, o argumento é sempre current-vpn, e o nome do VPS é configurado na variável (neste caso, é 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 sim, antes de todas essas operações, é necessário gerar os segredos (em particular, as chaves Wireguard) na pasta ./secrets, o diretório deve parecer .
Automação Ansible em Python
É possível notar que em vez do formato YAML, os comandos do Ansible estão codificados em scripts Python. Para comparação, como iniciar o daemon bird normalmente:
- name: start bird
systemd:
name: bird
state: started
enabled: yese como fazer a mesma coisa através do Python:
with mapping:
append("name", "start bird")
with mapping("systemd"):
append("name", "bird")
append("state", "started")
append("enabled", "yes")Gravar comandos do Ansible como código Python permite reutilizar o código e, na verdade, todas as possibilidades de uma linguagem de programação de propósito geral estão abertas. Por exemplo, instalar o bird no R64 e no VPS:
install_bird("router/bird.conf.j2")
install_bird("vpn/bird.conf.j2")ver o código da função .
Esse recurso denominado pybook são implementadas . A documentação do pybook ainda não está disponível, depois corrigirei essa omissão.
O que você acha sobre isso.
Monitoramento. Prometheus
No geral: o Telegram funciona, LinkedIn e pornhub também, a experiência do usuário está boa. Mas tudo pode falhar, e o hardware chinês também.
Atualizações do kernel também podem ser interessantes: por exemplo, eu quis atualizar do kernel 5.4 para 5.6, já que o Wireguard vem de fábrica, não precisa patch... Dito e feito: comparei os patches de 5.4 para 5.6, o kernel subiu, o túnel para o VPS está acessível, mas o bird não consegue se conectar com o erro "BGP Error"... "Em pânico, fiz o downgrade" (c) para 5.4; a migração para 5.6 foi adiada para o TODO.
Portanto, além da instalação do roteador e do VPS, adicionei monitoramento (em x86 Ubuntu 18.04), que é instalado em um host separado com os seguintes componentes:
- prometheus, alertmanager, blackbox_exporter — tudo em Docker
- os alertas são enviados para o canal do Telegram usando o bot metalmatze/alertmanager-bot — também em Docker
- tor para o bot, para permitir que o bot envie alertas em situações em que a internet está disponível, mas o Telegram ainda não funciona e o próprio bot não consegue se conectar
- alertas : NodeVPNTroubles (sem ping para o VPS), BirdVPNTroubles (sem sessão Bird), AntifilterDownloadTroubles (erro ao baixar IPs bloqueados), SiteTroubles (o infeliz Telegram está inacessível)
- alertas do sistema, por exemplo, HostGrowingDiskReadLatency (o cartão SD barato parou de funcionar)
Exemplo de instalação de monitoramento:
ansible-playbook ./monitoring.py -l monitoring-preprodA descoberta automática para o Prometheus está configurada na pasta /etc/prometheus/auto_http, exemplo de como adicionar um host ao monitoramento (por padrão, os hosts não são monitorados):
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 provedores, 2 BPI, failover anycast
Além de tudo isso, planejei me conectar a dois provedores, para que a internet continue funcionando, mesmo que um dos provedores tenha problemas na rede, ou se esqueçam de pagar a conta de internet, etc., e outros fatores humanos.
A experiência do usuário mais avançada sobre multi-wan é descrita para o sistema Mwan3 em Openwrt. Esta solução possui muitos recursos, mas configurar e operar para multi-wan é bastante trabalhoso. Um exemplo: se você acessar alguns sites a partir de dois endereços IP ao mesmo tempo, eles podem não gostar disso e parar de funcionar => "a internet não funciona".
Considerando essa experiência, decidi que o multihoming não é uma prioridade por enquanto, apenas o failover. Embora, parece que nas últimas versões do Linux tudo deve funcionar com um único comando do tipo:
ip route add default
nexthop via 192.168.1.1 weight 10
nexthop via 192.168.2.1 weight 5Então, para evitar um único ponto de falha, usamos 2 BPI, conectamos cada um a um provedor, interligamos entre si e fazemos a conexão dinâmica por meio de bird/OSPF.
Além disso, em cada um, anunciamos o mesmo endereço IP caso o serviço esteja disponível (internet, DNS). Ou seja, vamos definir a rota padrão não manualmente, mas através do bird. Essa solução foi observada .
Essa funcionalidade ainda não foi implementada, o traiçoeiro coronavírus interferiu (nem tudo chegou da AliExpress; outra loja online, a Layta, prometeu entrega em uma semana, mas já passou mais de um mês; o segundo provedor não conseguiu passar o cabo antes da quarentena, conseguiu apenas furar um buraco na parede para o cabo).
Como pedir R64
A própria placa na loja oficial .
Também é melhor pedir logo:
- + informar o padrão do plugue da UE ou dos EUA
- dissipador de calor: radiadores/ventiladores; porque tanto o CPU esquenta quanto o chip do switch
- uma antena para wifi,
Há um detalhe — o preço do frete se tornou desproporcionalmente alto na loja oficial. A gerente Judy Huang me convenceu de que não há erro, e que podemos escolher ePacket por $5, mas eu vi que para a Rússia só está disponível EMS por mais de 33$. Desagradável, mas não crítico. Além disso, se escolher qualquer outro país para entrega (pulei todos os continentes), o frete será por cerca de $5. Russofobia?... Mas então eu descobri que o preço do frete para a França também é cerca de 30$, e fiquei mais tranquilo.
No final, Judy sugeriu fazer o pedido, mas não pagar (dica: colocar menos no cartão para que o pagamento não passe automaticamente); escrever para ela, e ela reduzirá o preço do frete para um nível aceitável. Sucesso.
Problemas
Nem tudo ainda funciona perfeitamente.
Desempenho
Os comandos do Ansible=Python estão lentos, mesmo os vazios, levando de 20 a 30 segundos; muito mais do que no notebook x86. Além disso, eles são executados inicialmente de forma relativamente rápida, em cerca de 3 segundos, e depois desaceleram drasticamente. Isso pode estar ocorrendo devido ao superaquecimento do CPU (throttling). O código em Go também está funcionando devagar:
# запрос метрик для прометея из 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
O Wifi funciona, mas no Armbian, em algum momento após um dia, para de funcionar, apresentando a mensagem:
sa@bananapir64:~$ dmesg | grep -E 'mt7622_wmac.*timeout'
[470303.802539] mt7622_wmac 18000000.wmac: Mensagem 38 (seq 3) timeout
[470314.042508] mt7622_wmac 18000000.wmac: Mensagem 50 (seq 4) timeout
...Apenas reiniciar ajuda. Precisamos investigar mais. .
Ethernet
Ethernet funciona, mas após ~um dia, os pacotes (DHCP) do R64 deixam de chegar.
Reiniciar a interface ajuda:
ifdown br0; sleep 30; ifup br0O driver é novo, ainda não foi aceito no núcleo, espero que o chinês Landen Chao .
Fonte: habr.com
