Настройка Nginx как прокси для Unbound DNS (DoH)
Правильная конфигурация Nginx для Unbound DNS с grpc_pass, улучшение безопасности TLS, производительности кэшированием. Управление профилями, генерация iOS .mobileconfig, временные ссылки и автоудаление через 10 мин для DoH-сервера.
Правильна ли конфигурация Nginx в качестве обратного прокси для Unbound DNS? Какие существуют рекомендации по улучшению безопасности и производительности? Как настроить Nginx для шифрования и управления клиентскими профилями с доступом по временным ссылкам вида dns.domain.xyz/FgCKkdkf? Как интегрировать генерацию конфигурационных файлов для iOS (.mobileconfig) и DoH-ссылок для других клиентов с автоматическим удалением через 10 минут?
Правильная настройка Nginx в качестве обратного прокси для Unbound DNS требует особого подхода, учитывая особенности HTTP/2 и безопасности. DNS-over-HTTPS (DoH) через Nginx требует использования grpc_pass вместо proxy_pass и отключения TLS в Unbound для корректной работы. Для повышения безопасности и управления клиентскими профилями необходимо реализовать временные ссылки, шифрование и автоматическое удаление конфигурационных данных.
Содержание
- Введение в DNS-over-HTTPS и его преимущества
- Настройка Nginx как обратного прокси для Unbound DNS
- Улучшение безопасности и производительности Nginx для DoH
- Управление клиентскими профилями с временными ссылками
- Генерация конфигурационных файлов для iOS и DoH-ссылок
- Интеграция автоматического удаления и мониторинг
Введение в DNS-over-HTTPS и его преимущества
DNS-over-HTTPS (DoH) — это современный протокол, инкапсулирующий DNS-запросы в HTTPS-трафик для повышения безопасности и конфиденциальности. Стандартизированный в RFC 8484 (2018), DoH использует HTTP/2 + TLS, маскируя DNS-запросы под обычный веб-трафик на порту 443. Это делает их неотличимыми от обычного HTTPS-соединения и защищает от перехвата и подмены.
Историческое развитие протоколов безопасности DNS включает DNSSEC (1990-е) для подписи ответов, DNSCrypt (2013) как первую попытку шифрования, DNS-over-TLS (DoT, RFC 7858, 2016) через порт 853, и наконец DoH как наиболее современное решение. Преимущества DoH включают защиту от наблюдения со стороны провайдеров и цензуры, но есть и недостатки: только для веб-трафика и риск централизации вокруг крупных сервисов вроде Cloudflare и Google.
Для корпоративных и частных пользователей развертывание собственного DNS-over-HTTPS сервера позволяет избежать зависимости от корпоративных сервисов и обеспечить контроль над данными. Важно понимать, что DoH не решает проблему DNS для не-веб сервисов, что делает его менее универсальным по сравнению с DNS-over-TLS.
Настройка Nginx как обратного прокси для Unbound DNS
При развертывании Nginx в качестве обратного прокси для Unbound DNS возникает ключевая проблема: Unbound DoH ожидает HTTP/2 запросы, а модуль proxy в Nginx не поддерживает HTTP/2 на upstream-соединениях. Это приводит к ошибке 502 Bad Gateway и недоступности сервиса.
Правильная конфигурация Nginx должна использовать grpc_pass вместо стандартного proxy_pass:
server {
listen 443 ssl http2;
server_name dns.domain.xyz;
ssl_certificate /path/to/fullchain.pem;
ssl_certificate_key /path/to/privkey.pem;
location /dns-query {
grpc_pass grpc://127.0.0.1:5053;
# Безопасные заголовки
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
}
}
Одновременно с этим необходимо отключить TLS для DNS-over-HTTP в конфигурации Unbound:
# В конфигурации Unbound
server:
interface: 127.0.0.1
port: 5053
http-notls-downstream: yes
harden-dnssec-stripped: yes
harden-glue: yes
use-caps-for-id: yes
Эта комбинация обеспечивает корректную работу Nginx как обратного прокси для Unbound DNS. Важно отметить, что grpc_pass обеспечивает поддержку HTTP/2 для upstream-соединений, что критически важно для DoH-протокола.
Улучшение безопасности и производительности Nginx для DoH
Безопасность
Для повышения безопасности вашего DNS-over-HTTPS сервера на базе Nginx реализуйте следующие меры:
- TLS-конфигурация:
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers 'TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:ECDHE-RSA-AES128-GCM-SHA256';
ssl_prefer_server_ciphers off;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
ssl_session_tickets off;
- Ограничение доступа:
location /dns-query {
grpc_pass grpc://127.0.0.1:5053;
# Ограничение по IP-адресам
allow 192.168.1.0/24;
deny all;
# Ограничение по частоте запросов
limit_req zone=dns_per_ip burst=20 nodelay;
}
- Скрытие версии Nginx:
server_tokens off;
Производительность
Оптимизация производительности для DoH включает:
- Кэширование DNS-ответов в Nginx:
proxy_cache_path /var/cache/nginx/dns levels=1:2 keys_zone=dns_cache:10m inactive=60m;
location /dns-query {
grpc_pass grpc://127.0.0.1:5053;
proxy_cache dns_cache;
proxy_cache_key "$scheme$proxy_host$request_uri";
proxy_cache_valid 200 302 60m;
}
- Оптимизация буферов:
client_body_buffer_size 128k;
client_max_body_size 1m;
large_client_header_buffers 4 8k;
- HTTP/2 оптимизация:
http2_max_field_size 64k;
http2_max_header_size 64k;
http2_max_requests 1000;
Эти настройки значительно улучшают безопасность и производительность вашего DNS-over-HTTPS сервиса, делая его конкурентоспособным с крупными публичными сервисами.
Управление клиентскими профилями с временными ссылками
Для управления доступом клиентов к вашему DNS-over-HTTPS сервису реализуйте систему временных ссылок вида dns.domain.xyz/FgCKkdkf. Это обеспечивает безопасную передачу конфигурации клиентам с автоматическим удалением через 10 минут.
Генерация временных токенов
Используйте криптографически безопасный генератор токенов:
#!/bin/bash
# generate_temp_token.sh
TOKEN_LENGTH=12
TOKEN=$(head -c 256 /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w $TOKEN_LENGTH | head -n 1)
echo $TOKEN
Конфигурация Nginx для временных ссылок
server {
listen 443 ssl http2;
server_name dns.domain.xyz;
# Основной DNS-эндпоинт
location /dns-query {
grpc_pass grpc://127.0.0.1:5053;
allow all;
}
# Временные ссылки для конфигурации
location ~ ^/([a-zA-Z0-9]{12})$ {
# Проверка валидности токена
if (!-f /var/nginx/tokens/$1) {
return 404;
}
# Передача конфигурации
alias /var/nginx/configs/$1.mobileconfig;
default_type application/x-apple-aspen-config;
# Автоматическое удаление после 10 минут
add_header X-Token-Expires "10 minutes" always;
}
}
Система управления токенами
Создайте скрипт для управления жизненным циклом токенов:
#!/bin/bash
# manage_tokens.sh
TOKEN=$(./generate_temp_token.sh)
CONFIG_FILE="/var/nginx/configs/$TOKEN.mobileconfig"
TOKEN_FILE="/var/nginx/tokens/$TOKEN"
# Создание конфигурации
cat > "$CONFIG_FILE" <<EOF
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>PayloadContent</key>
<dict>
<key>DNSOverHTTPS</key>
<dict>
<key>ServerURL</key>
<string>https://dns.domain.xyz/dns-query</string>
</dict>
</dict>
</dict>
</plist>
EOF
# Создание файла токена
touch "$TOKEN_FILE"
# Планирование удаления через 10 минут
(sleep 600; rm -f "$CONFIG_FILE" "$TOKEN_FILE") &
Эта система обеспечивает безопасную передачу конфигурации клиентам с автоматическим удалением через 10 минут, предотвращая накопление неиспользуемых конфигураций.
Генерация конфигурационных файлов для iOS и DoH-ссылок
Конфигурационные профили для iOS (.mobileconfig)
Для установки DNS-over-HTTPS на устройствах iOS/macOS необходимо создать конфигурационный профиль .mobileconfig с соответствующими параметрами:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>PayloadIdentifier</key>
<string>com.example.dohprofile</string>
<key>PayloadDisplayName</key>
<string>DoH DNS Configuration</string>
<key>PayloadDescription</key>
<string>Configure DNS-over-HTTPS for enhanced security</string>
<key>PayloadVersion</key>
<integer>1</integer>
<key>PayloadContent</key>
<dict>
<key>DNSOverHTTPS</key>
<dict>
<key>ServerURL</key>
<string>https://dns.domain.xyz/dns-query</string>
<key>ServerName</key>
<string>dns.domain.xyz</string>
<key>ExcludedDomains</key>
<array>
<string>localhost</string>
<string>127.0.0.1</string>
<string>169.254.0.0/16</string>
</array>
</dict>
</dict>
</dict>
</plist>
Установка профиля выполняется через: Настройки > Общие > Профили. Важно учитывать ограничения профилей: игнорирование iCloud Private Relay, VPN-клиентов, captive portals, а также то, что CLI-инструменты (dig) не используют DoH.
Генерация DoH-ссылок для других клиентов
Для других клиентов (Windows, Android, Linux) создайте систему генерации DoH-ссылок:
#!/bin/bash
# generate_doh_link.sh
CLIENT_TYPE=$1
TOKEN=$(./generate_temp_token.sh)
case $CLIENT_TYPE in
"windows")
echo "dns.domain.xyz/dns-query#$TOKEN"
;;
"android")
echo "https://dns.domain.xyz/dns-query#$TOKEN"
;;
"linux")
echo "https://dns.domain.xyz/dns-query#$TOKEN"
;;
*)
echo "Unsupported client type"
exit 1
;;
esac
Для настройки различных клиентов используйте следующие форматы:
- Windows (PowerShell):
Set-DnsClientServerAddress -InterfaceAlias "Ethernet" -ServerAddresses ("https://dns.domain.xyz/dns-query")
- Android (Wi‑Fi настройки):
HTTPS://dns.domain.xyz/dns-query
- Linux (resolv.conf):
nameserver https://dns.domain.xyz/dns-query
Для каждой платформы существуют специфические требования к формату DoH‑ссылок, которые необходимо учитывать при генерации конфигурационных файлов.
Интеграция автоматического удаления и мониторинг
Система автоматического удаления
Для реализации автоматического удаления конфигураций и токенов через 10 минут создайте systemd‑таймер:
# /etc/systemd/system/dns-cleanup.timer
[Unit]
Description=Clean up expired DNS tokens and configs
Requires=dns-cleanup.service
[Timer]
OnBootSec=10min
OnUnitActiveSec=10min
Persistent=true
[Install]
WantedBy=timers.target
# /etc/systemd/system/dns-cleanup.service
[Unit]
Description=Clean up expired DNS tokens and configs
After=network.target
[Service]
Type=oneshot
ExecStart=/usr/local/bin/cleanup_dns_configs.sh
Скрипт очистки:
#!/bin/bash
# cleanup_dns_configs.sh
find /var/nginx/tokens -type f -mmin +10 -exec rm -f {} \;
find /var/nginx/configs -type f -mmin +10 -exec rm -f {} \;
Мониторинг и логирование
Для отслеживания работы вашего DNS-over-HTTPS сервиса настройте мониторинг:
# Включение подробного логирования
access_log /var/log/nginx/dns_access.log combined buffer=512k flush=1m;
error_log /var/log/nginx/dns_error.log warn;
# Метрики для Prometheus
location /metrics {
stub_status on;
access_log off;
}
Для анализа производительности используйте Prometheus с Grafana:
# prometheus.yml
scrape_configs:
- job_name: 'nginx_doh'
static_configs:
- targets: ['localhost:9113']
metrics_path: /metrics
Уведомления об ошибках
Настройте систему уведомлений о критических ошибках:
#!/bin/bash
# monitor_doh.sh
ERROR_COUNT=$(grep "502 Bad Gateway" /var/log/nginx/dns_error.log | wc -l)
if [ $ERROR_COUNT -gt 5 ]; then
mail -s "Critical DoH Error Alert" admin@example.com <<EOF
Detected $ERROR_COUNT 502 errors in DoH service. Please check Nginx configuration.
EOF
fi
Эта система обеспечивает автоматическое удаление неиспользуемых конфигураций, мониторинг работы сервиса и уведомления о критических ошибках.
Источники
-
Server Fault — Конфигурация Nginx как обратного прокси для Unbound DoH: https://serverfault.com/questions/1058252/runing-unbound-doh-behind-nginx
-
SkyDNS — DNS-over-HTTPS: протокол, преимущества и ограничения: https://skydns.ru/blog/dns-over-https
-
Habr — Развертывание собственного DNS-over-HTTPS сервера: https://habr.com/ru/articles/467237/
-
ArchWiki — Настройка DoH/DoT сервера с использованием CoreDNS: https://wiki.archlinux.org/title/DNS_over_HTTPS_servers
-
GitHub — Генерация конфигурационных файлов для iOS (.mobileconfig): https://github.com/paulmillr/encrypted-dns
Заключение
Правильная настройка Nginx в качестве обратного прокси для Unbound DNS требует использования grpc_pass вместо proxy_pass и отключения TLS в Unbound для корректной работы DNS-over-HTTPS. Для повышения безопасности реализуйте TLS‑конфигурацию, ограничение доступа и кэширование DNS‑ответов.
Система управления клиентскими профилями с временными ссылками вида dns.domain.xyz/FgCKkdkf обеспечивает безопасную передачу конфигураций с автоматическим удалением через 10 минут. Для iOS генерируйте .mobileconfig профили, а для других клиентов создавайте соответствующие DoH‑ссылки с учетом специфики каждой платформы.
Интеграция автоматического удаления через systemd‑таймер и мониторинг с Prometheus обеспечивает стабильную работу вашего DNS-over-HTTPS сервиса. Такой подход позволяет создать безопасную, производительную и управляемую инфраструктуру DoH, контролируемую вами, а не зависящую от крупных корпоративных сервисов.
Проблема использования Nginx в качестве обратного прокси для Unbound DoH заключается в том, что Unbound DoH ожидает HTTP/2 запросы, а модуль proxy в Nginx не поддерживает HTTP/2 на upstream-соединениях. Это приводит к ошибке 502 Bad Gateway. Решением является использование grpc_pass вместо proxy_pass:
location /dns-query {
grpc_pass grpc://unbound-host;
}
Также необходимо отключить TLS для DNS-over-HTTP в конфигурации Unbound:
http-notls-downstream: yes
DNS-over-HTTPS (DoH) - это протокол, инкапсулирующий DNS-запросы в HTTPS-трафик для повышения безопасности и конфиденциальности. Стандартизирован в RFC 8484 (2018), DoH использует HTTP/2 + TLS, маскируя DNS-запросы под обычный веб-трафик на порту 443. Это делает их неотличимыми от обычного HTTPS-соединения и защищает от перехвата и подмены.
Историческое развитие: DNSSEC (1990-е) для подписи ответов, DNSCrypt (2013) как первая попытка шифрования, DoT (RFC 7858, 2016) через порт 853, и наконец DoH как наиболее современное решение. Преимущества DoH включают защиту от наблюдения со стороны провайдеров и цензуры, но есть и недостатки: только для веб-трафика и риск централизации вокруг крупных сервисов вроде Cloudflare и Google.
При развертывании собственного DNS-over-HTTPS сервера важно понимать его ограничения. DoH ориентирован исключительно на веб-трафик, что делает его менее универсальным по сравнению с DNS-over-TLS (DoT). Кроме того, массовое внедрение DoH в браузеры приводит к централизации DNS-запросов вокруг крупных сервисов, что создает новые риски для приватности.
Для построения безопасной децентрализованной инфраструктуры рекомендуется использовать DoT совместно с DNSSEC/DANE. Однако если выбор падает на DoH, то развертывание собственного сервера позволяет избежать зависимости от корпоративных сервисов и обеспечить контроль над данными. При этом важно понимать, что DoH не решает проблему DNS для не-веб сервисов.
Для настройки DoH/DoT сервера с использованием CoreDNS необходимо создать конфигурационный файл /etc/coredns/Corefile с указанием протокола, домена и порта прослушивания, а также параметров пересылки запросов. Пример конфигурации для DoT прокси:
. {
forward . tls://1.1.1.1 {
tls_servername cloudflare-dns.com
}
}
Для DoH/DoT/gRPC необходимо указать пути к сертификатам:
tls cert.pem key.pem
После настройки CoreDNS нужно запустить или включить системный юнит coredns.service.
Для настройки DoH/DoT на устройствах iOS/macOS необходимо установить конфигурационный профиль .mobileconfig с соответствующими параметрами. Профиль должен содержать:
<PayloadType>Configuration</PayloadType>
<DNSProtocol>HTTPS</DNSProtocol>
<ServerURL>https://example/dns-query</ServerURL>
Установка профиля выполняется через: Настройки > Общие > Профили. Подписанные профили (до 2025-11-02, подписанные Xernium) имеют дополнительную проверку подлинности. Важно учитывать ограничения профилей: игнорирование iCloud Private Relay, VPN-клиентов, captive portals, а также то, что CLI-инструменты (dig) не используют DoH.