Рутерът 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

Най-първият умение, което трябва да се усвои при работа с SBC по принцип и с 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'
Boot configuration bytes [PARTITION_CONFIG: 0x00]
root@bpi-r64:~# ./mmc bootpart enable 1 1 /dev/mmcblk1
root@bpi-r64:~# ./mmc extcsd read /dev/mmcblk1 | grep 'PARTITION_CONFIG'
Boot 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 се води на форумa. Всъщност, самият производител се стреми да популяризира маршрутизатора под 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

Следва да внедрим на VPS нашия VPN по аналогичен начин:

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

Общо: телеграмът работи, linkedin и pornhub също, общото потребителско изживяване – ок. Но всичко може да се счупи, а китайските устройства също.

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

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

  • prometheus, alertmanager, blackbox_exporter – всичките в docker
  • алармите се изпращат в телеграм канал с помощта на бота metalmatze/alertmanager-bot – също в docker
  • tor за бота, за да може ботът да алармира в ситуации, когато интернет има, но телеграм все пак не работи, и самият бот не може да се свърже
  • приложни аларми: NodeVPNTroubles (няма ping до VPS), BirdVPNTroubles (няма сесия Bird), AntifilterDownloadTroubles (грешка при изтегляне на блокирани IP адреси), SiteTroubles (недостъпен проклет телеграм)
  • системни аларми, например, 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 адреса, те може да не харесат това и ще спрат да работят => "интернетът не работи".

С оглядыванием на этот опыт, я решил, что multihoming пока не является приоритетом, только failover. Хотя, кажется, в последних версиях 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 предложила сделать заказ, но не оплачивать (подсказка: положить на карту меньше, чтобы автоматом оплата не прошла); написать ей, и она снизит цену доставки до нормальной. Успех.

Проблемы

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

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

Команды Ansible=Python выполняются медленно, даже холостые, по 20-30 секунд; на порядок дольше, чем на ноуте x86. Причем сначала они выполняются достаточно быстро, около 3 секунд, а затем резко замедляются. Возможно, это происходит из-за перегрева CPU (throttling). Код на 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 работи, но след около ~24 часа пакетите (DHCP) от R64 спират да пристигат.
Помага рестартирането на интерфейса:

ifdown br0; sleep 30; ifup br0

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

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

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