Маршрутизатор Banana Pi R64 - Debian, Wireguard, РКН
Banana Pi 64 - це одноплатний комп'ютер на кшталт Raspberry Pi, але з кількома портами Ethernet, що дозволяє зробити з нього маршрутизатор на базі дистрибутива Linuх загального призначення.
Так, вже є Openwrt, але має свої проблеми свій GUI і CLI; є Mikrotik, але у нього знову ж таки свій GUI/CLI, та й Wireguard із коробки не працює… Загалом хочеться маршрутизатор із гнучкими налаштуваннями, при цьому залишившись у рамках стандартного лінуксу, з яким працюєш щодня.
У статті під назвами 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
Після цього найчастіше з'явиться консоль одноплатника = успіх.
Детальніше можна переглянути тут.
Далі, найпростіше завантажити операційну систему з SD-карти: завантажуємо по за посиланням образ і заливаємо його:
вставляємо карту в SD-слот R64, включаємо, спостерігаємо по підключеній консолі завантаження спочатку uboot, потім стандартне завантаження лінуксу.
Альтернативний варіант завантаження - за допомогою вже вшитої в R64 карти розміром 8Gb, званої eMMC. За інструкцією у вікі переписуємо образ на пристрій
/dev/mmcblk0 в BPI, перевантажуємось, витягуємо SD-карту, включаємо BPI знову… і не працює. Як туди-сюди Boot select ні смикай.
Справа в тому, що як мінімум для BPI необхідно поставити спеціальний прапор, щоб мати можливість завантажуватися з внутрішньої флешки:
Виробник R64 (Китай) виклав цей бінар тут. Що він робить невідомо (вихідників немає), але без нього теж не запрацює.
Загалом після цього образи починають вантажитися і з eMMC. Якщо ж захотіти розібратися і створювати образи з нуля, то обох випадків (SD/eMMC) необхідно записувати ще кілька файлів (preloader для SD-карти, ATF, u-boot), щоб дістатися завантаження ядра. Тема ця досі розвивається, Але для нас головне, що працює і добре.
Зараз я завантаження по eMMC, чесно кажучи, не використовую, SD карти достатньо, але я досить багато часу витратив на те, щоб воно запрацювало, тому нехай буде у статті.
Вибір операційної системи. Armbian
Перше прикладне завдання - запустити VPN, звичайно Wireguard. Відразу виявилося, що з боку ядра він не зібраний, і заголовків немає. Перезбирав ядро і, за звичкою x86, зібрав модуль ядра за допомогою DKMS. Однак швидкість складання на arm64 навіть невеликих утиліт мене неприємно здивувала. А далі ще один модуль ядра був потрібний, і т.д. Загалом, виходить, що все, пов'язане з ядром, краще збирати на тепло-ламповому ноутбуці x86, потім простим копіюванням переносити на R64, перевантажуватися і тестувати.
Інша справа - юзейспейсная частина. У моєму випадку вибору Debian все для архітектури arm64 вже є на packages.debian.org і нічого перезбирати не доводиться.
Щоб не плодити черговий велосипед, я портувавАрмбійський на BPI R64.
Вірніше так: userspace-на частина - Armbian, а ядро береться з репозиторію Френк-а. Найсвіжіший образ можна завантажити тут.
Уся активність з розробки софтової частини 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
Далі потрібно аналогічним чином задеплоїти на VPS наш VPN:
ansible-playbook ./router.py -l current-vpn
Тут аргумент завжди current-vpn, а власне ім'я VPS налаштовується у змінній (в даному випадку це paris-vpn-aws-t2-micro-1):
with mapping:
append("name", "start bird")
with mapping("systemd"):
append("name", "bird")
append("state", "started")
append("enabled", "yes")
Запис команд Ansible кодом на Python дозволяє повторно використовувати код та й взагалі відкриті всі можливості мови загального призначення. Наприклад, установка bird на R64 та VPS:
Разом: телеграмчик працює, linkedin і pornhub теж, загалом user experience - ок. Але все може ламатися, і китайські залозки також.
Оновлення ядра теж бувають цікавими: наприклад, я захотів оновити ядро 5.4 => 5.6, нуачо, там же Wireguard з коробки, не треба патчити ... Сказано-зроблено: ретельно переносив патчі з 5.4 на 5.6, ядро завелося, тунель до тунель до тунель до не може з'єднатися з помилкою "BGP Error"… "Жах відкотився назад" (с) на 5.4; переїзд на 5.6 відклав у TODO.
Тому на додаток до інсталяції роутера та VPS додав моніторинг (на x86 Ubuntu 18.04), який ставиться на окремий хост з такими компонентами:
prometheus, alertmanager, blackbox_exporter - все в докері
алерти направляються в телеграм-канал за допомогою бота metalmatze/alertmanager-bot теж у докері
tor для бота, щоб бот міг алертити ситуації, коли інтернет є, але телеграм все одно не працює, і сам бот не може з'єднатися
Auto Discovery для прометея налаштовано на папку /etc/prometheus/auto_http, приклад додавання хоста до моніторингу (за замовчуванням хости не моніторяться):
На додаток до всього, запланував підключитися до двох провайдерів, щоб інтернет продовжив працювати, навіть якщо в одного провайдера проблеми з мережею, або забули заплатити за інтернет і т.д., та інший людський фактор.
Найбільш просунутий user experience на тему 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 гріється, і чіп switch-а
Є нюанс — ціна доставки з якогось часу стала неадекватно високою в офіційному магазині. Менеджер 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
Wi-Fi
Wifi працює, але на Armbian десь за добу перестає, пише: