Я настроил свой сервер на отклонение ВСЕХ входящих пакетов 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)
Обычно, чтобы найти локальные динамические (также называемые эфемерными или частными) диапазоны портов в 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-адресов на список, который можно расширить, но хеширование в любом случае не очень эффективно для поиска по нему.