dadv: (chuck)
Choose your future ([personal profile] dadv) wrote2016-10-04 11:28 am
Entry tags:

DNS, NAT и проброс портов

Стандартная ситуация: локальная сеть с маршрутизатором, один публичный IP, для выхода в мир используется NAT. Плюс на маршрутизаторе работает кеширующий DNS-сервер для локальной сети. Всё работает.

Однажды на одном из хостов локальной сети поселяется сервис, которому требуется пробросить статический диапазон портов UDP с внешнего IP. Казалось бы, какие могут быть проблемы?

А ведь DNS-сервер, выполняя запросы к внешним серверам, для исходящих запросов сам использует динамические UDP-порты и ожидает ответ на них. Например, ISC BIND под FreeBSD использует sysctl net.inet.ip.portrange.hifirst и net.inet.ip.portrange.hilast для определения диапазона таких эфемерных портов, по умолчанию это 49152-65535. Пока этот диапазон не пересекается с диапазоном проброшенных внутрь локалки портов, всё будет в порядке. Но стоит лишь пробросить, скажем, порты 40000-65535, и наступает катастрофа. В случае FreeBSD проброс портов "имеет приоритет выше" (выполняется раньше, чем доставка локальным приложениям) и проброс-то работать будет, но DNS-сервер остается без DNS-ответов на свои запросы, которые теперь уходят по пробросу локальному хосту, которому они и не нужны вовсе. И вся локальная сеть остаётся без локального DNS-сервиса.

Решением будет либо изменить диапазон проброшенных портов, если это допустимо для сервера в локальной сети, а если нет - изменить диапазон эфемерных портов для DNS-сервера. Кроме изменения системного дефолта, ISC BIND позволяет задать этот диапазон в собственной конфигурации:

use-v4-udp-ports { range 10000 30000; };

Аналогично для IPv6. Для защиты от некоторых типов атак, BIND каждый раз выбирает случайный порт из диапазона и рекомендуется, чтобы диапазон был достаточно большим, минимум 16384 портов (14 бит энтропии).

[identity profile] filonov.livejournal.com 2016-10-04 05:52 am (UTC)(link)

А не пробрасывать udp с src port 53 не проще будет?

[identity profile] dadv.livejournal.com 2016-10-04 08:51 am (UTC)(link)
Тоже вариант (c)
Но развести по непересекающимся диапазонам мне как-то больше нравится.

[identity profile] http://users.livejournal.com/_slw/ 2016-10-04 09:04 am (UTC)(link)
нет
многие сервера уже более 5 лет как блокируют запросы с порта 53

[identity profile] filonov.livejournal.com 2016-10-04 09:07 am (UTC)(link)
Огласите пожалуйста полный список серверов блокирующих ответы внешних DNS-серверов на свои же DNS-запросы. Мне чисто поржать.

[identity profile] http://users.livejournal.com/_slw/ 2016-10-04 09:22 am (UTC)(link)
я же сказал "запросы", а не "ответы", что тут непонятно?
ip тех серверов, что стали фильтровать такие запросы я не записывал. это было не повально, но достаточно для того, что бы мне пришлось убирать опцию query-source address * port 53;

[identity profile] filonov.livejournal.com 2016-10-04 09:23 am (UTC)(link)
я же сказал "запросы", а не "ответы", что тут непонятно?
Непонятно, какое это имеет отношение к предмету обсуждения.

[identity profile] http://users.livejournal.com/_slw/ 2016-10-04 09:27 am (UTC)(link)
"DNS-сервер, выполняя запросы к внешним серверам, для исходящих запросов сам использует динамические UDP-порты и ожидает ответ на них."

ну вот же.

[identity profile] dadv.livejournal.com 2016-10-04 09:29 am (UTC)(link)
В посте речь идёт о (не)форварде приходящих ответов.

[identity profile] http://users.livejournal.com/_slw/ 2016-10-04 09:32 am (UTC)(link)
у тебя (в некоторых случаях) нечего будет форвардить если ты будешь делать запросы с src_port=53.

[identity profile] dadv.livejournal.com 2016-10-04 09:37 am (UTC)(link)
Но ведь это уже второй вопрос, профессор.

[identity profile] http://users.livejournal.com/_slw/ 2016-10-04 09:39 am (UTC)(link)
нет. это исходный вопрос: "многие сервера уже более 5 лет как блокируют запросы с порта 53"

[identity profile] dadv.livejournal.com 2016-10-04 09:42 am (UTC)(link)
И этот вопрос - второй, другой. Не та проблема, о которой речь в посте.

[identity profile] filonov.livejournal.com 2016-10-04 09:30 am (UTC)(link)
Там дальше еще DNS-сервер остается без DNS-ответов на свои запросы, которые теперь уходят по пробросу локальному хосту

[identity profile] filonov.livejournal.com 2016-10-04 09:35 am (UTC)(link)
Проблем с DNS-запросами, очевидно, не наблюдается.

[identity profile] http://users.livejournal.com/_slw/ 2016-10-04 09:38 am (UTC)(link)
а почему она должна быть?
проблема будет с отсутвием ответов от некоторых серверов, если делать запросы с порта 53.

[identity profile] filonov.livejournal.com 2016-10-04 09:39 am (UTC)(link)
Это совсем другая проблема.

PS: Слава, уболтал, ты зануднее :)

[identity profile] http://users.livejournal.com/_slw/ 2016-10-04 09:41 am (UTC)(link)
да как же другая, если именно про это я и сказал?
http://dadv.livejournal.com/207897.html?thread=844569&style=mine#t844569

а, я тебя прочитал неправильно.
всё равно у тебя плохой вариант -- из локалки нельзя будет к внешним dns серверам обращаться, даже для тестирования.

[identity profile] filonov.livejournal.com 2016-10-04 09:47 am (UTC)(link)
всё равно у тебя плохой вариант -- из локалки нельзя будет к внешним dns серверам обращаться, даже для тестирования.
То, что мы не пробрасываем определенные пакеты, не отменяет обычной работы NAT.

[identity profile] http://users.livejournal.com/_slw/ 2016-10-04 09:50 am (UTC)(link)
ты такой загадочный...
можешь более конкретно высказаться?

[identity profile] filonov.livejournal.com 2016-10-04 09:53 am (UTC)(link)
А что собственно мешает "из локалки к внешним dns серверам обращаться"?

[identity profile] dadv.livejournal.com 2016-10-04 09:57 am (UTC)(link)
Он имеет в виду, что NAT engine для входящих пакетов сначала ищет существующий максимально специфичный стейт и если он есть, то транслирует пакет по нему. Таким образом, трансляция для ответов на запросы из локалки будет выполнена. И только если такого стейта нет, трансляция идёт по менее специфичному стейту, созданному статическим правилом форвардинга портов, в котором не специфицирован порт источника. И вот NAT теоретически мог бы на этом этапе проверить, а не равен ли порт источника 53 в случае udp и если да - выпустить пакет без трансляции и тогда он доставился бы локально.

Практически ipfw nat такого не умеет.

[identity profile] filonov.livejournal.com 2016-10-04 10:15 am (UTC)(link)
ipfw nat надо два nat instance - один для проброса портов, второй для остального траффика.
Впрочем могу ошибаться - я туда уже лет десять не смотрел.
У pfnat все проще -
rdr on $ext_if proto udp from any port != 53 to ....
Edited 2016-10-04 10:26 (UTC)

[identity profile] dadv.livejournal.com 2016-10-04 10:37 am (UTC)(link)
Да, верно, если вынести портфорвардинг во второй инстанс и отключить однопроходность - сработает и c ipfw nat, хотя и громоздко вышло бы.

[identity profile] dadv.livejournal.com 2016-10-04 09:11 am (UTC)(link)
Речь про форвардинг *DNS-ответов* с серверного порта 53.

[identity profile] dadv.livejournal.com 2016-10-04 09:20 am (UTC)(link)
(безотносительно к форварду DNS-ответов)

Что это за "многие" сервера, что блокируют DNS-запросы с порта-источника 53?

[identity profile] http://users.livejournal.com/_slw/ 2016-10-04 09:24 am (UTC)(link)
да вот наконфигуряли какие-то админы в свое время.
я ip не записывал, но наткнулся -- не мог отресолвить какие-то домены -- ответы на мои запросы не приходили