Полезности: защищаем сервер с помощью iptables
Перед началом проведения основного этапа настройки выделенного или виртуального сервера необходимо обеспечить его надлежащую защиту на 2-4 уровнях согласно сетевой модели OSI.
В этой публикации я расскажу, как обеспечить базовую защиту своего сервера при помощи инструмента iptables, позволяющего управлять работой межсетевого экрана netfilter.
Шаг 1. Отбрасываем все некорректные пакеты
Сразу хочу обратить внимание, что вплоть до шестого шага мы будем работать с таблицей
В некоторых случаях она также может быть полезна для модификации заголовков пакетов.
Для фильтрации некорректных пакетов нам необходимо выполнить следующую команду:
Здесь флаг -t указывает на таблицу mangle, флаг -A указывает на то, что мы обращаемся к цепочке PREROUTING, которая позволяет модифицировать пакет до принятия решения о маршрутизации.
Аргумент INVALID флага —ctstate указывает на то, что пакет по смыслу должен принадлежать уже установленному соединению (например, ICMP-сообщение port-unreachable), однако такое соединение в системе не зарегистрировано. Поэтому мы с чистой совестью отбрасываем этот пакет.
Шаг 2. Блокируем все попытки открыть входящее TCP-соединение не SYN-пакетом
Дело в том, что попытка установить соединение таким образом может быть либо ошибкой, либо атакой. Соответственно, такие пакеты мы тоже отбрасываем.
Шаг 3. Отбрасываем пакеты с подозрительным значением MSS
Для установления корректной TCP-сессии с удалённым хостом должно соблюдаться следующее условие:
MSS + заголовок TCP + заголовок IP ≤ MTU
Во всех остальных случаях мы можем смело отбрасывать пакеты с некорректным значением MSS:
Шаг 4. Отбрасываем все пакеты с подделанными флагами
В реальной среде обитания Интернета такое сочетание флагов обычно не встречается, поэтому эти пакеты мы также отбрасываем. Их наличие в системе может свидетельствовать о возможной попытке атаки на сервер.
/sbin/iptables -t mangle -A PREROUTING -p tcp —tcp-flags FIN,SYN FIN,SYN -j DROP
/sbin/iptables -t mangle -A PREROUTING -p tcp —tcp-flags SYN,RST SYN,RST -j DROP
/sbin/iptables -t mangle -A PREROUTING -p tcp —tcp-flags FIN,RST FIN,RST -j DROP
/sbin/iptables -t mangle -A PREROUTING -p tcp —tcp-flags FIN,ACK FIN -j DROP
/sbin/iptables -t mangle -A PREROUTING -p tcp —tcp-flags ACK,URG URG -j DROP
/sbin/iptables -t mangle -A PREROUTING -p tcp —tcp-flags ACK,FIN FIN -j DROP
/sbin/iptables -t mangle -A PREROUTING -p tcp —tcp-flags ACK,PSH PSH -j DROP
/sbin/iptables -t mangle -A PREROUTING -p tcp —tcp-flags ALL ALL -j DROP
/sbin/iptables -t mangle -A PREROUTING -p tcp —tcp-flags ALL NONE -j DROP
/sbin/iptables -t mangle -A PREROUTING -p tcp —tcp-flags ALL FIN,PSH,URG -j DROP
/sbin/iptables -t mangle -A PREROUTING -p tcp —tcp-flags ALL SYN,FIN,PSH,URG -j DROP
/sbin/iptables -t mangle -A PREROUTING -p tcp —tcp-flags ALL SYN,RST,ACK,FIN,URG -j DROP
Шаг 5. Отбрасываем все пакеты, пришедшие из сети Интернет с поддельным IP-адресом
Дело в том, что некоторые подсети предназначены исключительно для локального использования.
Таким образом, если к вам на сервер пришёл пакет с интерфейса, который позволяет установить соединение с сетью Интернет, но его IP-адрес относится к локальной подсети, мы его также отбрасываем.
/sbin/iptables -t mangle -A PREROUTING -s 169.254.0.0/16 -j DROP
/sbin/iptables -t mangle -A PREROUTING -s 172.16.0.0/12 -j DROP
/sbin/iptables -t mangle -A PREROUTING -s 192.0.2.0/24 -j DROP
/sbin/iptables -t mangle -A PREROUTING -s 192.168.0.0/16 -j DROP
/sbin/iptables -t mangle -A PREROUTING -s 10.0.0.0/8 -j DROP
/sbin/iptables -t mangle -A PREROUTING -s 0.0.0.0/8 -j DROP
/sbin/iptables -t mangle -A PREROUTING -s 240.0.0.0/5 -j DROP
Если пакет пришёл из подсети 127.0.0.0/8, но не с интерфейса lo, мы его тоже отбросим:
Шаг 6. Отбрасываем фрагментированные пакеты во всех цепочках
Это последний шаг, в котором мы будем обращаться к таблице mangle.
Дело в том, что фрагментирование пакетов должно происходить в том случае, если его размер превышает установленный MTU.
В противном случае фрагментированные пакеты с отличным MTU могут указывать на то, что производится попытка атаки типа DoS.
Такие пакеты необходимо отбросить до принятия решения о маршрутизации:
Шаг 7. Ограничиваем максимальное количество одновременных подключений с одного IP-адреса
Чтобы предотвратить возможные сценарии атак типа DoS с одного IP-адреса, нам необходимо ограничить максимальное количество одновременных подключений.
Для этого нам необходимо установить произвольное значение флага —connlimit-above:
Если количество одновременных подключений с одного IP-адреса достигнет порога в 111, дальнейшие попытки установить соединение будут пресекаться.
Шаг 8. Защищаемся от атаки типа «TCP Reset»
В каждом TCP-пакете внутри определённого соединения присутствуют различные заголовки. Среди них есть бит флага сброса (RST, сокращение от «RESET»).
У большинства пакетов этот бит установлен в 0 и при маршрутизации таких пакетов с ними не требуется проводить никаких дополнительных действий.
Однако если этот бит установлен в 1, то получатель пакета должен немедленно прервать это соединение — он больше не должен посылать в ответ пакеты с текущим идентификатором и на текущий порт, а впоследствии ему также необходимо игнорировать все последующие пакеты этого соединения.
Этот механизм обеспечивает моментальный разрыв соединения TCP. Злоупотребление использованием этого механизма злоумышленником может привести к негативным последствиям — ведь правильно сформированные поддельные пакеты могут быть весьма надёжным способом нарушить любое TCP-соединение, доступное для отслеживания нападающим.
Отбрасываем такие пакеты, если их количество превышает 2 пакета в секунду:
/sbin/iptables -A INPUT -p tcp —tcp-flags RST RST -j DROP
Шаг 9. Ограничиваем максимальное количество новых подключений по протоколу TCP для каждого IP-адреса
Для того, чтобы избежать избыточной нагрузки на сервер, необходимо ограничить максимальное количество новых подключений по протоколу TCP для каждого IP-адреса.
Ограничим возможность создания новых сессий TCP для каждого из IP-адресов — по одной новой сессии в секунду:
/sbin/iptables -A INPUT -p tcp -m conntrack —ctstate NEW -j DROP
Шаг 10. Если вы используете Cloudflare для проксирования трафика и защиты от атак типа DDoS на портах 80 и 443
Давайте получим список актуальных подсетей Cloudflare, из которых к нам будут приходить пакеты на 80 и 443 порты, а для пакетов, которые пришли из других подсетей, ограничим доступ:
/sbin/ip6tables -I INPUT -p tcp -m multiport —dports http,https -s ::1 -j ACCEPT; for i in `curl -s https://www.cloudflare.com/ips-v6`; do /sbin/ip6tables -I INPUT -p tcp -m multiport —dports http,https -s $i -j ACCEPT; done
Блокируем доступ для пакетов из подсетей, отличных от подсетей Cloudflare:
/sbin/ip6tables -A INPUT -p tcp -m multiport —dports http,https -j DROP
Шаг 11. Защищаем порт SSH от атак типа DoS
Если в течение одной минуты к нам на сервер пришло хотя бы десять запросов для 22 порта, ограничиваем возможность подключения для этого IP-адреса:
/sbin/iptables -A INPUT -p tcp —dport 22 -m conntrack —ctstate NEW -m recent —update —seconds 60 —hitcount 10 -j DROP
Шаг 12. Защита от сканирования портов с определённого IP-адреса
Веерное сканирование портов может повысить нагрузку на сервер и негативно сказаться на безопасности сервера.
Поэтому давайте попробуем предотвратить такие попытки сканирования портов:
/sbin/iptables -A port-scanning -p tcp —tcp-flags SYN,ACK,FIN,RST RST -m limit —limit 1/s —limit-burst 2 -j RETURN
/sbin/iptables -A port-scanning -j DROP
Вместо заключения
Эти инструкции носят рекомендательный характер и должны быть скорректированы сетевым администратором под каждый отдельный кейс, если он того требует.