# Ручне встановлення Pi-hole DNS на прикладі Fedora / Linux На сайті DOU є досить інформативний гайд з описом проєкту Pi-hole та причин користуватись ним сьогодні, на відміну від популярних uBlock і AdGuard: => https://dou.ua/forums/topic/54745/ Блокуємо рекламу за допомогою Pi Hole. Детальний гайд * особисто я (через аналізатор Etherape) помічав за uBlock запити на статичне сховище Google, ймовірно за актуалізацією блок-списків, що мене також не влаштовує як мінімум. Якщо коротко, то Pi-hole - дозволяє підняти локальний (або локально-мережний) проксі-сервер DNS з Веб-адмінкою, через яку можна наочно керувати правилами блокування та переглядати статистику запитів. При цьому, необхідність у високо-рівневих блокувальниках реклами відпадає, адже паразитний трафік не покидатиме "53 порт" локальної мережі ще на етапі резольву. Взагалі, в мене були думки скористатись більш легкими рішеннями DNS, але Pi-hole заманив своєю візуалізацією і орієнтацією конкретно на потрібні мені задачі. У цьому матеріалі я не буду розглядати конкретний тюнінг блокування, але надам приклад ручного встановлення П/З, адже у всіх гайдах, які мені зустрілись нашвидкоруч - використовуються приклади інсталяції з Docker або автоматизованим скриптом: ``` bash curl -sSL https://install.pi-hole.net | bash ``` Мене це не влаштовує, оскільки сам скрипт доволі великий (через свою універсальність) а також просить root, що тим паче потребує додаткового аналізу виконаних дій на моїй системі. Адже наприклад на Fedora я не користуюсь більше firewalld, а в офіційній документації - зустрічаються ось такі дозвільні приклади, коли як для мене відкриття 80 порту на всі інтерфейси не є прийнятним: => https://docs.pi-hole.net/main/prerequisites/#ufw Отже, пробігшись по репозиторіям проєкту на GitHub, назбирав для себе такий мінімальний набір: * FTL (Faster Than Light, `pi-hole/FTL`) - Це ядро комплексу Pi-hole, написане мовою C. Являє собою кастомізований DNS-сервер на базі dnsmasq і відповідає за блокування запитів та збір статистики * Web UI (`pi-hole/web`) - Веб-панель для керування, що взаємодіє з бекендом FTL по API ## FTL (Faster Than Light) Спочатку, знадобляться як мінімум такі залежності: ``` bash sudo dnf install gmp-static xxd mbedtls-devel ``` Забираємо початковий код і переходимо в його корінь: ``` bash git clone https://github.com/pi-hole/FTL.git cd FTL ``` ## Компіляція На цьому етапі, можна заглянути в `./build.sh`, але суть там наступна: ``` bash mkdir build cd build cmake -DCMAKE_C_FLAGS="-fPIC" .. cmake --build . ``` * для Fedora 43, я додав відсутній в скрипті аргумент `-DCMAKE_C_FLAGS="-fPIC"` ### Оновлення залежностей mbedtls-devel Якщо на етапі збірки буде помилка: ``` bash FTL/src/webserver/x509.c:232:19: error: too few arguments to function ‘mbedtls_x509write_crt_pem’; expected 5, have 3 232 | if((ret = mbedtls_x509write_crt_pem(&ca_cert, ca_buffer, sizeof(ca_buffer))) != 0) ``` Це значить, що у вас (як і в мене) в репозиторіях застаріла версія `mbedtls-devel`: ``` bash $ dnf info mbedtls-devel | grep Version Version : 3.6.5 Version : 3.6.5 ``` => https://github.com/pi-hole/FTL/issues/2778 => https://docs.pi-hole.net/ftldns/compile/ ``` bash wget https://github.com/Mbed-TLS/mbedtls/releases/download/mbedtls-4.0.0/mbedtls-4.0.0.tar.bz2 -O mbedtls-4.0.0.tar.bz2 tar -xjf mbedtls-4.0.0.tar.bz2 cd mbedtls-4.0.0 sed -i '/#define MBEDTLS_THREADING_C/s*^//**g' include/mbedtls/mbedtls_config.h sed -i '/#define MBEDTLS_THREADING_PTHREAD/s*^//**g' include/mbedtls/mbedtls_config.h cmake -S . -B build -DCMAKE_C_FLAGS="-fomit-frame-pointer" cmake --build build -j $(nproc) sudo cmake --install build ``` Взагалі, коли змінюєте системні залежності в процесі відлову помилок компілятора, або довстановлюєте відсутні пакети `*-devel`, варто скидати поточний сетап з подальшою пере-конфігурацією проєкту: ``` bash rm -rf * cmake .. cmake --build . ``` ## Встановлення Продовжуємо збірку Pi-hole і перевіряємо результат: ``` bash ./pihole-FTL verify ``` В корені FTL ще є корисні скрипти тестів, варто заглянути, але я їх не проходив: ``` FTL/test/run.sh ``` Далі я буду пускати сервер від systemd, тому мене влаштовує глобальна інсталяція від root: ``` bash sudo cmake --install . ``` Вручну потрібно додати стандартні розташування: ``` bash sudo mkdir -p /etc/pihole/config_backups sudo mkdir -p /run/pihole sudo mkdir -p /var/log/pihole sudo touch /etc/pihole/dhcp.leases sudo touch /var/log/pihole/FTL.log sudo touch /var/log/pihole/pihole.log sudo touch /var/log/pihole/webserver.log ``` А також видати на неї права користувачеві, від якого планується запуск служби: ``` bash sudo chown -R pihole:pihole /etc/pihole /run/pihole /var/log/pihole ``` * `pihole:pihole` (USER:GROUP) - ваше значення ## Налаштування Якщо запустити сервіс на стандартному конфігі, то можна побачити як мінімум наступне: ``` bash sudo ss -tulpn | grep pihole-FTL udp UNCONN 0 0 0.0.0.0:53 0.0.0.0:* users:(("pihole-FTL",pid=24659,fd=4)) udp UNCONN 0 0 0.0.0.0:53 0.0.0.0:* users:(("pihole-FTL",pid=24294,fd=20)) tcp LISTEN 0 200 0.0.0.0:443 0.0.0.0:* users:(("pihole-FTL",pid=24659,fd=29)) tcp LISTEN 0 200 0.0.0.0:80 0.0.0.0:* users:(("pihole-FTL",pid=24659,fd=28)) tcp LISTEN 0 200 [::]:443 [::]:* users:(("pihole-FTL",pid=24659,fd=31)) tcp LISTEN 0 200 [::]:80 [::]:* users:(("pihole-FTL",pid=24659,fd=30)) ``` Це означає, що якщо у вас є локальна мережа типу Yggdrasil, всі її користувачі зможуть безперешкодно звертатись на цей сервер за виключенням, якщо у вас налаштоване блокування через фаєрвол або в самій програмі це передбачено версією. Також я планую запуск цього серверу локально, тому `0.0.0.0/::` мені потрібно змінити на `127.0.0.1/::1`, звільнити 53, 80 порти (на формальні 5354 і 8053) і прибрати зайвий сокет 443 (HTTPs) - це робиться у файлі `/etc/pihole/pihole.toml`, який буде створено автоматично при першому запуску: ``` /etc/pihole/pihole.toml [webserver] port = "127.0.0.1:8053,[::1]:8053" ### CHANGED, default = "80o,443os,[::]:80o,[::]:443os" [webserver.paths] # цей шлях можна змінити на свій # або встановити до теки `/var/www/html/admin` корінь репозиторію: # `git clone https://github.com/pi-hole/web.git admin` webroot = "/var/www/html" [dns] listeningMode = "BIND" ### CHANGED, default = "LOCAL" port = 5354 ### CHANGED, default = 53 [dns.reply.host] IPv4 = "127.0.0.1" ### CHANGED, default = "" IPv6 = "::1" ### CHANGED, default = "" ``` ## Системний сервіс ``` bash sudo useradd -s /usr/sbin/nologin -Mr pihole ``` ``` /etc/systemd/system/pihole.service [Unit] Description=Pi-hole FTL DNS and Web Server After=network.target [Service] Type=exec User=pihole Group=pihole # дізнатись поточне розташування: `$ which pihole-FTL` # всі опції запуску: `$ pihole-FTL --help` ExecStart=/usr/bin/pihole-FTL -f # AmbientCapabilities=CAP_NET_BIND_SERVICE CAP_NET_RAW CAP_NET_ADMIN # CapabilityBoundingSet=CAP_NET_BIND_SERVICE CAP_NET_RAW CAP_NET_ADMIN # Restart=on-failure # RestartSec=5s [Install] WantedBy=multi-user.target ``` * у цьому випадку використовується `Type=exec` разом з `-f` (foreground) бо в мене чомусь в бекграунді крашиться процес навіть з forking ## Налаштування системного резольвера В Fedora я змінюю налаштування одним рядком у файлі: ``` /etc/systemd/resolved.conf [Resolve] DNS=127.0.0.1:5354 ``` Тепер потрібно перезавантажити службу: ``` bash sudo systemctl restart systemd-resolved ``` Переглянути статус: ``` bash resolvectl status ``` Якщо все зроблено правильно, то у Веб-адмінці (за адресою у прикладі - http://localhost:8053/admin/) почне відображатись аналітика локальних запитів: => pi-hole-manual-install-on-fedora-linux/web-ui.png Вигляд адмінки Pi-hole (скріншот) ## pi-hole/pi-hole Не був би-то піхол: згодом виявилось, що найважливіша функція білих/чорних списків все ще не працює при спробі оновити базу в адмінці. Для вирішення цієї проблеми, потрібен ще один компонент: ``` bash git clone https://github.com/pi-hole/pi-hole sudo mkdir -p /etc/.pihole sudo install pi-hole/advanced/* /etc/.pihole sudo chown pihole:pihole /opt/pihole ``` А також: ``` bash sudo mkdir -p /opt/pihole sudo install pi-hole/advanced/Scripts/* /opt/pihole sudo install pi-hole/gravity.sh /opt/pihole ``` * можливо щось з того лінкується, але в мене це копії І наостанок: ``` bash sudo install pi-hole/pihole /usr/local/bin ``` Технічно, після цих маніпуляцій, повинна без помилок працювати відповідна функціональність в адмінці, а також команда ініціалізації бази списків "Gravity": ``` bash sudo pihole -g ``` * Бонус: нарешті в `pi-hole/advanced/Templates/pihole-FTL.service`, я випадково знайшов приклад конфігурації сервісу systemd, де й дійсно для запуску потрібен аргумент `-f`. ## Висновки Чесно кажучи, з цими кущами-хащами bash, я розчарувався в даному рішенні. Навіть, якщо в Pi-hole вгепано багато зусиль сісадмінів, що звикли спілкуватись з компом переважно мовою препроцесору і текстових конфігів. Для мене це не стабільність, не передбачувана поведінка через відсутність типізації і логічних помилок; залежність від контейнера. Оскільки мені головою (замість процесора) переварювати цей баш в сирому вигляді і на живій системі не цікаво, шукатиму якесь інше рішення, а досвід - хай лишається на замітку.