Что происходит в обычном сценарии подключения к интернету в домашней сети?
Этапы:
- Получение настроек: Устройства получают от роутера адрес DNS-сервера
- Использование публичного DNS: Обычно это DNS провайдера, Google (8.8.8.8) или Cloudflare (1.1.1.1)
- Отправка всех запросов: Все DNS-запросы уходят на внешний сервер
- Получение ответов: Ответы приходят напрямую к устройствам
Проблемы этой схемы:
1. Конфиденциальность 👁️
- Провайдер видит ВСЕ: Каждый запрос, каждый сайт, каждое приложение
- Google/Cloudflare знают о вас: Если используете их DNS, они строят профиль
- Полная история посещений: Доступна третьим лицам
2. Реклама и трекеры 🎯
- Нет фильтрации: Вся реклама проходит беспрепятственно
- Трекеры следят за вами: Сайты знают, где вы были и что искали
- Таргетированная реклама: На основе ваших запросов показывается релевантная реклама
3. Безопасность ⚠️
- DNS-спуфинг: Легче подменить ответы
- Нет проверки подлинности: Ответы могут быть от поддельных серверов
- Манипуляции с трафиком: Провайдер может перенаправлять запросы
4. Цензура и ограничения 🚫
- Фильтрация на уровне DNS: Провайдер может блокировать сайты
- Гео-ограничения: DNS может определять ваше местоположение
- Троттлинг: Замедление определенных запросов
В этой статье будем стараться исправить имеющиеся у нас "проблемы" при взаимодействии с Интернет.
docker-compose
Для фильтрации DNS-запросов будем использовать Pi-hole, а в роли DNS-сервера будем использовать Unbound .
Чтобы описать docker-compose.yml сначала опишем концептуальную схему:
Как это работает:
- Настройка (1 раз):Роутер назначает Pi-hole в качестве DNS-сервера для всех устройств
Все устройства автоматически начинают использовать Pi-hole - Когда вы заходите на сайт:Устройство спрашивает у Pi-hole: "Где находится определенный сайт?"
Pi-hole проверяет: если это реклама → блокирует, если нет → спрашивает Unbound
Unbound напрямую обращается к корневым DNS-серверам в интернете
Получает "чистый" ответ без посредников
Ответ возвращается к вашему устройству - Что это дает:✅ Блокировка рекламы на всех устройствах
✅ Безопасность: Unbound не использует сторонние DNS-серверы
✅ Конфиденциальность: ваши запросы не идут к Google/Cloudflare
✅ Скорость: кэширование часто запрашиваемых сайтов
Создадим необходимые файлы для работы:
# Создаем папки и файлы
mkdir {dns,dns/config_pihole,dns/config_unbound}
cd dns
touch {docker-compose.yml,.env,config_unbound/a-records.conf,config_unbound/srv-records.conf,config_unbound/forward-records.conf}
cat > .env << 'EOF'
PIHOLE_PASSWORD=<your_secret_password>
EOF
cat > config_unbound/unbound.conf << 'EOF'
server:
verbosity: 1
interface: 0.0.0.0@53
access-control: 0.0.0.0/0 allow
do-ip4: yes
do-udp: yes
do-tcp: yes
hide-identity: yes
hide-version: yes
prefetch: yes
prefetch-key: yes
num-threads: 2
so-reuseport: yes
EOF
Редактируем systemd-resolved, чтобы 53 порт был у нас не занят и мы могли управлять DNS-запросами через наши сервисы:
# Открываем для редактирования конфиг systemd-resolved
$ sudo nano /etc/systemd/resolved.conf
# Вставляем/заменяем (пункт должен быть раскомментирован)
DNSStubListener=no
Перезапускаем и проверяем systemd-resolved:
# Перезапускаем службу
sudo systemctl restart systemd-resolved
# Проверяем
sudo ss -tulpn | grep :53
Редактируем docker-compose.yml через nano docker-compose.yml:
services:
unbound:
container_name: unbound
image: mvance/unbound:latest
restart: unless-stopped
volumes:
- './config_unbound:/opt/unbound/etc/unbound/'
networks:
dns:
pihole-init:
image: pihole/pihole:latest
container_name: pihole_init
volumes:
- './config_pihole:/etc/pihole'
environment:
- TZ=Europe/Moscow
- FTLCONF_webserver_api_password=${PIHOLE_PASSWORD}
- FTLCONF_dns_listeningMode=ALL
- FTLCONF_dns_upstreams=8.8.8.8;1.1.1.1
dns:
- 8.8.8.8
- 1.1.1.1
command: >
sh -c "
if [ ! -f /etc/pihole/gravity.db ]; then
echo 'Создаём базу данных с публичными DNS...';
# Запускаем создание базы данных
pihole-FTL &
sleep 5
pihole updateGravity
sleep 30
pkill pihole-FTL
echo 'База создана!';
else
echo 'База уже существует, пропускаем инициализацию';
fi
"
restart: "no" # Запускаем только один раз
networks:
dns:
pihole:
container_name: pihole
image: pihole/pihole:latest
ports:
- "53:53/tcp"
- "53:53/udp"
- "280:80/tcp"
environment:
- TZ=Europe/Moscow
- FTLCONF_webserver_api_password=${PIHOLE_PASSWORD}
- FTLCONF_dns_listeningMode=ALL
- FTLCONF_dns_upstreams=unbound
volumes:
- './config_pihole:/etc/pihole/'
cap_add:
- NET_ADMIN
- SYS_NICE
env_file:
- ".env"
restart: unless-stopped
networks:
dns:
depends_on:
- unbound
- pihole-init
networks:
dns:
driver: bridge
Перед запуском создаем сеть:
docker network create dns
# Проверить создание
# docker network ls
Сервис pihole-init нужен для первого запуска и я не нашел как запустить иначе. После запуска его можно остановить docker stop pihole-init.
После запуска в UI
Pi-hole мы можем попасть по адресу: http://<your_ip>:280/admin.
Вводим пароль, который мы указали в файле c секретами выше. В самом
начале никакой статистики мы не будем видеть, так как на пути устройств в
Интернет ничего не изменилось. Исправлять этот момент будем на
следующем этапе.
Настройки роутера
Заходим в интерфейс роутера, обычно это 192.168.0.1.
Авторизируемся.
Делаем бэкап настроек роутера на всякий случай 😆.
Находим
настройку, которая отвечает за DNS. В моем TP Link Archer A6 v2.0:
Дополнительные настройки -> Сеть -> Дополнительные настройки. В
окнах с "Предпочитаемый DNS-сервер"и "Альтернативный DNS-сервер"
указываем IP VM или ПК, где развернуты наши сервисы.
Перезагружаем
роутер. Теперь должны увидеть статистику, которая постоянно изменяется,
так как наши устройства постоянно делают запросы через наш роутер.
Проверка работы сервисов
Проверка запросов:
# Первый запрос (должен быть медленнее, >50 мс)
$ docker exec pihole dig @127.0.0.1 stackoverflow.com | grep -E "Query time|IN.*A"
# Сразу же второй запрос (должен быть быстрее, <5 мс
$ docker exec pihole dig @127.0.0.1 stackoverflow.com | grep -E "Query time|IN.*A"
;stackoverflow.com. IN A
stackoverflow.com. 300 IN A 198.252.206.1
;; Query time: 20 msec
;stackoverflow.com. IN A
stackoverflow.com. 300 IN A 198.252.206.1
;; Query time: 1 msec
Видим косвенное подтверждение работы: первый запрос выполнился, а затем сработал кэш Unbound.
Проверка перенаправления unbound:
$ docker exec pihole tail -f /var/log/pihole/pihole.log | grep "forwarded"
Dec 19 13:50:53 dnsmasq[55]: forwarded open.selezen.org to 172.20.0.3
Dec 19 13:50:53 dnsmasq[55]: forwarded open.selezen.org to 172.20.0.3
Должный увидеть вывод как в примере выше, который говорит о работе Unbound. 172.20.0.3 - это IP нашего контейнера Unbound.
Умный дом
Чтобы видеть всю статистику в 1 месте устанавливаем:
Карточка Pi-hole из HACS. Теперь можем видеть в 1 месте статистику Pi-hole:
Мои наблюдения
До 2022 г.:
- До 30% трафика блокировалось.
- Устройство
с самым большим количеством заблокированных DNS-запросов была умная
колонка с Алисой. Ничего этим не хочу сказать, просто наблюдения.
Итог
На всех наших устройствах фильтруется реклама на уровне DNS-запросов.
Ссылки:
1. Зачем нужен собственный сервер в 2025?
2. Как установить Proxmox?
*.wikipedia.org - РКН: иностранный владелец ресурса нарушает закон РФ.