O roteador Banana Pi R64 — Debian, Wireguard, RKN

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.

O roteador Banana Pi R64 — Debian, Wireguard, RKN

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 SBC 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 aqui.

O roteador Banana Pi R64 — Debian, Wireguard, RKN

Em seguida, a maneira mais simples de carregar o sistema operacional é a partir de um cartão SD: baixamos pela link 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=noxfer

inserimos 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/mmcblk0boot0

O fabricante R64 (China) lançou este binário aqui. 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 é está em desenvolvimento, 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 importeio Armbian para o BPI R64.
Na verdade, assim: a parte userspace é Armbian, e o kernel é obtido do repositório Frank-o. A imagem mais recente pode ser baixada aqui.

Toda a atividade de desenvolvimento da parte de software do R64 está acontecendo em fórum. 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: um, dois, três.

A implementação exatamente dessa solução foi realizada com a ajuda do Ansible: link.

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-1

Em seguida, precisamos implantar nosso VPN no VPS da mesma forma:

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

Aqui, 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-1

Ah 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 assim.

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: yes

e 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 install_bird().

Esse recurso denominado pybook são implementadas aqui. A documentação do pybook ainda não está disponível, depois corrigirei essa omissão.

O que você acha upstream 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 aplicativos: 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-preprod

A 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
EOF

TODO: 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 aqui 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 5

Entã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 aqui .

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 SinoVoip.
Também é melhor pedir logo:

  • alimentação + 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, por exemplo

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
51700

Wifi

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. continuar a verificar.

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 br0

O driver é novo, ainda não foi aceito no núcleo, espero que o chinês Landen Chao finalize.

Fonte: habr.com

Compre hospedagem confiável para sites com proteção contra DDoS, servidores VPS VDS 🔥 Compre hospedagem confiável para sites com proteção contra DDoS, servidores VPS VDS | ProHoster