DNS-блокировщик рекламы за $2, который втыкается в USB роутера
Мне нравится DIY, особенно когда самоделка решает задачу, для которой обычно берут отдельный сервер. Кайфую от решений, где дешёвая плата и немного кода делают работу сетевого сервиса. На днях попалось короткое видео: автор сделал DNS-блокировщик рекламы на ESP32-C3 за $2. Обычно такой софт ставят на Raspberry Pi или мини-ПК, а здесь плата размером с USB-флешку.
Плата в корпусе с переходником USB-A. Кадр из видео автора.
У платы 4 МБ флеша и 400 КБ оперативной памяти. PSRAM это внешняя оперативная память, которую распаивают на некоторых платах. Здесь её нет, поэтому список доменов приходится держать во флеше. В 4 МБ помещается до 537 тыс. доменов.
ESP32-C3 Super Mini: 400 КБ RAM, PSRAM нет. Кадр из видео автора.
Хранятся они не строками, а 40-битными хешами. Каждый адрес превращается в пятибайтный хеш, и дальше по отсортированному списку идёт бинарный поиск.
Почему список помещается в 4 МБ флеша
Я открыл tools/build_blocklist.py, чтобы посмотреть, сколько байт уходит на домен. На 141 тыс. доменов выходит 0,67 МБ. Если бы те же домены лежали строками, им понадобилось бы около 2,5 МБ оперативной памяти, а у платы её 400 КБ. Поэтому в RAM живёт только текущий запрос.
Хеш занимает 5 байт. Можно было взять 32 или 64 бита, но 32 дают слишком много коллизий, а 64 тратят на домен лишние три байта. Коллизия это когда два разных домена дают одинаковый отпечаток, и тогда один из них блокируется по ошибке. На 40 битах её почти нет: на 141 тыс. доменов ноль, на 537 тыс. одна. Меня такой размен устраивает.
Что плата умеет и где упирается
Прошивка и список делят те же 4 МБ. Обновление по воздуху требует двух слотов, после чего под список остаётся около 1,3 МБ, то есть примерно 250 тыс. доменов. Максимальный список помещается только без обновления прошивки.
Ещё есть веб-панель со статистикой по клиентам, блокировка отдельного устройства, свои blacklist и whitelist, настройка Wi-Fi через портал и адрес c3adblock.local в локальной сети.
Панель на списке по умолчанию: 141 203 домена, 57,8 °C, 158 КБ свободной RAM. Кадр из видео автора.
Работает это как обычный DNS-резолвер, и часть привычных вещей Pi-hole здесь отсутствует. DHCP-сервером плата пока не стала, поэтому DNS прописывается на роутере вручную или плата ставится вторым резолвером. Панель работает по обычному HTTP с Basic Auth. Такая защита не пускает в панель без пароля, но трафик не шифрует. Рекламу, которая приходит с того же домена, что и контент, плата не тронет. Ролики на YouTube едут с googlevideo.com вместе с самим видео, так что вставки там останутся.
Стоит ли менять Pi-hole на плату за $2
Хеши во флеше работают не только на ESP32-C3. На ESP32-S3 с 16 МБ флеша они держат около 2,7 млн доменов, а строки в 8 МБ PSRAM дают около 466 тыс. На большой плате выигрыш просто менее заметен.
Если нужен такой блокировщик на роутере и есть свободный USB, плата за $2 и вечер на прошивку выглядят разумно. На телевизоре, телефонах и приставках реклама режется без установки приложений. Если нужен полноценный DNS с шифрованием, DHCP и тонкими правилами, это задача для Pi-hole или AdGuard Home на отдельном железе. Дешёвые переходники USB-C на USB-A просаживают напряжение при передаче по Wi-Fi, и плата от них перезагружается.