DevOps

Настройка Nginx как прокси для Unbound DNS (DoH)

Правильная конфигурация Nginx для Unbound DNS с grpc_pass, улучшение безопасности TLS, производительности кэшированием. Управление профилями, генерация iOS .mobileconfig, временные ссылки и автоудаление через 10 мин для DoH-сервера.

6 ответов 3 просмотра

Правильна ли конфигурация 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 и его преимущества

DNS-over-HTTPS (DoH) — это современный протокол, инкапсулирующий DNS-запросы в HTTPS-трафик для повышения безопасности и конфиденциальности. Стандартизированный в RFC 8484 (2018), DoH использует HTTP/2 + TLS, маскируя DNS-запросы под обычный веб-трафик на порту 443. Это делает их неотличимыми от обычного HTTPS-соединения и защищает от перехвата и подмены.

Сравнение незащищенного DNS-трафика и DoH-запроса в Wireshark

Историческое развитие протоколов безопасности 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 реализуйте следующие меры:

  1. 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;
  1. Ограничение доступа:
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;
}
  1. Скрытие версии Nginx:
server_tokens off;

Производительность

Оптимизация производительности для DoH включает:

  1. Кэширование 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;
}
  1. Оптимизация буферов:
client_body_buffer_size 128k;
client_max_body_size 1m;
large_client_header_buffers 4 8k;
  1. 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 минут.

Генерация временных токенов

Используйте криптографически безопасный генератор токенов:

bash
#!/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;
 }
}

Система управления токенами

Создайте скрипт для управления жизненным циклом токенов:

bash
#!/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
<?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-ссылок:

bash
#!/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):
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‑таймер:

ini
# /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
ini
# /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

Скрипт очистки:

bash
#!/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 сервиса настройте мониторинг:

nginx
# Включение подробного логирования
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:

yaml
# prometheus.yml
scrape_configs:
 - job_name: 'nginx_doh'
 static_configs:
 - targets: ['localhost:9113']
 metrics_path: /metrics

Уведомления об ошибках

Настройте систему уведомлений о критических ошибках:

bash
#!/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

Эта система обеспечивает автоматическое удаление неиспользуемых конфигураций, мониторинг работы сервиса и уведомления о критических ошибках.


Источники

  1. Server Fault — Конфигурация Nginx как обратного прокси для Unbound DoH: https://serverfault.com/questions/1058252/runing-unbound-doh-behind-nginx

  2. SkyDNS — DNS-over-HTTPS: протокол, преимущества и ограничения: https://skydns.ru/blog/dns-over-https

  3. Habr — Развертывание собственного DNS-over-HTTPS сервера: https://habr.com/ru/articles/467237/

  4. ArchWiki — Настройка DoH/DoT сервера с использованием CoreDNS: https://wiki.archlinux.org/title/DNS_over_HTTPS_servers

  5. 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, контролируемую вами, а не зависящую от крупных корпоративных сервисов.

K

Проблема использования Nginx в качестве обратного прокси для Unbound DoH заключается в том, что Unbound DoH ожидает HTTP/2 запросы, а модуль proxy в Nginx не поддерживает HTTP/2 на upstream-соединениях. Это приводит к ошибке 502 Bad Gateway. Решением является использование grpc_pass вместо proxy_pass:

nginx
location /dns-query {
 grpc_pass grpc://unbound-host;
}

Также необходимо отключить TLS для DNS-over-HTTP в конфигурации Unbound:

bash
http-notls-downstream: yes
Я

DNS-over-HTTPS (DoH) - это протокол, инкапсулирующий DNS-запросы в HTTPS-трафик для повышения безопасности и конфиденциальности. Стандартизирован в RFC 8484 (2018), DoH использует HTTP/2 + TLS, маскируя DNS-запросы под обычный веб-трафик на порту 443. Это делает их неотличимыми от обычного HTTPS-соединения и защищает от перехвата и подмены.

Сравнение незащищенного DNS-трафика и DoH-запроса в Wireshark

Историческое развитие: DNSSEC (1990-е) для подписи ответов, DNSCrypt (2013) как первая попытка шифрования, DoT (RFC 7858, 2016) через порт 853, и наконец DoH как наиболее современное решение. Преимущества DoH включают защиту от наблюдения со стороны провайдеров и цензуры, но есть и недостатки: только для веб-трафика и риск централизации вокруг крупных сервисов вроде Cloudflare и Google.

M

При развертывании собственного DNS-over-HTTPS сервера важно понимать его ограничения. DoH ориентирован исключительно на веб-трафик, что делает его менее универсальным по сравнению с DNS-over-TLS (DoT). Кроме того, массовое внедрение DoH в браузеры приводит к централизации DNS-запросов вокруг крупных сервисов, что создает новые риски для приватности.

Для построения безопасной децентрализованной инфраструктуры рекомендуется использовать DoT совместно с DNSSEC/DANE. Однако если выбор падает на DoH, то развертывание собственного сервера позволяет избежать зависимости от корпоративных сервисов и обеспечить контроль над данными. При этом важно понимать, что DoH не решает проблему DNS для не-веб сервисов.

Для настройки DoH/DoT сервера с использованием CoreDNS необходимо создать конфигурационный файл /etc/coredns/Corefile с указанием протокола, домена и порта прослушивания, а также параметров пересылки запросов. Пример конфигурации для DoT прокси:

bash
. {
 forward . tls://1.1.1.1 {
 tls_servername cloudflare-dns.com 
 }
}

Для DoH/DoT/gRPC необходимо указать пути к сертификатам:

bash
tls cert.pem key.pem

После настройки CoreDNS нужно запустить или включить системный юнит coredns.service.

P

Для настройки DoH/DoT на устройствах iOS/macOS необходимо установить конфигурационный профиль .mobileconfig с соответствующими параметрами. Профиль должен содержать:

xml
<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.

Авторы
K
Системный администратор
M
Системный администратор
Я
Специалист по DNS-безопасности
M
Системный администратор
P
Разработчик
X
Разработчик
C
Разработчик
Источники
Documentation Portal
Проверено модерацией
НейроОтветы
Модерация
Настройка Nginx как прокси для Unbound DNS (DoH)