Рутерът Banana Pi R64 — Debian, Wireguard, РКН

Banana Pi 64 е едноплатен компютър, подобен на Raspberry Pi, но с няколко Ethernet порта, което позволява да се създаде рутер на база дистрибуция на Linux с общо предназначение.

Рутерът Banana Pi R64 — Debian, Wireguard, РКН

Да, вече има Openwrt, но той има свои особености и собствен GUI и CLI; има Mikrotik, но той отново има свой GUI/CLI, а и Wireguard не работи от кутията... В общи линии, искам рутер с гъвкави настройки, запазвайки стандартния Linux, с който работя всеки ден.

В статията под названията BPI, R64, едноплатният компютър, ще имам предвид едно и също — самият едноплатен компютър Banana Pi R64.

Избор на образ. Загрузка по eMMC

Първото умение, което трябва да придобиеш при работа с ← стандартизиран в A2DP, поддържа се от всички устройства вообще, и с R64 в частност, е да се научиш да зареждаш операционната система в него и да имаш възможност да взаимодействаш с него, тъй като R64 няма порт за монитор (например HDMI). Когато всичко спре — спре WiFi, Ethernet мрежата, Bluetooth, USB и всичко останало, остава UART, през интерфейса на който винаги можеш да видиш какво не е наред, както и да стартираш няколко команди от конзолата, при необходимост.

Алгоритъм за свързване с R64 по USB-UART:

  • отиваме в магазина за радиоелектроника за кабел USB-UART (PL2303, Serial-to-USB)
  • свързваме единия USB край към компютъра, а другия, UART, към R64, с три проводника от четирите, както е показано на изображението по-долу
  • в конзолата на компютъра стартираме sudo minicom

След това в повечето случаи ще се появи конзолата на едноплатника = успех.
По-подробно може да се види тук..

Рутерът Banana Pi R64 — Debian, Wireguard, РКН

Нататък, най-лесно е да се зареди операционната система от SD карта: сваляме по връзката образ и го записваме:

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

вмъкваме картата в SD слота на R64, включваме, наблюдаваме през свързаната конзола зареждането първо на uboot, след това стандартното зареждане на Linux.

Алтернативен вариант за зареждане — чрез вградената в R64 карта с размер 8Gb, наречена eMMC. Според инструкциите в Wiki записваме образа на устройството
/dev/mmcblk0 в BPI, перегружаемся, вытаскиваем SD-карту, включаем BPI снова… и не работает. Как туда-сюда Boot select не пипай.

Факт е, че поне за BPI е необходимо да се постави специален флаг, за да имаш възможност да зареждаш от вътрешната флаш памет:

root@bpi-r64:~# .\/mmc extcsd read \/dev\/mmcblk1 | grep 'PARTITION_CONFIG'\nBoot configuration bytes [PARTITION_CONFIG: 0x00]\nroot@bpi-r64:~# .\/mmc bootpart enable 1 1 \/dev\/mmcblk1\nroot@bpi-r64:~# .\/mmc extcsd read \/dev\/mmcblk1 | grep 'PARTITION_CONFIG'\nBoot configuration bytes [PARTITION_CONFIG: 0x48]

След това, в специалния boot раздел трябва да запишеш preloader

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

Производителят R64 (Китай) публикува този бинарен файл тук.. Какво прави, не е известно (не са налични изходни кодове), но без него също не работи.

Всъщност, след това образите започват да се зареждат и от eMMC. В случай, че искате да разгледате и да създавате образи от нула, за двата случая (SD/eMMC) трябва да запишете още няколко файла (preloader за SD картата, ATF, u-boot), само за да стигнете до зареждането на ядрото. Темата все още развива, но за нас е важно, че работи и това е.

В момента не използвам зареждане по eMMC, честно казано, SD картите са достатъчни, но прекарах доста време, за да го накарам да работи, затова нека бъде в статията.

Избор на операционна система. Armbian

Първата практическа задача е да стартирам VPN, естествено Wireguard. Веднага се установи, че от страната на ядрото не е компилиран и заглавките липсват. Прекомпилирах ядрото и, по навик от x86, компилирах модул на ядрото с помощта на DKMS. Обаче скоростта на компилация на arm64 дори на малки утилити ме неприятно изненада. А след това се нуждаеше от още един модул на ядрото и т.н. В общи линии, всичко, свързано с ядрото, е най-добре да се компилира на топлия-лампов ноутбук x86, след което просто да се прехвърли на R64, да се рестартира и да се тества.

Съвсем друго е - частта на потребителското пространство. В моя случай с избора на Debian, всичко за архитектура arm64 вече е налично на packages.debian.org и не е необходимо да се прекомпилира.

За да не създавам поредния велосипед, аз е портировал Armbian на BPI R64.
По-точно: частта на потребителското пространство - Armbian, а ядрото се взима от хранилището Frank-а. Най-новият образ може да бъде изтеглен тук..

Цялата активност по разработка на софтуерната част на R64 се извършва на форума. Всъщност, самият производител се стреми да популяризира рутера под Openwrt, но благодарение на активността на разработчика Frank от Германия, всички функции бързо се появяват в ядрото за Debian. Учудващо, но Frank е активен във всяка нишка на форума.

Организация на работното пространство: кабели

Отделно искам да разкажа как по време на разработка/тестване да разположите SBC (не само BPI) на масата, така че да не трябва да водите Ethernet кабел до него от източника на интернет през цялата стая/офис. Факт е, че от една страна е необходимо да се осигури интернет на устройството, а от друга страна, в самото устройство всичко може да се провали, като в първо време Wifi.

Първоначално реших да закупя евтин USB-Wifi "дън" и да го включа в единствения порт на BPI, за да забравя за кабелите. Затова купих недорогия TP-LINK TL-WN725N USB 2.0, но много скоро стана ясно, че няма да се получи: за работа на дъна е необходим драйвер на ядрото, който, естествено, липсваше (по-късно събрах необходимия драйвер RTL8XXXU, но все пак това е неприложимо). И Ethernet-кабелът развалял вида на стаята известно време.

В крайна сметка успях да се отърва от кабела с помощта на Tenda MW3 (Wifi mesh-система): просто поставих един куб под масата и с метър Ethernet-кабел свързах BPI към LAN порта на последния. Успех.

Wireguard, РКН, Bird

Една от желаните функции, за която използвам Banana PI, е да имам свободен достъп до сайтове, блокирани от РКН, по-специално, за да работи Telegram и разговори в Slack. Вече бяха предложени статии на тази тема в Хабър: раз, два, три.

Реализирах внедряването на точно такова решение с помощта на Ansible: линк.

Предполага се, че VPS работи под Ubuntu 18.04. Проверих работоспособността на два хостинга в Европа: Amazon и Digital Ocean.

И така, инсталирахме посочения Armbian на R64, той е достъпен по ssh под името hm-bananapi-1 и има достъп до интернет. Последователно разгръщаме ansible, скриптове за автоматизация и стартираме инсталацията на 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

Следващата стъпка е аналогично да внедрим нашия VPN на VPS:

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

Тук аргументът винаги е current-vpn, а самото име на VPS се настройва в променливата (в случая това е 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

Ах да, преди всички тези операции е необходимо да генерирате секрети (по-специално ключове за Wireguard) в папката .\/secrets, директорията трябва да изглежда така.

Автоматизация с Ansible на Python

Може да се забележи, че вместо формата YAML, командите на Ansible са кодирани в Python скриптове. За сравнение, как обикновено се активира демонът bird:

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

и как същото да стане чрез Python:

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

Записването на командите на Ansible с Python код позволява повторно използване на кода, и изобщо, предлагат се всички възможности на общ език. Например, инсталирането на bird на R64 и VPS:

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

да се види кода на функцията install_bird().

Тази функция със заглавие pybook реализирана тук.Документацията за pybook все още не е налична, после ще коригирам този пропуск.

Какво мисли upstream по този въпрос.

Мониторинг. Prometheus

В обобщение: Telegram работи, LinkedIn и Pornhub също, общо взето потребителското изживяване е ок. Но всичко може да се счупи, и китайските устройства също.

А обновленията на ядрото също понякога са интересни: например исках да обновя ядрото от 5.4 на 5.6, нали там има Wireguard от кутията, не трябва да патчвам... Казано-несказано: усърдно прехвърлях патчове от 5.4 на 5.6, ядрото тръгна, тунелът до VPS пингва, но Bird не може да се свърже с грешката "BGP Error"... "С ужас се върнах назад" (с) на 5.4; преместването на 5.6 отложих в TO-DO.

Затова в допълнение към инсталацията на рутера и VPS добавих мониторинг (на x86 Ubuntu 18.04), който се инсталира на отделен хост със следните компоненти:

  • prometheus, alertmanager, blackbox_exporter — всичко в Docker
  • алармите се изпращат в Telegram канал с помощта на бота metalmatze/alertmanager-bot — също в Docker
  • tor за бота, за да може ботът да предупреждава за ситуации, когато интернет има, но Telegram не работи, и самият бот не може да се свърже
  • приложни аларми: NodeVPNTroubles (няма ping до VPS), BirdVPNTroubles (няма сесия Bird), AntifilterDownloadTroubles (грешка при изтегляне на блокирани IP адреси), SiteTroubles (невъзможен достъп до нещастния Telegram)
  • системни аларми, например, HostGrowingDiskReadLatency (евтина SD карта спира да се чете)

Пример за инсталация на мониторинг:

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

Auto Discovery за Prometheus е настроено на папка /etc/prometheus/auto_http, пример за добавяне на хост в мониторинга (по подразбиране хостовете не се мониторят):

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 доставчика, 2 BPI, anycast failover

В допълнение към всичко планирах да се свържа с двама доставчици, така че интернетът да продължи да работи, дори ако един от доставчиците има проблеми с мрежата, или ако са забравили да платят за интернет и т.н., и друг човешки фактор.

Най-напредналото потребителско изживяване на тема multi-wan е описано тук. за системата Mwan3 под OpenWrt. Това решение предлага богати функции, но настройката и експлоатацията на multi-wan изискват значителни усилия. Само един пример: ако се опитате да достъпите някои сайтове едновременно от два IP адреса, те може да не се радват на това и да спрат да работят => "интернетът не работи".

С оглядкой на этот опыт я решил, что мультихоминг пока не является приоритетом, только резервирование. Хотя, кажется, в последних версиях Linux всё должно работать одной командой вида:

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

Итак, чтобы избежать единой точки отказа, берём 2 BPI, каждый подключаем к одному провайдеру, связываем их между собой и устанавливаем динамическую маршрутизацию через bird/OSPF.

Далее, на каждом мы анонсируем одинаковый IP-адрес в случае, если сервис доступен (интернет, DNS). То есть маршрут по умолчанию мы будем устанавливать не сами, а посредством bird. Это решение я подсмотрел. тук. .

Эту функциональность пока не реализовал, коварный коронавирус вмешался (не всё пришло с Алиэкспресс; ещё один интернет-магазин, Layta, обещал доставить за неделю, а прошло уже больше месяца; второй провайдер не успел проложить кабель до карантина, успел только просверлить дырку в стене для кабеля).

Как заказать R64

Сама плата в официальном магазине SinoVoip.
Также лучше сразу заказать:

  • блок питания + сообщить стандарт штекера ЕС или США
  • теплоотвод: радиаторы/вентиляторы; потому что греется и CPU, и чип свитча
  • антенну для WiFi, например

Есть нюанс – со временем цена доставки стала неадекватно высокой в официальном магазине. Менеджер Judy Huang убеждала меня, что ошибки нет, и можно выбрать ePacket за $5, но я видел, что для России доступен только EMS за >33$. Неприятно, но не критично. Причём если выбрать любую другую страну для доставки (я перебрал все континенты), доставка составит ~5$. Русофобы?.. Но затем я нашёл, что для Франции цена доставки тоже ~30$, и успокоился.

В итоге Judy предложила сделать заказ, но не оплачивать (hint: положить на карту меньшую сумму, чтобы автоматом оплата не прошла); написать ей, и она снизит цену доставки до нормальной. Успех.

Проблемы

Не всё пока работает идеально.

Производителност

Команды Ansible=Python выполняются медленно, даже холостые, по 20-30 секунд; на порядок дольше, чем на ноутбуке x86. При этом сначала они выполняются достаточно быстро, ~3 секунды, а затем резко замедляются. Возможно, это происходит из-за перегрева CPU (троттлинг). Код на Go тоже работает долго:

# запрос метрик для прометея из 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 работает, но на Armbian где-то через сутки перестаёт, пишет:

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

Помага само рестартиране. Трябва да продължим да разследваме.

Ethernet

Ethernet работи, но след ~день пакети (DHCP) от R64 спират да идват.
Помага рестартиране на интерфейса:

ifdown br0; sleep 30; ifup br0

Шофьорът е нов, все още не е приет в ядрото, надявам се китайецът Ланден Чао да го завърши.

Източник: habr.com

Купете надежден хостинг за сайтове със защита от DDoS, VPS и VDS сървъри 🔥 Купете надежден хостинг за сайтове със защита от DDoS, VPS и VDS сървъри | ProHoster