24 авг. 2026

DNS-прокси для программного шлюза Pfsense. Как расширить функционал и защитить корпоративную сеть.

Настройка DOH через DNSProxy на корпоративном шлюзе Pfsense

Шлюз pfSense со встроенным резолвером Unbound из коробки поддерживает только DNS-over-TLS (DoT), но не имеет нативной поддержки DNS-over-HTTPS (DoH), что создает уязвимость для корпоративной сети: трафик DoT на стандартном порту 853 легко идентифицируется и блокируется вышестоящими провайдерами, в то время как DoH маскирует DNS-запросы под обычный зашифрованный веб-трафик (HTTPS, порт 443). Решением является интеграция легковесного DNSProxy от команды AdGuard, который берет на себя роль локального DoH-апстрима.

Преимущества связки Unbound + dnsproxy.

  • Обход блокировок и инспекции трафика: Запросы инкапсулируются в стандартные HTTPS-сессии, неотличимые от посещения обычных веб-сайтов.

  • Сохранение локального DNSSEC и кэширования: Unbound продолжает валидировать цепочки доверия и отдавать локальные зоны, передавая во внешний мир только зашифрованные запросы.

  • Отказоустойчивость: Возможность одновременного использования нескольких независимых DoH-резолверов (Quad9, Cloudflare) с резервированием через Bootstrap DNS.

Пошаговая установка и настройка.

1. Автоматическое развертывание службы через Shell.

Подключитесь к pfSense по SSH (выбрав пункт 8 — Shell) и выполните скрипт установки. Скрипт скачивает релиз dnsproxy для FreeBSD, размещает бинарный файл в /usr/local/bin/ и создает rc-службу /usr/local/etc/rc.d/dnsproxy.sh.

#!/bin/sh
set -e
VERSION="v0.84.1"
ARCH="freebsd-amd64"
DOWNLOAD_URL="https://github.com/AdguardTeam/dnsproxy/releases/download/${VERSION}/dnsproxy-${ARCH}-${VERSION}.tar.gz"
WORK_DIR="/tmp/dnsproxy_install"
BIN_TARGET="/usr/local/bin/dnsproxy"
SERVICE_SCRIPT="/usr/local/etc/rc.d/dnsproxy.sh"
echo "=== [1/5] Скачивание и распаковка dnsproxy ${VERSION} ==="
mkdir -p "$WORK_DIR"
curl -sL "$DOWNLOAD_URL" -o "$WORK_DIR/dnsproxy.tar.gz"
tar -xzf "$WORK_DIR/dnsproxy.tar.gz" -C "$WORK_DIR"
echo "=== [2/5] Установка бинарного файла в $BIN_TARGET ==="
if [ -f "$WORK_DIR/${ARCH}/dnsproxy" ]; then
    mv -f "$WORK_DIR/${ARCH}/dnsproxy" "$BIN_TARGET"
else
    mv -f "$WORK_DIR/dnsproxy" "$BIN_TARGET"
fi
chmod +x "$BIN_TARGET"
rm -rf "$WORK_DIR"
echo "=== [3/5] Создание службы управления $SERVICE_SCRIPT ==="
cat << 'EOS' > "$SERVICE_SCRIPT"
#!/bin/sh
PIDFILE="/var/run/dnsproxy.pid"
LOGFILE="/var/log/dnsproxy.log"
case "$1" in
  start)
    if [ -f "$PIDFILE" ] && kill -0 $(cat "$PIDFILE") 2>/dev/null; then
      echo "dnsproxy already running (PID: $(cat $PIDFILE))"
      exit 0
    fi
    echo "Starting dnsproxy DoH upstream..."
    /usr/sbin/daemon -f -p "$PIDFILE" -o "$LOGFILE" /usr/local/bin/dnsproxy \
      -l 127.0.0.1 -p 5353 \
      -u https://dns.quad9.net/dns-query \
      -u https://cloudflare-dns.com/dns-query \
      -b 1.1.1.1:53 -b 1.0.0.1:53 \
      --cache \
      --cache-size=65536
    ;;
  stop)
    if [ -f "$PIDFILE" ]; then
      echo "Stopping dnsproxy..."
      kill $(cat "$PIDFILE") 2>/dev/null && rm -f "$PIDFILE"
    else
      echo "dnsproxy is not running"
    fi
    ;;
  status)
    if [ -f "$PIDFILE" ] && kill -0 $(cat "$PIDFILE") 2>/dev/null; then
      echo "dnsproxy is running (PID: $(cat $PIDFILE))"
    else
      echo "dnsproxy is stopped"
    fi
    ;;
  restart)
    $0 stop
    sleep 1
    $0 start
    ;;
  *)
    echo "Usage: $0 {start|stop|restart|status}"
    exit 1
    ;;
esac
EOS
chmod +x "$SERVICE_SCRIPT"
echo "=== [4/5] Запуск службы dnsproxy ==="
"$SERVICE_SCRIPT" restart
echo "=== [5/5] Тест работы DoH-прокси ==="
sleep 2
if drill @127.0.0.1 -p 5353 cloudflare.com | grep -q "NOERROR"; then
    echo "========================================================"
    echo " УСПЕХ: dnsproxy успешно запущен и отвечает на 127.0.0.1:5353"
    echo "========================================================"
else
    echo "ВНИМАНИЕ: Тестовый запрос не вернул NOERROR. Проверьте /var/log/dnsproxy.log"
fi

Служба автоматически слушает локальный порт 127.0.0.1:5353, производит первичное разрешение DoH-серверов через bootstrap DNS (1.1.1.1:53) и кэширует до 65 536 записей

2. Настройка DNS Resolver в WebGUI pfSense.

Перейдите в веб-интерфейс pfSense по пути Services → DNS Resolver → General Settings:

  • Enable DNS Resolver: Включено (Checked).

  • Enable Forwarding Mode: Включено (Checked) — переводит Unbound в режим пересылки запросов.

  • Use SSL/TLS for outgoing DNS Queries: Выключено (Unchecked) — так как шифрование по HTTPS берет на себя локальный dnsproxy.

  • Enable DNSSEC Support: Включено (Checked).

В самом низу страницы найдите поле Custom Options и добавьте конфигурацию пересылки на локальный порт 5353:

server:
  do-not-query-localhost: no
forward-zone:
  name: "."
  forward-addr: 127.0.0.1@5353

Нажмите Save и примените изменения кнопкой Apply Changes.

Проверка и валидация DNSSEC.

После перезапуска резолвера проверьте корректность обработки запросов и валидацию цифровых подписей DNSSEC прямо из терминала pfSense.

# 1. Проверка валидного домена (в ответе должны присутствовать флаг 'ad' и секция RRSIG)
drill -D @127.0.0.1 cloudflare.com
# 2. Проверка тестовой сломанной зоны (Unbound обязан заблокировать резолв и вернуть статус SERVFAIL)
drill -D @127.0.0.1 dnssec-failed.org

Если второй запрос возвращает rcode: SERVFAIL, значит, цепочка безопасности выстроена корректно: корпоративный сегмент защищен от подмены DNS-ответов и компрометации внешнего трафика.

Компания «Эдвелс Автоматизация» проектирует и внедряет цифровые системы и решения промышленной автоматизации под ключ. Свяжитесь с нами для проведения технологического аудита и расчета окупаемости модернизации вашего предприятия.

Ваш заказ
  • image alt
    POWER Full 14
    POWER Full 14
    1000
  • image alt
    POWER Full 14
    POWER Full 14
    2000
3000
Выберите вариант доставки
2