Не хватает RAM для пакетов на роутере? Поставьте их на мини-сервер из старого смартфона

В предыдущей статье о (без)умном доме домашней сети я рассказал об использовании локального агента для её настройки и поднятия разных интересных сервисов.
Однако почти сразу я столкнулся с тем, что встроенной оперативки моего роутера (256 МБ) перестало хватать. Запустил AdGuard Home, telemt‑форк под OpenWRT, далее попробовал поднять v2ray со списками разрешенных серверов — и тут же OOM безжалостно начал убивать процессы.
Кажется, что можно было купить новый роутер, с большим количеством оперативки — но роутеры с 1Гб или более RAM сейчас стоят недешево. И тут меня посетила идея: «А что если взять старый смартфон в качестве сервера?».
Главное, что есть у смартфона: намного более мощный (по сравнению с роутерами) ARM‑процессор с несколькими гигабайтами оперативки. Плюс: встроенный ИБП (батарея), экран (можно использовать для отображения нагрузки или сапёра KMines), и в наличии WiFi модуль для подключения к домашней сети.
В этом гайде я расскажу, как пройти путь от выбора и покупки б/у телефона на торговой площадке до рабочего мини-сервера под управлением PostmarketOS с Podman и запущенным на нём AdGuard Home. А также как я облажался в процессе этого пути, прилично ограничив возможности моего сервера.
Поехали...
Шаг 1. Выбор телефона-«донора» и ОС
Изначальная идея: берём не очень старый мобильный телефон с 4Гб+ RAM, прошиваем на него Linux, подключаем к нему USB-хаб (значит, у телефона должен работать USB-OTG), а к хабу — недорогую гигабитную USB-сетевую карту. Profit: полноценный проводной сетевой узел, почти как взрослый роутер.
Но реальность, как обычно, внесла свои коррективы:
USB 3.0 — роскошь. Лишь у достаточно дорогих телефонов разъём поддерживает USB 3.0 (или выше). У большей части аппаратов обычный USB 2.0, то есть теоретический потолок скорости обмена данными — 480 Мбит/с, а на практике он ещё меньше. Гигабитная сетевая карта, подключенная к такому порту, просто не сможет работать с максимальной скоростью.
Дистрибутивов для телефонов немного. Linux-систем под мобильные устройства (с готовыми образами) оказалось не так уж много. Беглый поиск дал мне лишь два варианта: PostmarketOS и Ubuntu Touch.
Телефон должно быть не жалко. Для экспериментов я решил потратить пару тысяч на недорогой аппарат, чтобы было не жалко его «окирпичить», если что-то пойдёт не так.
В итоге я посмотрел список поддерживаемых устройств PostmarketOS и Ubuntu Touch, сверил его с предложениями на Авито — и приобрёл б/у Redmi Note 9 Pro 8/128 для прошивки под PostmarketOS. Телефон продавался с немного повреждённым экраном. Но серверу, который будет жить на полке, экран в целом не очень нужен (а из-за повреждения телефон продавался дешевле чем «непокоцанный»).

В итоге, если всё получится, рассуждал я, у меня появится мощное устройство аж с 6 гигабайтами RAM, на которых можно кучу всего запустить!
И тут внимательный читатель спросит: почему я пишу про 6Гб RAM если обозначил модель как Redmi Note 9 Pro 8/128?
Дело в том, что физически у этой модели действительно всего 6Гб RAM. А ещё 2Гб — это swap на основе флеш‑памяти телефона. По этой же логике более слабая модель Redmi Note 9 Pro 6/64 имеет на борту лишь 4Гб RAM.
Если будете выбирать другой недорогой телефон для превращения в сервер — учитывайте подобные особенности.
Подключать же телефон к домашней сети я решил через специально выделенную для него WiFi-точку доступа.
Сноска про домашнюю сеть. У меня дома несколько роутеров. Основной — Xiaomi AX3000T, на нём активированы сети 2.4 ГГц и 5 ГГц. И два дополнительных роутера (Xiaomi Mi Mini), подключенные по проводу к основному. К ним подключаются только IoT-устройства, поэтому на них WiFi активирован только в диапазоне 2.4 ГГц (хотя физически роутеры могут и 5 ГГц).
В итоге я решил расположить телефон на расстоянии нескольких нескольких дециметров от одного из дополнительных роутеров, а затем включить на этом роутере сеть 5 ГГц с минимальной силой сигнала (с помощью WiFi Analyzer я выбрал свободный, никем не зашумлённый, канал).
И в целом это сработало! Соединение по Wi-Fi получилось стабильным. Правда, позднее всплыл неучтенный мною момент — об этом я честно расскажу в конце.
Итак, приступаем к перепрошивке.
Шаг 2. Разблокировка загрузчика Xiaomi или «приходите через недельку»
Xiaomi славится своей заботой о пользователях. В частности, чтобы поставить на их устройство что-то отличное от родной прошивки, нужно разблокировать загрузчик. И тут нас ждёт первый квест на выносливость.
Для начала на самом телефоне (пока ещё с родной системой):
Вставляем SIM-карту. Без неё Xiaomi не даст привязать аккаунт.
Идём в Настройки -> О телефоне и для для разблокировки режима разработчика тыкаем 10 раз по пункту «Версия MIUI».
Идём в Настройки -> Расширенные настройки -> Для разработчиков.
Включаем тумблер Заводская разблокировка (OEM Unlocking).
Там же находим «Статус Mi Unlock», нажимаем «Привязать аккаунт».
Важно: на этапе привязки нужно выключить Wi-Fi и использовать мобильный интернет. Иначе выдастся ошибка.
Теперь скачиваем утилиту Mi Unlock Tool. И тут отмечу два момента:
Первый: утилита Mi Unlock есть только под Windows. Я работаю из-под винды, так что эта часть пути проблем не вызвала. Но если у вас Linux — вы предупреждены.
Второй: сейчас с официального сайта Xiaomi скачивается версия 6.5.224.28, в которой у меня не работало ни автообновление, ни авторизация в Xiaomi-аккаунте (программа просто упорно отказывалась логиниться). Хорошо, что интернет подсказал, где искать рабочую версию. На свой страх и риск я скачал её на форуме 4pda. Так что если официальная сборка капризничает так же — вы знаете, куда можно обратиться.
А теперь главное: между привязкой аккаунта и самой разблокировкой Xiaomi заставляет ждать ровно 7 дней (168 часов). И обойти это нельзя: по текущим правилам разлочить с одного аккаунта Xiaomi можно не более 1 телефона в неделю и не более 4 телефонов в год. Так что привязываем аккаунт, — и идём пить чай, чтоб вернуться попробовать снова через недельку.
Неделя прошла? Отлично: логинимся в утилиту под своим Mi-аккаунтом, переводим телефон в режим Fastboot (удерживаем питание + громкость вниз при включении), подключаем к ПК и жмём заветную кнопку «Unlock».
После успешной разблокировки телефон сбросится до заводских настроек и сотрёт все данные.
Шаг 3. Пункт для тех, у кого нет Linux — используйте для прошивки флешку с Ubuntu LiveCD
Итак, загрузчик разблокирован, и телефон готов к экспериментам. Изучив сайт PostmarketOS, я пришёл к неутешительному выводу: для установки требуется Linux. «Ну у меня же Windows с Hyper-V, сейчас подниму виртуалку», — наивно полагал я. И тоге попытка была позорно провалена: даже после всех манипуляций по пробросу USB через расширенную сессию и установки драйверов Xiaomi Adb на хостовую ОС, ОС в виртуалке упорно не видела подключённый телефон.
Поэтому знакомый посоветовал мне следующее:
Взять чистую флешку на 16 ГБ и больше.
Скачать Ubuntu LTS Desktop с официального сайта.
Записать образ на флешку через Rufus. Я записывал со схемой разделов GPT, чтобы не отключать SecureBoot в UEFI ноутбука.
Загрузиться с флешки, выбрать «Try Ubuntu without installing».
Делать все дальнейшие манипуляции в этом окружении.

Теперь следующий шаг — собрать прошивку под телефон.
Шаг 4. Магия pmbootstrap: собираем новую прошивку
Перед тем как погружаться в терминал, вот ссылка на официальную инструкцию именно для нашего семейства устройств (miatoll). Настоятельно рекомендую держать её при прошивке открытой в соседней вкладке — там есть специфические нюансы, о которых мы поговорим ниже.
Итак, телефон разлочен, подключен по USB, а компьютер снова загружен с нашей Ubuntu-флешки. Пришло время собирать нашу систему. Для этого сообщество PostmarketOS написало мощнейший комбайн — pmbootstrap.
Устанавливаем минимальные зависимости:
sudo apt update
sudo apt install python3-pip git android-tools-fastbootТеперь ставим сам pmbootstrap из исходников, почти полностью следуя официальной инструкции (лишь репозиторий клонируем неглубоко):
git clone https://gitlab.postmarketos.org/postmarketOS/pmbootstrap.git --depth 1
cd pmbootstrap
mkdir -p ~/.local/bin
ln -s "$PWD/pmbootstrap.py" ~/.local/bin/pmbootstrap
pmbootstrap --versionКомментарий из личного опыта: у меня алиас
pmbootstrapтак и не заработал. Поэтому все дальнейшие команды я запускал, напрямую вызывая python-скрипт:./pmbootstrap.py --version.
Теперь — инициализация:
./pmbootstrap.py initВ целом дальнейшие шаги очень зависят от вашей модели телефона. Я приведу свои — но исключительно в качестве примера. В частности, параметры vendor и device при инициализации, а также действия с образом U-Boot взяты из инструкции именно к моему телефону (Redmi Note 9 Pro). Для вашего устройства эти действия могут быть другими!
Ответы Init:
Work path, и pmaports path: оставил без изменений
Channel:
v26.06(последний стабильный релиз на момент написания статьи)Vendor:
xiaomiDevice codename:
miatollUsername:
user(в pmOS по умолчанию создаётся пользователь с правами sudo)Provider-ы для Audio, WiFi и USB: оставил без изменений
User interface: Изначально я выбрал
console, руководствуясь логикой «серверу графика не нужна». Но позже доустановилxfce4. Несмотря на то что консоль потребляла бы меньше ресурсов, в GUI можно гораздо красивее выводить полезную информацию (дашборды, статусы). Плюс в GUI проще всего настроить выключение дисплея — чтобы он не выгорал при постоянной работеAdditional options: нашёл в интернете, что для моей модели надо уменьшит boot_size до 370Мб. Для этого, помимо указания данной настройки, пришлось руками заменить условие в файле
<папка куда скачали pmbootstrap>/pmb/install/_install.pyв методеsanity_check_boot_sizeвместоint(default)вписать350. Не самое элегантное решение, но без этого прошивка не проходила сборкуAdditional packages: ничего не вводил, дополнительные пакеты на этом этапе не ставил
Остальные параметры до конца мастера: также значения по умолчанию
Когда опрос закончен, запускаем сборку системы:
./pmbootstrap.py installЭто займёт время (от пары минут до получаса в зависимости от скорости интернета). Утилита скачает необходимые пакеты, скомпилирует ядро и соберёт образы разделов. Пока прошивка собирается, можно снова подумать о чае.
Когда сборка завершится, выключаем телефон, переводим его в режим Fastboot (питание + громкость вниз), подключаем к компьютеру и начинаем прошивку:
./pmbootstrap.py flasher flash_kernel && ./pmbootstrap.py flasher flash_rootfsДалее стираем раздел dtbo:
fastboot erase dtboИ теперь нам понадобится загрузчик. Скачиваем последний образ U-Boot из репозитория (файл u-boot-sm7125.img) и прошиваем его:
fastboot flash boot u-boot-sm7125.imgПосле чего даём команду на перезагрузку телефона:
fastboot rebootВсё! Экран (у вас он, надеюсь, цел) покажет красивый логотип загрузки PostmarketOS.

Поскольку выше я выбрал графическую оболочку xfce4, вы видите экранную клавиатуру, которой бы не было в режиме console (там, на черном экране, появилось бы несколько приглашений ко вводу логина). Для меня — это ещё один failsafe‑механизм на случай, если в процессе где‑то напортачу.

Шаг 5. Подключение по ssh
Теперь наша задача — получить доступ к консоли телефона.
Здесь в игру вступает USB Networking. Если на Шаге 4 вы не меняли настройки сети и не выключали автовключение USB Network, телефон автоматически сконфигурирует виртуальную сеть через кабель:
IP-адрес телефона:
172.16.42.1IP-адрес вашего ПК:
172.16.42.2
Пробуем подключиться по ssh (я для ssh использую консоль Git Bash):
ssh <имя пользователя>@172.16.42.1Система запросит пароль (вы его задали на прошлом шаге, при сборке дистрибутива). Вводим, — и мы внутри!

Теперь наша главная задача — подключить телефон к домашнему Wi-Fi, чтобы он стал полноценным узлом локальной сети и перестал зависеть от провода. Для этого используем утилиту nmcli (NetworkManager Command Line Interface) в консоли соединения с телефоном.
Сначала посмотрим, какие WiFi-сети доступны:
nmcli radio wifi on
nmcli device wifi listА теперь подключимся к нужной (замените YOUR_WIFI_SSID и, когда вас спросят, введите пароль подключения к WiFi:
nmcli --ask device wifi connect "YOUR_WIFI_SSID"Если команда отработала без ошибок, смотрим, какой IP-адрес выдал роутер:
ifconfigВ выдаче ищем блок, соответствующий WiFi адаптеру (у меня это wlan0), адрес будет в нём inet addr.
Теперь осталось завершить текущее соединение, и подключиться к телефону мини-серверу уже используя адрес в локальной сети командой ssh <имя пользователя>@<ip адрес, полученный из ifconfig>.
Для справки: если подключение не произошло, или вам потребуется что-то скачать из интернета до подключения к WiFi, вот официальная справка по тому, как настроить интернет через USB Networking.
Шаг 6. Серверные будни: настраиваем podman
PostmarketOS базируется на дистрибутиве Alpine Linux. Это значит, что привычного apt или yum здесь нет, а пакеты ставятся через легковесный apk.
Для запуска контейнеров я выбрал Podman, не Docker. Почему? Podman не требует постоянно висящего в фоне демона с root-правами (daemonless), что для мини-сервера на ARM-архитектуре критически важно с точки зрения экономии RAM.
Устанавливаем Podman (и iptables — понадобится для запуска контейнера AdGuard Home):
sudo apk update
sudo apk add podman iptablesПроверяем, что установка прошла корректно:
podman --version
podman infoЕсли вторая команда вывела «простыню» системной информации — ваш сервер почти готов запустить первый контейнер.
Остался один важный момент. Фаервол в PostmarketOS работает через nftables, и по умолчанию он блокирует трафик из контейнеров, потому что не знает про интерфейс podman0. Чтобы контейнеры могли ходить в интернет (и в локальную сеть), требуется добавить разрешающее правило. Для этого:
1. выполните команду создания правила в bash:
sudo tee /etc/nftables.d/60_podman.nft << 'EOF'
#!/usr/sbin/nft -f
table inet filter {
chain forward {
iifname "podman*" accept comment "Allow forwarding from podman containers"
}
}
EOF2. Проверьте, что созданное правило корректно (если команда не выведет ничего — файл с правилом корректен):
sudo nft -c -f /etc/nftables.d/60_podman.nft3. Поскольку правило, созданное ранее, применится лишь после перезагрузки, применим его же в текущую рабочую конфигурацию:
sudo nft add rule inet filter forward iifname "podman*" acceptИ вот теперь можно и контейнер запустить.
Шаг 7. Запускаем AdGuard Home
Финишная прямая — запуск полезной нагрузки. Для примера поднимем локальный DNS‑сервер, который будет вырезать рекламу и трекеры на уровне домашней сети. AdGuard Home вполне подходит под эту задачу: он написан на Go, потребляет немного и имеет веб-интерфейс для настройки.
Критический момент: чтобы поднять DNS-сервер на устройстве, нам понадобится занять порт 53. По умолчанию на нём работает dnsmasq. Но как только мы его отключим, до момента запуска настроенного AdGuard потеряем возможность выполнять DNS-запросы. То есть по сути скачивать из интернета по доменным именам. Поэтому будет действовать аккуратно: сначала скачаем необходимое, затем остановим dnsmasq, и в конец запустим adguard.
Скачивание образа AdGuard Home можно выполнить командой:
sudo podman pull adguard/adguardhomeТеперь освобождение порта. Проверим, кто занимает порт 53:
sudo netstat -tlnp | grep :53В выводе вы увидите что-то вроде:
tcp 0 0 127.0.0.1:53 0.0.0.0:* LISTEN 1199/dnsmasqЗначит порт занят сервисом dnsmasq (по крайней мере на чистой системе PostmarketOS у меня так). Чтобы его отключить, открываем конфиг NetworkManager:
sudo nano /etc/NetworkManager/NetworkManager.confДобавляем строку dns=none в секцию [main]. Итоговый конфиг будет выглядеть примерно так:
[main]
dhcp=internal
dns=noneСохраняем файл и перезапускаем NetworkManager:
sudo systemctl restart NetworkManagerЗатем повторно проверям командой sudo netstat -tlnp | grep :53 отсутствие процессов, использующих порт 53.
Если далее до момента запуска настроенного AdGuard вам потребуется интернет — закомментируйте строку
dns=noneв файле настроек NetworkManager, затем перезапустите NetworkManager.
Теперь создадим директории, чтобы настройки и базы данных AdGuard не стирались:
mkdir -p ~/adguardhome/work ~/adguardhome/confИ наконец — запустим контейнер:
sudo podman run -d \
--name adguardhome \
--restart=always \
-v ~/adguardhome/work:/opt/adguardhome/work \
-v ~/adguardhome/conf:/opt/adguardhome/conf \
-p 53:53/tcp -p 53:53/udp \
-p 80:80/tcp \
-p 3000:3000/tcp \
adguard/adguardhomeПодробнее про параметры команды запуска:
-d— запускаем в фоновом режиме (detached).--restart=always— если телефон перезагрузится или контейнер упадёт, Podman сам его поднимет.-v— пробрасываем локальные папки внутрь контейнера (персистентность данных).-p— пробрасываем порты:53(TCP и UDP) — это стандартный порт DNS;3000(TCP) — порт для первоначальной настройки веб-интерфейса;80(TCP) — порт для обращения к админке после настройки;

Проверяем, что контейнер поднялся:
sudo podman psЕсли видите запись adguardhome в списке со статусом Up — всё работает.
Следом открываем браузер на основном ПК и переходим по адресу http://<ip-сервера-из-ifconfig>:3000. Вас встретит мастер первоначальной настройки. Следуйте его шагам, придумайте логин и пароль, и на последнем этапе убедитесь, что интерфейс слушает все доступные IP-адреса. Помните, что после завершения настройки админка переподнимется на 80 порту.
А теперь, когда DNS-сервер заработал, надо вернуть телефону возможность DNS-запросов (ведь ранее мы выключили dnsmasq). Указываем чтобы DNS-запросы уходили к нам же:
echo "nameserver 127.0.0.1" | sudo tee /etc/resolv.confИ проверяем что dns-резолв работает:
nslookup ya.ruЕсли настройка выполнено верно, команда вернёт ip-адрес сервера ya.ru (он, скорее всего, начинается на 77.88). И при этом в начале вывода будет строка Server: 127.0.0.1 (то есть обращение шло через поднятый нами DNS-сервер).
Шаг 8. Настройка использования другими устройствами поднятого DNS‑сервера
Пункт 1. Раздача через DHCP (для обычных устройств)
Большинство домашних гаджетов получают настройки сети автоматически. Нам нужно лишь сказать роутеру: «теперь главным по именам в сети будет вот этот вот сервер».
У меня роутер на OpenWRT, поэтому привожу инструкцию для его веб-интерфейса LuCI:
Переходим в Network (Сеть) -> Interfaces (Интерфейсы).
Напротив вашего LAN нажимаем Edit.
Листаем вниз до раздела DHCP Server и открываем вкладку Advanced Settings.
Ищем поле DHCP-Options.
Вписываем туда следующую строку:
6,192.168.0.119(замените192.168.0.119на реальный IP-адрес вашего DNS-сервера. Цифра6означает «опция 6 — список DNS-серверов»).Нажимаем Save & Apply.
Теперь любое устройство, которое переподключится к сети по кабелю или по Wi-Fi, получит адрес Redmi в качестве основного DNS.
Пункт 2. Принудительный перехват (чтобы никто не смог обойти блокировку)
Умные телевизоры или некоторые планшеты могут игнорировать настройки роутера и ломиться напрямую в 8.8.8.8. К счастью, на Хабре уже была статья по настройке AdGuard от уважаемого хабравчанина @ShyDamn — и в ней было предложено заворачивать все исходящие обращения от устройств на 53 порт.
Чтобы выполнить эту инструкцию, понадобится подключиться к роутеру по ssh и сконфигурировать фаервол через uci (с решётки начинаются комментарии с описанием, что делает очередная команда):
# Внимание! Это пример команд для конфигурации роутера, а не для устройства с PostmarketOS!
# Создаём новое правило редиректа в конфиге фаервола
uci add firewall redirect
# Даём правилу читаемое имя
uci set firewall.@redirect[-1].name='Redirect DNS to AdGuard'
# Источник трафика — локальная сеть
uci set firewall.@redirect[-1].src='lan'
# Перехватываем и TCP, и UDP
uci set firewall.@redirect[-1].proto='tcp udp'
# Ловим все обращения, идущие на 53 порт (DNS)
uci set firewall.@redirect[-1].src_dport='53'
# ...и перенаправляем их на 53 порт нашего сервера
uci set firewall.@redirect[-1].dest_port='53'
# Это IP нашего телефона с AdGuard Home (замените на свой!)
uci set firewall.@redirect[-1].dest_ip='192.168.0.119'
# DNAT — подмена адреса назначения, то есть перенаправление пакета
uci set firewall.@redirect[-1].target='DNAT'
# Сохраняем конфигурацию и перезапускаем фаерволл
uci commit firewall && service firewall restartТеперь, даже если устройство попытается отправить DNS-запрос на любой внешний адрес по порту 53, роутер поймает этот пакет и перенаправит его на наш DNS-сервер.
Шаг 9. Где же я облажался
Под конец — честное признание, потому что без него гайд был бы неполным.
Телефон я успешно подключил к дополнительному роутеру — Xiaomi Mi Mini, прошитому на OpenWRT. Я уже потирал руки, представляя, как всё будет летать. Однако несмотря на то, что модуль Wi-Fi по спецификации поддерживает скорость до 867 Мбит/с при использовании диапазона 5 ГГц, все Ethernet-порты роутера работают лишь на 100 Мбит/с. Плюс оригинальная заводская прошивка, вероятно, была лучше оптимизирована под железо роутера, чем OpenWRT.
В общем, итогом стало то, что скорость подключения по Wi-Fi (даже после некоторого шаманства с каналами и шифрованием) составила скромные 40 Мбит/с (или 60 Мбит/с — если полностью отключить шифрование, но это, согласитесь, не вариант).
Так что, увы, запустить РКН или что-то требовательное к сети на этом устройстве у меня не получится. Но для поднятого AdGuard Home этого достаточно: DNS-запросы — это крошечные пакеты, и даже 40 Мбит/с хватит на сотни RPS.
Если вам (для вашего сетапа) потребуется из консоли проверить скорость передачи информации до вашего устройства, это можно сделать двумя способами:
если измеряется скорость доступа в интернет с конкретного устройства, то пробуйте сделать это командой
curl -o /dev/nullhttp://speedtest.selectel.ru/100MB(она в отдельном столбце выведет вам скорость скачивания);если же надо измерить скорость обмена данными между двумя устройствами по локальной сети, то воспользуйтесь утилитой
iperf3. Скачайте и установите её на оба устройства (на телефоне —sudo apk add iperf3, на Ubuntu —sudo apt install iperf3, а под windows можно просто скачать собранный бинарь этой утилиты).Далее на одном из устройств запустите сервер, на другом — клиент:
# На первом устройстве запускаем сервер
iperf3 -s
# На втором устройстве запускаем клиент, указав адрес сервера
iperf3 -c 192.168.0.25В итоге получите примерно такой отчёт (скриншот с устройства, где iperf3 был запущен как сервер):

Что в итоге
Я получил полноценный, автономный мини‑сервер, путь и с ограничением по пропускной способности. Теперь роутер занимается только роутингом — и не тратит драгоценную оперативную память на всякие КВНы.
Надеюсь, мой опыт поможет вам найти разумное применение вашему старому смартфону. Если у вас возникли вопросы или у вас есть идеи, как оптимизировать работу подобного сетапа — добро пожаловать в комментарии!
Если эта публикация вас вдохновила и вы хотите поддержать автора — не стесняйтесь нажать на кнопку
KioskNews shows a cleaned-up reading view extracted from the publisher’s page — the original always lives on their site, not ours.