Назад | Перейти на главную страницу

Как я могу отклонить все входящие UDP-пакеты, кроме DNS-запросов?

Я настроил свой сервер на отклонение ВСЕХ входящих пакетов UDP, чтобы предотвратить наводнение UDP. Однако мне сказали, что, поскольку я использую свой собственный домен и сервер для своих серверов имен, это может вызвать некоторые проблемы. Как я могу это обойти?

Мой брандмауэр - iptables, мой дистрибутив - CentOS5.5.

Если вы следуете стандартным методам безопасности, ваша политика брандмауэра по умолчанию будет блокировать все. Все, что вам нужно сделать, это написать правило, разрешающее трафик tcp и udp на порт 53, если вы хотите разрешить входящие запросы DNS.

Трафик, о котором вы говорите, - это UDP. UDP не имеет состояния. Это означает, что люди, заинтересованные в насыщении вашего соединения, могут отправлять пакеты на ваш адрес, даже если вы их просто отбрасываете. Тем не менее, вы можете сделать что-то полу-полезное с последним совпадением iptables, чтобы разрешить только ограниченный объем трафика, который фактически принимается и обрабатывается системой. У Эвана есть пример использование этого для SSH Вот. Возможно, нам придется просмотреть весь ваш набор правил брандмауэра, чтобы сообщить вам, какие правила нужно добавить.

Если у вас есть серьезный DoS против вашей системы, вам почти наверняка понадобится помощь вашего интернет-провайдера, попытка справиться с наводнением с помощью брандмауэра на основе хоста на VPS действительно не будет очень полезна.

Если у вас его еще нет, вам следует подумать о настройке нескольких вторичных DNS-серверов для ваших зон в совершенно другой сети.

В Iptables принимайте входящий UDP-трафик на порт 53 и отклоняйте все в диапазоне портов для эфемерных портов.

Максимальный предел не должен быть слишком высоким, иначе ваш сервер не сможет разрешить внешние домены (например, когда вы выполните «ping google.com») изнутри вашего сервера. В ОС Linux 32768 - это первый эфемерный порт (также известный как динамические порты) для сокетов до 61000. Таким образом, 32767 - это самый высокий порт для статически выделенных портов. Это верно только в том случае, если вы не используете свой сервер в качестве преобразователя DNS, также известного как DNS-кеш, или сервер с файлом /etc/resolv.conf, указывающим на сервер имен 127.0.0.1 или :: 1

Вот пример tcpdump:

 23:10:13.315832 IP b.b.b.b.34507 > a.a.a.a.53: 23674% [1au] A? whitehouse.gov. (38)
 23:10:13.377619 IP a.a.a.a.53 > b.b.b.b.34507: 23674*- 1/2/3 A 172.230.122.69(122)
  1. b.b.b.b запрашивает сервер имен a.a.a.a с порта 34507, чтобы предоставить запись A для whitehouse.gov на порт 53
  2. a.a.a.a из порта 53 отвечает b.b.b.b на порт 34507

Обычно, чтобы найти локальные динамические (также называемые эфемерными или частными) диапазоны портов в Linux для UDP и TCP:

 cat /proc/sys/net/ipv4/ip_local_port_range

Однако это работает только для серверов, на которых нет DNS-преобразователя (например, когда вы указываете свой /etc/resolv.conf на 8.8.8.8).

Сервер не является преобразователем DNS:

 -A INPUT -p udp -m udp --dport 53 -j ACCEPT
 -A INPUT -p udp -m udp --dport 0:32767 -j DROP

сервер является преобразователем DNS:

-A INPUT -p udp -m udp --dport 53 -j ACCEPT
-A INPUT -p udp -m udp --dport 0:1023 -j DROP

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

Лучше всего проверить это самостоятельно:

Вы можете отслеживать порты отправки, используя

tcpdump udp and port 53 and not dst host *yourserveripaddress*

затем посмотрите на отправляющие порты и попробуйте найти наименьшее число. Это наименьшее число не должно быть ниже номера порта xxxx в --dport 0: xxxx, иначе вы заблокируете или замедляете свои DNS-запросы.

Вам действительно нужно разрешить посторонним в Интернете запускать DNS-запросы к вашему серверу? Я подозреваю, что вам просто нужно убедиться, что ваш брандмауэр позволяет вашему серверу делать исходящие DNS-запросы.

С брандмауэром вы начинаете с блокировки всего, а затем очень точно / подробно раскрываете определенные комбинации порта / службы / протокола и ограничиваете их IP-адресом (диапазоном).

Как я могу отклонить все входящие UDP-пакеты, кроме DNS-запросов?

Об этом можно сказать более широко: как я могу отклонить весь трафик, который я не инициировал с помощью Linux netfilter?

Ответ состоит из двух строк:

iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -j DROP

(Принимая во внимание, что вы не хотите фильтровать кольцевой трафик для экономии циклов процессора, вы можете добавить для него исключение.)

Если OTOH у вас есть DNS-сервер на том же компьютере, и ваш q-n можно более точно указать как "Как я могу отклонить весь входящий UDP-трафик, кроме внешних запросов к DNS-серверу?"вы должны использовать ту же базу из двух строк и добавить еще одну, которая явно разрешает трафик DNS:

iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

iptables -A INPUT -p udp --dport 53 -j ACCEPT -m comment --comment "we serve DNS"
iptables -A INPUT -p tcp --dport 53 -j ACCEPT -m comment --comment "DNS uses TCP too sometimes"

iptables -A INPUT -j DROP

Обратите внимание, что обычно вам не нужно указывать -m state вещи для чего угодно, кроме первой строки, потому что первая строка является сокращением, позволяющим продолжить любой законный трафик, если его пилотные пакеты получили разрешение на вход.

Другие уведомления

Совет @ Zoredache для recent вообще не применимо. recent имеет очень ограниченную область применения, потому что он использует не эффективные структуры данных, а список и хеши, никаких деревьев, нет. По умолчанию он может запомнить только 100 IP-адресов на список, который можно расширить, но хеширование в любом случае не очень эффективно для поиска по нему.