Ручне встановлення Pi-hole DNS на прикладі Fedora / Linux


На сайті DOU є досить інформативний гайд з описом проєкту Pi-hole та причин користуватись ним сьогодні, на відміну від популярних uBlock і AdGuard:


Блокуємо рекламу за допомогою Pi Hole. Детальний гайд


Якщо коротко, то Pi-hole - дозволяє підняти локальний (або локально-мережний) проксі-сервер DNS з Веб-адмінкою, через яку можна наочно керувати правилами блокування та переглядати статистику запитів. При цьому, необхідність у високо-рівневих блокувальниках реклами відпадає, адже паразитний трафік не покидатиме "53 порт" локальної мережі ще на етапі резольву.


Взагалі, в мене були думки скористатись більш легкими рішеннями DNS, але Pi-hole заманив своєю візуалізацією і орієнтацією конкретно на потрібні мені задачі. У цьому матеріалі я не буду розглядати конкретний тюнінг блокування, але надам приклад ручного встановлення П/З, адже у всіх гайдах, які мені зустрілись нашвидкоруч - використовуються приклади інсталяції з Docker або автоматизованим скриптом:


curl -sSL https://install.pi-hole.net | bash

Мене це не влаштовує, оскільки сам скрипт доволі великий (через свою універсальність) а також просить root, що тим паче потребує додаткового аналізу виконаних дій на моїй системі. Адже наприклад на Fedora я не користуюсь більше firewalld, а в офіційній документації - зустрічаються ось такі дозвільні приклади, коли як для мене відкриття 80 порту на всі інтерфейси не є прийнятним:


https://docs.pi-hole.net/main/prerequisites/#ufw


Отже, пробігшись по репозиторіям проєкту на GitHub, назбирав для себе такий мінімальний набір:



FTL


Спочатку, знадобляться як мінімум такі залежності:


sudo dnf install gmp-static xxd mbedtls-devel

Забираємо початковий код і переходимо в його корінь:


git clone https://github.com/pi-hole/FTL.git
cd FTL

Компіляція


На цьому етапі, можна заглянути в `./build.sh`, але суть там наступна:


mkdir build
cd build
cmake -DCMAKE_C_FLAGS="-fPIC" ..
cmake --build .

Оновлення залежностей mbedtls-devel


Якщо на етапі збірки буде помилка:


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`:


$ 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/


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="-fPIC -fomit-frame-pointer"
cmake --build build -j $(nproc)
sudo cmake --install build

Взагалі, коли змінюєте системні залежності в процесі відлову помилок компілятора, або довстановлюєте відсутні пакети `*-devel`, варто скидати поточний сетап з подальшою пере-конфігурацією проєкту:


rm -rf *
cmake ..
cmake --build .

Встановлення


Продовжуємо збірку Pi-hole і перевіряємо результат:


./pihole-FTL verify

В корені FTL ще є корисні скрипти тестів, варто заглянути, але я їх не проходив:


FTL/test/run.sh

Далі я буду пускати сервер від systemd, тому мене влаштовує глобальна інсталяція від root:


sudo cmake --install .

Вручну потрібно додати стандартні розташування:


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

А також видати на них права користувачеві, від якого планується запуск служби:


sudo chown -R pihole:pihole /etc/pihole /run/pihole /var/log/pihole

Налаштування


Якщо запустити сервіс на стандартному конфігі, то можна побачити як мінімум наступне:


$ 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`, який буде створено автоматично при першому запуску:


[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 = ""

Системний сервіс


sudo useradd -s /usr/sbin/nologin -Mr pihole

[Unit]
Description=Pi-hole FTL DNS and Web Server
After=network.target

[Service]
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

Налаштування системного резольвера


В Fedora я змінюю налаштування одним рядком у файлі:


[Resolve]
DNS=127.0.0.1:5354
Domains=~.
# блокувати запити, якщо pi-hole DNS не доступний (лишити порожнім)
# FallbackDNS=

Тепер потрібно перезавантажити службу:


sudo systemctl restart systemd-resolved

Переглянути статус:


resolvectl status

Якщо все зроблено правильно, то у Веб-адмінці (за адресою у прикладі - http://localhost:8053/admin/) почне відображатись аналітика локальних запитів:


Вигляд адмінки Pi-hole (скріншот)


pi-hole/pi-hole


Не був би-то піхол: згодом виявилось, що найважливіша функція білих/чорних списків все ще не працює при спробі оновити базу в адмінці. Для вирішення цієї проблеми, потрібен ще один компонент:


git clone https://github.com/pi-hole/pi-hole
sudo mkdir -p /etc/.pihole
sudo cp -r pi-hole/advanced /etc/.pihole/
sudo chown pihole:pihole -R /etc/.pihole

А також:


sudo mkdir -p /opt/pihole
sudo cp -r pi-hole/advanced/Scripts/* /opt/pihole
sudo install pi-hole/gravity.sh /opt/pihole
sudo chown pihole:pihole -R /opt/pihole

І наостанок:


sudo install pi-hole/pihole /usr/local/bin

Технічно, після цих маніпуляцій, повинна без помилок працювати відповідна функціональність в адмінці, а також команда ініціалізації бази списків "Gravity":


sudo pihole -g


Висновки


Чесно кажучи, з цими кущами-хащами bash, я розчарувався в даному рішенні. Навіть, якщо в Pi-hole вгепано багато зусиль сісадмінів, що звикли спілкуватись з компом переважно мовою препроцесору і текстових конфігів. Для мене це не стабільність, не передбачувана поведінка через відсутність типізації і логічних помилок; залежність від контейнера.


Оскільки мені головою (замість процесора) переварювати цей баш в сирому вигляді і на живій системі не цікаво, шукатиму якесь інше рішення (див. crab-hole) а досвід - хай лишається на замітку.


Дивіться також


Crab-hole DNS як 100% програмна альтернатива Pi-hole



/uk/