Router Banana Pi R64 - Debian, Wireguard, RKN

Banana Pi 64 es un ordenador de placa única tipo Raspberry Pi, pero con varios puertos Ethernet, lo que permite convertirlo en un enrutador basado en una distribución de Linux de propósito general.

Router Banana Pi R64 - Debian, Wireguard, RKN

Sí, ya existe Openwrt, pero tiene sus peculiaridades con su propia GUI y CLI; hay Mikrotik, pero nuevamente tiene su propia GUI/CLI, y Wireguard no funciona de forma nativa... En general, quiero un enrutador con configuraciones flexibles, pero permaneciendo dentro del Linux estándar con el que trabajas cada día.

En este artículo, me referiré a BPI, R64, y un ordenador de placa única como lo mismo: en realidad, la propia placa única Banana Pi R64.

Selección de la imagen. Carga por eMMC.

La primera habilidad que debes adquirir al trabajar con SBC en general, y con R64 en particular, es aprender a cargar el sistema operativo y tener la posibilidad de interactuar con él, ya que el R64 no tiene un puerto para monitor (como HDMI, por ejemplo). Cuando algo falla — Wi-Fi deja de funcionar, red Ethernet, Bluetooth, USB y demás aún hay UART, a través del cual siempre puedes ver qué fue mal, así como ejecutar un par de comandos desde la consola, si es necesario.

Algoritmo de conexión al R64 por USB-UART:

  • vamos a la tienda de componentes electrónicos a comprar un cable USB-UART (PL2303, Serial-to-USB)
  • conectamos un extremo USB a la computadora y el otro, UART, al R64, usando tres cables de cuatro, como en la imagen de abajo
  • en la consola de la computadora ejecutamos sudo minicom

Después de esto, en la mayoría de los casos aparecerá la consola del ordenador de placa única = éxito.
Más detalles se pueden ver aquí.

Router Banana Pi R64 - Debian, Wireguard, RKN

Luego, es más fácil cargar el sistema operativo desde una tarjeta SD: descargamos la el enlace imagen y la volcamos:

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

insertamos la tarjeta en la ranura SD del R64, encendemos, y observamos en la consola conectada la carga primero de uboot, luego la carga estándar de Linux.

Una alternativa para arrancar es utilizando el eMMC de 8Gb que ya viene integrado en el R64. Siguiendo las instrucciones en la wiki, copiamos la imagen en el dispositivo.
/dev/mmcblk0 в BPI, перегружаемся, вытаскиваем SD-карту, включаем BPI снова… и не работает. Как туда-сюда Seleccionar arranque no lo toques.

La cuestión es que, al menos para el BPI, es necesario establecer un indicador especial para poder arrancar desde la memoria interna:

root@bpi-r64:~# ./mmc extcsd read /dev/mmcblk1 | grep 'PARTITION_CONFIG'
Bytes de configuración de arranque [PARTITION_CONFIG: 0x00]
root@bpi-r64:~# ./mmc bootpart enable 1 1 /dev/mmcblk1
root@bpi-r64:~# ./mmc extcsd read /dev/mmcblk1 | grep 'PARTITION_CONFIG'
Bytes de configuración de arranque [PARTITION_CONFIG: 0x48]

Luego, en la sección de arranque especial, es necesario grabar el preloader.

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

El fabricante R64 (China) ha publicado este binario aquí. Lo que hace no se sabe (no hay fuentes), pero sin él tampoco funcionará.

En general, después de esto, las imágenes comienzan a cargarse también desde eMMC. Si se desea profundizar y crear imágenes desde cero, entonces para ambos casos (SD/eMMC) es necesario grabar algunos archivos más (preloader para la tarjeta SD, ATF, u-boot), solo para llegar a la carga del núcleo. Este tema aún se desarrolla, pero para nosotros lo principal es que funciona y está bien.

Ahora mismo no utilizo realmente la carga por eMMC, las tarjetas SD son suficientes, pero pasé bastante tiempo haciéndolo funcionar, así que lo dejo en el artículo.

Elección del sistema operativo. Armbian

La primera tarea práctica es iniciar un VPN, naturalmente Wireguard. Inmediatamente se descubrió que no estaba compilado del lado del núcleo y no hay encabezados. Recompilé el núcleo y, por costumbre de x86, compilé el módulo del núcleo usando DKMS. Sin embargo, la velocidad de compilación en arm64 incluso para utilidades pequeñas me sorprendió desagradablemente. Y luego se necesitó otro módulo del núcleo, etc. En general, resulta que todo lo relacionado con el núcleo es mejor compilar en un portátil x86 cálido y acogedor, luego transferirlo a R64 por simple copia, reiniciar y probar.

Por otro lado, la parte de userspace. En mi caso, eligiendo Debian, todo para la arquitectura arm64 ya está en packages.debian.org y no es necesario recompilar nada.

Para no crear otra bicicleta, yo portado Armbian en BPI R64.
Mejor dicho: la parte de userspace es Armbian, mientras que el núcleo se toma del repositorio Frank-a. La imagen más reciente se puede descargar aquí.

Toda la actividad de desarrollo del software para R64 se lleva a cabo en foro. En general, el propio fabricante busca popularizar el enrutador bajo Openwrt, pero gracias a la actividad del desarrollador Frank de Alemania, todas las características rápidamente están en el núcleo para Debian. Sorprendentemente, Frank está activo en cada hilo del foro.

Organización del espacio de trabajo: cables

Quiero explicar cómo, durante el desarrollo/pruebas, colocar un SBC (no solo BPI) en la mesa de manera que no sea necesario llevar un cable Ethernet desde la fuente de internet a través de toda la habitación/oficina. La cuestión es que por un lado hay que proporcionar internet al hardware, y por otro lado, en ese mismo hardware puede estar fallando, y en primer lugar el Wifi.

Al principio decidí adquirir un económico USB-Wifi "dongle", conectarlo en el único puerto del BPI y olvidarme de los cables. Para esto compré un TP-LINK TL-WN725N USB 2.0, pero pronto quedó claro que no funcionaría: el dongle necesita un controlador del núcleo, que allí, por supuesto, no estaba (más tarde compilé el controlador necesario RTL8XXXU, pero aun así, no es práctico). Además, el cable Ethernet arruinaba la apariencia de la habitación durante un tiempo.

Finalmente, logré deshacerme del cable con la ayuda del Tenda MW3 (sistema Wifi mesh): simplemente coloqué un cubo debajo de la mesa y conecté el BPI al puerto LAN del último con un cable Ethernet de un metro. Éxito.

Wireguard, RKN, Bird

Uno de mis deseos al usar Banana PI es tener acceso libre a sitios bloqueados por RKN, en particular, que funcionen Telegram y las llamadas en Slack. Ya se han propuesto artículos sobre este tema en Habr: uno, dos, tres.

La implementación de tal solución la realicé con Ansible: enlace.

Se supone que el VPS funciona bajo Ubuntu 18.04. Verifiqué su funcionamiento en dos hostings en Europa: Amazon y Digital Ocean.

Así que instalamos el Armbian mencionado anteriormente en el R64, el cual está disponible por ssh bajo el nombre hm-bananapi-1 y tiene acceso a Internet. Desplegamos secuencialmente ansible, scripts de automatización y comenzamos la instalación propiamente dicha en el 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

A continuación, necesitamos desplegar de manera similar nuestro VPN en el VPS:

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

Aquí el argumento es siempre current-vpn, y el nombre del VPS se configura en la variable (en este caso, es 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, sí, antes de todas estas operaciones, se deben generar secretos (en particular, claves de Wireguard) en la carpeta .\/secrets, el directorio debe verse así.

Automatización Ansible en Python

Se puede notar que, en lugar de formato YAML, los comandos de Ansible están codificados en scripts de Python. Para comparar, cómo iniciar el demonio bird de la manera habitual:

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

y cómo lo mismo a través de Python:

with mapping:
    append("name", "start bird")
    with mapping("systemd"):
        append("name",  "bird")
        append("state", "started")
        append("enabled", "yes")

Grabar comandos de Ansible como código en Python permite reutilizar el código, y además se abren todas las posibilidades del lenguaje de propósito general. Por ejemplo, instalación de bird en R64 y VPS:

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

ver código de la función install_bird().

Esta característica, llamada pybook se ha implementado aquí. No hay documentación sobre pybook por ahora, corregiré este descuido más tarde.

Qué piensa upstream sobre esto.

Monitoreo. Prometheus

En resumen: Telegram funciona, LinkedIn y Pornhub también, en general, la experiencia de usuario es aceptable. Pero todo puede fallar, y también los equipos chinos.

Las actualizaciones del núcleo también pueden ser interesantes: por ejemplo, quise actualizar del núcleo 5.4 al 5.6, porque Wireguard está incluido, no hay que parchear… Dicho y hecho: transferí cuidadosamente los parches de 5.4 a 5.6, el núcleo se inició, el túnel al VPS responde, pero bird no puede conectarse con el error "BGP Error"… "Con horror retrocedí" (c) a 5.4; postergué la migración a 5.6 en la lista de tareas.

Por lo tanto, además de la instalación del router y del VPS, añadí monitoreo (en x86 Ubuntu 18.04), que se instala en un host separado con los siguientes componentes:

  • prometheus, alertmanager, blackbox_exporter — todo en Docker
  • las alertas se envían a un canal de Telegram con la ayuda del bot metalmatze/alertmanager-bot — también en Docker
  • tor para el bot, para que pueda alertar situaciones en las que hay Internet, pero Telegram sigue sin funcionar, y el propio bot no puede conectarse
  • alertas aplicativas: NodeVPNTroubles (sin ping al VPS), BirdVPNTroubles (sin sesión Bird), AntifilterDownloadTroubles (error de descarga de IP bloqueadas), SiteTroubles (no se puede acceder al problemático Telegram)
  • alertas del sistema, por ejemplo, HostGrowingDiskReadLatency (la tarjeta SD barata deja de leerse)

Ejemplo de instalación del monitoreo:

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

La Auto Discovery para Prometheus está configurada en la carpeta /etc/prometheus/auto_http, ejemplo de agregar un host al monitoreo (por defecto, los hosts no son monitoreados):

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

Tareas pendientes: 2 proveedores, 2 BPI, failover anycast

Además de todo, planeé conectarme a dos proveedores, para que Internet continúe funcionando, incluso si uno tiene problemas de red, o si se olvidaron de pagar por Internet, etc., y otros factores humanos.

La experiencia de usuario más avanzada sobre el tema multi-wan está descrita aquí para el sistema Mwan3 bajo OpenWrt. Esta solución tiene una rica funcionalidad, pero la configuración y explotación para multi-wan son bastante complicadas. Un solo ejemplo: si se accede a ciertos sitios desde dos direcciones IP a la vez, podrían no aceptarlo, dejarán de funcionar => "Internet no funciona".

Teniendo en cuenta esta experiencia, decidí que el multihoming no es una prioridad en este momento, solo el failover. Sin embargo, parece que en las últimas versiones de Linux todo debería funcionar 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 5

Así, para evitar un único punto de fallo, tomamos 2 BPI, cada uno conectado a un proveedor, los conectamos entre sí y hacemos que la conexión entre ellos sea enrutamiento dinámico a través de bird/OSPF.

Luego, en cada uno anunciamos la misma dirección IP en caso de que el servicio esté disponible (Internet, DNS). Es decir, vamos a establecer la ruta por defecto no nosotros mismos, sino a través de bird. Tomé esta solución de otro lugar. aquí .

Esta funcionalidad aún no la he implementado; el traicionero coronavirus ha complicado las cosas (no todo llegó de AliExpress; otra tienda en línea, Layta, prometió entregar en una semana, pero ya ha pasado más de un mes; el segundo proveedor no pudo conectar el cable antes de la cuarentena, solo consiguió hacer un agujero en la pared para el cable).

Cómo pedir R64

La placa en la tienda oficial SinoVoip.
También es mejor pedir de inmediato:

  • la alimentación + indicar el estándar del conector UE o EE. UU.
  • disipadores: radiadores/ventiladores; porque tanto la CPU se calienta como también el chip del switch
  • la antena para wifi, por ejemplo

Hay un matiz: el precio del envío se ha vuelto excesivamente alto en la tienda oficial. La gerente Judy Huang me insistió en que no había error y que se podía elegir ePacket por $5, pero vi que para Rusia solo hay EMS por más de 33$. Desagradable, pero no crítico. Además, si eliges cualquier otro país para el envío (probé todos los continentes), el envío será de aproximadamente $5. ¿Russófobos? Sin embargo, luego encontré que para Francia el precio del envío también es de aproximadamente $30, y me tranquilicé.

Al final, Judy propuso hacer el pedido, pero no pagar (hint: cargar menos en la tarjeta para que el pago automático no se realizara); escribirme, y ella reduciría el precio del envío a uno razonable. Éxito.

Problemas

No todo funciona de manera perfecta todavía.

Rendimiento

Los comandos de Ansible=Python se ejecutan lentamente, incluso los vacíos, tardando de 20 a 30 segundos; mucho más que en la laptop x86. Además, al principio se ejecutan bastante rápido, alrededor de 3 segundos, y luego se ralentizan drásticamente. Es posible que esto suceda debido al sobrecalentamiento del CPU (throttling). El código en Go también se ejecuta 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
51700

Wifi

El Wifi funciona, pero en Armbian deja de funcionar después de aproximadamente un día, muestra:

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

Solo ayuda reiniciar. Hay que seguir investigando.

Ethernet

Ethernet funciona, pero después de aproximadamente ~un día, los paquetes (DHCP) del R64 dejan de llegar.
Reiniciar la interfaz ayuda:

ifdown br0; sleep 30; ifup br0

El driver es nuevo, aún no se ha incluido en el núcleo, espero que el chino Landen Chao lo complete.

Fuente: habr.com

Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS 🔥 Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS | ProHoster