Переопределение некоторых записей DNS в BIND для внутренних сетей

39

У меня есть внутренняя сеть с DNS-сервером под управлением BIND, подключенным к Интернету через один шлюз. Мой домен "example.com" управляется внешним поставщиком DNS. Некоторые записи в этом домене, например, «host1.example.com» и «host2.example.com», а также запись верхнего уровня «example.com», указывают на публичный IP-адрес шлюза.

Я хотел бы, чтобы узлы, расположенные во внутренней сети, разрешали «host1.example.com», «host2.example.com» и «example.com» во внутренние IP-адреса вместо адреса шлюза. Другие хосты, такие как «otherhost.example.com», должны разрешаться внешним DNS-провайдером.

Мне удалось сделать это для записей host1 и host2, определив две зоны с одним входом в BIND для «host1.example.com» и «host2.example.com». Однако, если я добавлю зону для «example.com», все запросы для этого домена будут решены моим локальным DNS-сервером, и, например, запрос «otherhost.example.com» приведет к ошибке.

Можно ли настроить BIND так, чтобы он переопределял только некоторые записи домена, а остальное разрешал рекурсивно?

Реми Бланк
источник
Аналогичный вопрос: serverfault.com/questions/8694/…
MikeyB
1
«Можно ли настроить BIND для переопределения только некоторых записей домена?» Нет, не с BIND. Используйте поддомен.
bortzmeyer
1
Unbound, кажется, делает именно то, что я просил, поэтому я устанавливаю ответ Alnitak как принятый ответ. Но, в конце концов, я собираюсь последовать совету борцмейера и не отменять запись домена. Спасибо за все отклики!
Реми Бланк
1
Теперь Bind может сделать это с зоной политики ответа. Смотрите мой ответ ниже. Другие решения, такие как Unbound, не могут переопределить CNAME. С зонами политики в Bind вам не нужно создавать поддоменов; Вы можете просто переопределить отдельные записи по желанию.
Флорин Андрей

Ответы:

18

Лучший способ - через зону политики ответа в Bind 9.8.1 или новее. Он позволяет вам переопределять отдельные записи в произвольных зонах (и для этого не нужно создавать целый поддомен, только одну запись, которую вы хотите изменить), он позволяет переопределять CNAME и т. Д. Другие решения, такие как Unbound, не могут переопределять CNAME. ,

https://www.redpill-linpro.com/sysadvent/2015/12/08/dns-rpz.html


РЕДАКТИРОВАТЬ: Давайте сделаем это правильно тогда. Я задокументирую то, что я сделал, основываясь на учебнике, указанном выше.

Моя ОС - Raspbian 4.4 для Raspberry Pi, но метод должен работать без изменений в Debian и Ubuntu или с минимальными изменениями на других платформах.

Перейдите туда, где хранятся ваши файлы конфигурации Bind в вашей системе - здесь он находится /etc/bind. Создайте там файл db.rpzс таким содержимым:

$TTL 60
@            IN    SOA  localhost. root.localhost.  (
                          2015112501   ; serial
                          1h           ; refresh
                          30m          ; retry
                          1w           ; expiry
                          30m)         ; minimum
                   IN     NS    localhost.

localhost       A   127.0.0.1

www.some-website.com    A        127.0.0.1

www.other-website.com   CNAME    fake-hostname.com.

Что оно делает?

  • он переопределяет IP-адрес www.some-website.comс помощью поддельного адреса 127.0.0.1, эффективно отправляя весь трафик для этого сайта на адрес обратной связи
  • он отправляет трафик на www.other-website.comдругой сайт под названиемfake-hostname.com

Все, что можно поместить в файл зоны Bind, вы можете использовать здесь.

Для активации этих изменений есть еще несколько шагов:

Отредактируйте named.conf.localи добавьте этот раздел:

zone "rpz" {
  type master;
  file "/etc/bind/db.rpz";
};

В приведенном выше руководстве рассказывается о том, как добавить больше материала, zone "rpz" { }но в простых установках это не нужно - я показал здесь минимум, чтобы заставить его работать на вашем локальном преобразователе.

Отредактируйте named.conf.optionsи где-нибудь в options { }разделе добавьте response-policyопцию:

options {
  // bunch
  // of
  // stuff
  // please
  // ignore

  response-policy { zone "rpz"; };
}

Теперь перезапустите Bind:

service bind9 restart

Вот и все. Сервер имен должен начать переопределять эти записи сейчас.

Если вам нужно внести изменения, просто отредактируйте db.rpz, а затем перезапустите Bind снова.

Бонус: если вы хотите регистрировать DNS-запросы в системном журнале, чтобы вы могли следить за ходом работы, отредактируйте named.conf.localи убедитесь, что есть loggingраздел, который включает эти утверждения:

logging {
    // stuff
    // already
    // there

    channel my_syslog {
        syslog daemon;
        severity info;
    };
    category queries { my_syslog; };
};

Перезапустите Bind снова и все.

Проверьте это на машине, на которой запущен Bind:

dig @127.0.0.1 www.other-website.com. any

Если вы запускаете dig на другом компьютере, просто используйте @ the-ip-address-of-Bind-server вместо @ 127.0.0.1

Я с большим успехом использовал эту технику, чтобы переопределить CNAME для веб-сайта, над которым я работал, и отправить его на новый балансировщик нагрузки AWS, который я только что тестировал. Raspberry Pi использовался для запуска Bind, а RPi также был настроен для работы в качестве маршрутизатора WiFi - поэтому, подключая устройства к SSID, работающему на RPi, я получал переопределения DNS, необходимые для тестирования.

Флорин андрей
источник
1
Обратите внимание, что BIND RPZ на самом деле (пока) не может переопределить отдельные записи для каждого QTYPE - он переопределит все записи для конкретного имени владельца. Это означает, что если вы хотите переопределить запись A для домена, но не, например, запись MX, вы не сможете. Вы также должны поместить запись MX в зону RPZ и синхронизировать ее с реальной зоной.
Альнитак
2
Спасибо, что сломал это, как ты. Очень полезно.
Sruffell
Есть ли какие-то предостережения? Я пытаюсь сделать это на pfsense, но я не могу «подделать» никаких результатов, он по-прежнему сообщает реальный адрес. Я считаю, что я следовал инструкциям к письму.
Ленн
@ Ленна Это должно сработать. Я отредактировал пост и добавил предложение для тестирования изменений.
Флорин Андрей
@Lenne Пакет pfSense BIND уже встроен в GUI уже около года, поэтому не нужно выполнять копирование с помощью конфигов. OP: возможно, стоит упомянуть о некоторых других вещах, которые вы можете сделать с RPZ, таких как ответ с помощью NXDOMAIN или просто отбрасывание ответа.
miken32
21

Несвязанный рекурсивный сервер DNS имеет возможность переопределить отдельные записи ресурсов.

Посмотрите на local-zoneи local-dataнастройки конфигурации в руководстве , например:

local-zone: "example.com." transparent
local-data: "foo.example.com. IN A 192.168.1.1"

Параметр в transparentнастройках local-zoneзаставляет его выполнять обычный рекурсивный поиск для любых имен, не входящих в local-data.

Альнитак
источник
1
Кажется, именно то, что я хочу сделать, спасибо. Я прочитаю на Unbound сегодня вечером.
Реми Бланк
С другой стороны, мудрость этого весьма сомнительна. Наличие внутреннего домена .example.com будет более понятным.
bortzmeyer
@Bortzmeyer - вы могли бы быть правы, но я не думаю, что Воутер вставил это просто для удовольствия ;-)
Альнитак
3
@bortzmeyer, иногда нет выбора. Пример: SBS 2008 должен иметь один IP-адрес локальной сети, однако к нему необходимо подключиться извне, используя внешний IP-адрес, который маршрутизирует маршрутизатор. Microsoft не разрешает использование двух сетевых карт на SBS и двух IP-адресов на одной карте. Если локальные серверы разрешают DNS-имя для внешнего IP-адреса, маршрутизатору необходимо выполнить DNAT и SNAT для IP-адресов локальной сети, а затем в журналах SBS будет отображаться весь доступ с IP-адреса маршрутизатора, и это просто неправильно. Я установлю unboundна свой роутер, думаю, решение намного лучше.
Cosmin Prund
Это не отвечает на вопрос, так как вопрос специфичен для BIND.
bzeaman
4

Возможно, вы захотите взглянуть на «dnsmasq», который позволяет вам делать довольно умные вещи с тонкой настройкой разрешения.

Люк
источник
Спасибо, хороший совет. Жаль, что dnsmasq не выполняет рекурсивное разрешение, поэтому мне все равно придется запускать BIND для другого порта для этого (DNS-серверы моего провайдера не работают).
Реми Бланк
4

То, что вы ищете, это разделенный DNS, который определяется Webopedia как:

В раздельной инфраструктуре DNS вы создаете две зоны для одного домена, одну для внутренней сети, а другую для внешней сети. Разделенный DNS направляет внутренние хосты на внутренний сервер доменных имен для разрешения имен, а внешние хосты направляются на внешний сервер доменных имен для разрешения имен.

По сути, вам нужно будет сделать копию файла внешней зоны и сохранить ее на своем внутреннем DNS-сервере, а затем изменить или добавить записи, необходимые специально для вашей внутренней сети. Это довольно распространенная настройка, хотя может быть очень сложно синхронизировать «внешние» записи между двумя DNS-серверами. Если вы создаете или изменяете запись на общедоступном сервере, ее также необходимо будет создать или изменить на частном сервере.

Это может быть реализовано независимо от того, какую реализацию DNS-сервера вы используете. В большинстве случаев у вас будет один DNS-сервер, который обслуживает внешнюю сеть, и другой, который обслуживает внутреннюю сеть. С помощью BIND, как и, возможно, других реализаций, вы можете иметь обе версии зоны на одном и том же сервере с помощью оператора «allow-query» в разделе зоны файла named.conf.

Другая возможность в BIND (и я никогда не пробовал этого) состояла бы в том, чтобы установить домен example.com на внутреннем DNS-сервере только с теми записями, которые вы используете для внутреннего использования. Затем установите оператор «forward» с аргументом «first» (в сочетании с «forwarders»). Теоретически, для этого нужно запросить ответ у внешнего DNS-сервера (как установлено в «серверах пересылки», который не будет содержать ваши внутренние записи и не даст ответ о сбое. Затем внутренний сервер сам ищет ответ. Не конечно, если это сработает, но это мысль.

Джастин скотт
источник
Синхронизация двух файлов зон будет затруднена, поскольку внешний обновляется через динамический DNS-клиент. Я прочитаю предварительное заявление, хотя. Спасибо за совет.
Реми Бланк
Нет, пересылка BIND не будет работать, это будет только для неизвестных доменов, но внутренний сервер имен будет знать о example.com, он будет уполномоченным для этого.
bortzmeyer
1
Если я правильно читаю документацию, оператор «forward first» в разделе зоны должен указать BIND выйти и искать ответ у сервера пересылки даже для авторитетного локального домена, а затем использовать локальную информацию, только если это возможно » получить ответ от экспедитора.
Джастин Скотт
Если вы поставите глобальное «вперед вперед», «оно отправит запросы серверу пересылки и, если не ответит, попытается ответить на запрос» (из документа), но если оно получит ответ, оно не будет пытаться разрешить себя. Было бы здорово, если бы вы могли принудительно разрешить, если ответ не является официальным или даже если это NXDOMAIN, но bind не будет пытаться получить ответ от сервера пересылки.
Пабло Мартинес
3

В BIND я добираюсь до этих результатов, определяя зону, используя желаемое имя хоста. Подход хорош, если вы хотите переопределить только несколько хостов.

Моя декларация зоны выглядит так:

zone "override.example.com" {
        type master;
        notify no;
        file "zone-config/override.example.com";
};

Мое определение зоны выглядит так:

$TTL 4H
@       IN      SOA     ns.override.example.com.    root.override.example.com. (
                        2009072215      ; Serial
                        3600            ; Refresh
                        600             ; Retry
                        604800          ; Expire
                        3600    )       ; Minimum
;
                NS      ns
        IN      NS      ns.override.example.com.
        IN      A       192.168.1.100
ns      IN      A       192.168.1.100

Поэтому, если я запрашиваю example.com в интрасети DNS и DNS провайдера, я получаю один и тот же IP-адрес, но если я запрашиваю override.example.com, я получаю разные результаты, если интрасеть DNS (основной) доступна.

Срджан
источник
2

Вы уже на правильном пути.

На ваших внутренних DNS-серверах вам нужно определить зону для каждого узла исключения сразу под "example.com". Чтобы свести к минимуму эти исключения, обычной практикой является присвоение имен всем внутренним компьютерам "hosta.internal.example.com", при этом DNS-сервер отправляет большинство запросов на внешние DNS-серверы, но является доверенным для зоны "internal.example.com". (После выполнения небольших операций обычно существует два DNS-сервера, на которые направляются клиенты, и отдельный авторитетный DNS-сервер, на который эти серверы направляются для «internal.example.com».)

Обычно, только когда хост должен быть доступен как снаружи, так и внутри, создаются исключения, которые вы описываете. Даже тогда вы можете использовать «host1.example.com» извне и «host1.internal.example.com» изнутри. Внутренние хосты настроены на поиск имен в "internal.example.com". Существуют ситуации, когда то, что вы уже делаете, подходит, например, если сертификат для сервера идентифицирует сервер как «host1.example.com», и в этом случае вы хотите, чтобы это было имя, к которому подключаются клиенты.


источник
Да, для хостов "host1.example.com" он уже работает хорошо. Хитрая часть обрабатывает "example.com" верхнего уровня таким же образом ...
Реми Бланк
2

Использование dnsmasq делает это действительно легко. http://www.thekelleys.org.uk/dnsmasq/doc.html Действует как сервер DNS, но получает ответы от локального сервера DNS. Приятно то, что вы можете переопределить отдельные записи домена, не связываясь с файлами зон


источник
2

На самом деле, есть другой, хотя, возможно, немного иной, способ сделать это. У меня такая же ситуация, у меня есть домен, который используется снаружи и внутри, и у меня есть внешние статические и динамические хосты. Единственными действительно болезненными являются внешние динамические. Решение, возможно, не самое элегантное, но реализуемое с помощью небольшого сценария. В основном я делаю свой собственный динамический DNS-скрипт с API моего динамического DNS-провайдера, я запускаю этот скрипт по cron, каждые 5 минут:

1) получить мой внешний IP. это изменилось? нет выхода.

2) изменили IP, вызовите API dyndns-провайдера, с новым IP-адресом,

3) sed the db.mydomain.com с внешним IP

4) перезапустите привязку.

Работает очень надежно для моей домашней сети

Nico
источник
Тот же процесс, сделанный мной. подробности вы найдете на нашем вики- сервере Stealth Name . Но не в состоянии решить dyn.dev.shahed.bizот World Wide! Не могли бы вы помочь нам решить эту проблему?
Шахед Хоссейн