Docker не разрешает DNS с сервера BIND.

Вопрос или проблема

Я пытаюсь использовать контейнер Docker в качестве локального DNS-сервера для переписывания IP-адреса существующего домена внутри частной сети.

Моя настройка заключается в том, что у меня есть частная сеть с несколькими машинами и маршрутизатором, который имеет общедоступный IP-адрес. Одна из этих машин обслуживает некоторый контент в интернете под доменом (например, example.com), который указывает на публичный IP, при этом порт маршрутизируется от маршрутизатора к этой машине. Дело в том, что другим машинам в частной сети также нужен доступ к этому серверу. Однако маршрутизатор блокирует пакеты, исходящие изнутри, от доступа к публичному IP. Поэтому я подумал, что использую этот контейнер в качестве локального DNS-сервера, чтобы переписать этот публичный IP на локальный.

В общем, вот эта сеть:

  • Ubuntu-машина с IP 192.168.1.6 ~> узел Docker
  • Ubuntu-машина с IP 192.168.1.4 ~> узел контента для example.com
  • другие машины с диапазоном IP 192.168.1.0/8
  • DNS-сервер всех машин настроен на 192.168.1.6

Теперь BIND настроен с использованием этого compose-файла:

version: '2'

services:
  bind:
    image: sameersbn/bind:latest
    restart: always
    dns: 8.8.8.8
    logging:
      driver: "json-file"
      options:
        max-size: "200k"
        max-file: "10"
    environment:
        - ROOT_PASSWORD=somepass
    ports:
      - 10000:10000
      - 53:53/udp
    volumes:
      - ./data:/data

и имеет такую конфигурацию:

acl localclients {
    192.168.0.0/16;
    172.17.0.0/16;
    172.23.0.0/16;
    localhost;
    localnets;
};

options {
    directory "/var/cache/bind";
    dnssec-validation auto;

    auth-nxdomain no;
    listen-on-v6 { any; };
    listen-on {
        any;
        };

    recursion yes;

    allow-query { any; };
    allow-recursion {
        localclients;
        };
    allow-query-cache { localclients; };
}

В настоящее время запрос имени домена на хост-машине Docker (с IP 192.168.1.6), а также на других машинах в той же сети (IP 192.168.1.x) работает как ожидается:

$ nslookup example.com
Server:     192.168.1.6
Address:    192.168.1.6#53

Name:   example.com
Address: 192.168.1.4

но я не могу использовать это в другом контейнере:

$ docker run --rm busybox nslookup example.com
Server:    192.168.1.6
Address 1: 192.168.1.6 servername

Name:      example.com
Address 1: 188.15.221.88

когда я принуждаю использовать только локальный DNS-сервер, я получаю следующий вывод:

$ docker run --rm --dns 192.168.1.6 busybox nslookup example.com
nslookup: can't resolve 'example.com'
Server:    192.168.1.6
Address 1: 192.168.1.6

Я не уверен, является ли это проблемой Docker или конфигурацией BIND.

ну это не ответ, а скорее решение, которое я нашел, так что я не буду отмечать его как ответ.

Я не смог найти каких-либо решений для этого, возможно, это ошибка Docker, возможно, (странная) желаемая функциональность. Однако, так как мне действительно нужно было найти решение, я использовал --add-host для команды run и extra-hosts в файлах compose, чтобы преодолеть эту проблему.

Решение на основе “–net=host”

Одним из вариантов было бы запустить второй Docker с --net=host. Тогда --dns 192.168.1.6 должен работать, потому что второй Docker имеет ту же сетевую конфигурацию, что и хост.

Решение на основе “пользовательской мостовой сети”

  1. Создайте пользовательскую сеть Docker типа bridge с фиксированной подсетью (это делает возможным установку статических IP адресов для контейнеров):

    docker network create --subnet=172.18.0.0/24 dns-network
    
  2. Запустите “dns docker контейнер”, открывая DNS-порт 53 и подключая его к сети Docker:

    docker run --publish 53:53 --net=dns-network --ip 172.18.0.53 sameersbn/bind:latest
    
  3. Запустите другой Docker-контейнер и настройте 172.18.0.53 как DNS-сервер:

    docker run --dns=172.18.0.53  --net=dns-network busybox nslookup example.com
    

Ответ или решение

Решение проблемы с разрешением DNS через BIND сервер в Docker

Вы столкнулись с проблемой доступа к домену example.com в контейнере Docker, где должен использоваться локальный DNS-сервер для перенаправления запросов внутри частной сети. Обратите внимание, что проблема заключается в разрешении имен внутри другого Docker-контейнера и попытке установить связь с частной сетью через локальный DNS.

Анализ проблемы

  1. Четыре основных элемента настройки:

    • У вас есть частная сеть, где некоторые машины (включая Docker-хост) должны разрешать example.com через локальный DNS-сервер (BIND).
    • DNS-сервер, работающий в контейнере на Docker-хосте с IP 192.168.1.6.
    • Сервер контента example.com на устройстве с IP 192.168.1.4.
    • Проблема возникает при попытке разрешения DNS-запросов внутри Docker-контейнеров.
  2. Особенности Docker:

    • При запуске контейнера Docker, он может использовать отдельную сеть по умолчанию, что не всегда позволяет ему обращаться к вашей сети для разрешения имен или использовать локальный BIND-сервер из контейнера.

Предложенные решения

  1. Использование параметра --net=host:

    • Запуск контейнера с помощью --net=host позволит контейнеру использовать сетевой стек хоста, тем самым использовав DNS-сервер хоста для разрешения. Однако это влечет за собой потерю изоляции сети, что может быть критично в некоторых сценариях.
  2. Настройка пользовательской сети bridge:

    • Создайте мостовую сеть с фиксированным подсетью:
      docker network create --subnet=172.18.0.0/24 dns-network
    • Запустите BIND контейнер в этой сети с конкретным IP:
      docker run --publish 53:53 --net=dns-network --ip 172.18.0.53 sameersbn/bind:latest
    • При запуске других контейнеров, например, с busybox, укажите использование этой сети и DNS-сервера:
      docker run --dns=172.18.0.53 --net=dns-network busybox nslookup example.com

Профессиональные рекомендации

  • Проверка конфигураций: Убедитесь, что BIND сервер правильно настроен для прослушивания 53 порта и обработки запросов от всех потенциальных клиентов в вашей сети.

  • Настройка доступа: Проверьте ACL (Access Control List) в конфигурации BIND, чтобы разрешить доступ для всех необходимых подсетей, включая подсетку пользовательской мостовой сети.

  • Логирование и диагностика: Используйте логи Docker и BIND для диагностики проблем. Это может помочь выявить отсутствие доступа к DNS-серверу или любые другие потенциальные ошибки в конфигурации.

Работая с Docker и сетевой изоляцией, важно учитывать, как контейнеры взаимодействуют друг с другом и с хостовой системой. Подходы, указанные выше, дают возможность гибко настраивать взаимодействие через DNS внутри Docker-контейнеров с использованием различных методов.

Оцените материал
Добавить комментарий

Капча загружается...