Настраиваем фаерволл для веб-сервера

Сервер в сети с открытыми портами — звучит не очень безопасно 🙂 В данной заметке вы найдёте отлаженные правила фаерволла для сервера, принимающего HTTP запросы и отдающего HTTP ответы, проще говоря, веб-сервера.

Вероятнее всего ваш веб-сервер крутится на Linux, а в Linux из коробки присутствует фаерволл netfilter. Для управления им используется утилита iptables.

Внимание: если вы не имеете непосредственного физического доступа к серверу, а работаете с ним удалённо через SSH, то прежде, чем приступать к настройке фаерволла, обратитесь к вашему хостинг-провайдеру с вопросом, сможет ли он восстановить доступ к SSH или предоставить альтернативу в случае, если вы нечаянно заблокируете себя.

Тем не менее, iptables сам не сохраняет введённые правила навсегда — они будут сброшены после перезагрузки. Чтобы настройки сохранялись нужно установить iptables-persistent отдельно. Но это в конце. Для начала следует сформировать и протестировать правила фаерволла, убедиться в работоспособности доступа к серверу по SSH, работы приложения веб-сервера (nginx, Apache) и т.п.

Как уже было сказано выше, заметка несёт собой цель привести уже готовые правила, а не составить подробный гайд. Ещё обращаю внимание, что статья носит ознакомительный характер, и автор не несёт ответственности за возможные проблемы с сервером. Но замечания и предложения будут учтены. Для понимания работы фаерволла и базовых понятий следует прочесть хотя бы статью в википедии про Iptables:

  • Правило — состоит из критерия, действия и счетчика. Если пакет соответствует критерию, к нему применяется действие, и он учитывается счетчиком. Критерия может и не быть — тогда неявно предполагается критерий «все пакеты». Указывать действие тоже не обязательно — в отсутствие действия правило будет работать только как счетчик.
    • Критерий — логическое выражение, анализирующее свойства пакета и/или соединения и определяющее, попадает ли данный конкретный пакет под действие текущего правила.
    • Действие — описание действия, которое нужно проделать с пакетом и/или соединением в том случае, если они попадают под действие этого правила. О действиях более подробно будет рассказано ниже.
    • Счетчик — компонент правила, обеспечивающий учёт количества пакетов, которые попали под критерий данного правила. Также счетчик учитывает суммарный объём таких пакетов в байтах.
  • Цепочка — упорядоченная последовательность правил. Цепочки можно разделить на пользовательские и базовые.
    • Базовая цепочка — цепочка, создаваемая по умолчанию при инициализации таблицы. Каждый пакет, в зависимости от того, предназначен ли он самому хосту, сгенерирован им или является транзитным, должен пройти положенный ему набор базовых цепочек различных таблиц. Кроме того, базовая цепочка отличается от пользовательской наличием «действия по умолчанию» (default policy). Это действие применяется к тем пакетам, которые не были обработаны другими правилами этой цепочки и вызванных из неё цепочек. Имена базовых цепочек всегда записываются в верхнем регистре (PREROUTING, INPUT, FORWARD, OUTPUT, POSTROUTING).
    • Пользовательская цепочка — цепочка, созданная пользователем. Может использоваться только в пределах своей таблицы. Рекомендуется не использовать для таких цепочек имена в верхнем регистре, чтобы избежать путаницы с базовыми цепочками и встроенными действиями.

Отмечу, что netfilter будет обрабатывать правила начиная с самых старых — если в предыдущем введённом правиле вы заблокируете пакет, до следующего правила он не дойдёт.

Итак, команды и правила ниже вводим по одной в командную строку, они сопровождены комментариями:

iptables -L -n # Команда: выводим список установленных правил
iptables -F # Команда: очищаем все установленные правила
iptables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP # Здесь и далее идут правила: блокируем нулевые пакеты
iptables -A INPUT -p tcp --tcp-flags ALL ALL -j DROP # Сбрасываем пакеты XMAS
iptables -A INPUT -p tcp ! --syn -m state --state NEW -j DROP # Защищаемся от Syn-flood
iptables -A INPUT -p tcp -m tcp --dport 22 -j ACCEPT # Разрешаем доступ по SSH (если SSH висит не на 22 порту, укажите здесь нужный порт!)
iptables -A INPUT -i lo -j ACCEPT # Разрешаем трафик на локальный интерфейс. Необходимо для работы баз данных, почтового сервера и т.п. если к ним осуществляется доступ по локалхосту.
iptables -A INPUT -p tcp -m tcp --dport 80 -j ACCEPT # Разрешаем 80 порт для доступа к сайтам по HTTP
iptables -A INPUT -p tcp -m tcp --dport 443 -j ACCEPT # Разрешаем 443 порт для доступа к сайтам по HTTPS (если есть)
iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT # Разрешаем пинговать наш сервер (если запретить, внешние сервисы могут посчитать, что сервер недоступен)
iptables -I INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT # Необходимо для обновления сервера
iptables -P OUTPUT ACCEPT # Разрешаем весь исходящий трафик от сервера
iptables -P INPUT DROP # Закрываем остальные порты для входящего трафика
iptables -L -n # Команда: проверим установленные правила

Теперь подключаемся (или переподключаемся) по SSH, проверяем. Затем пробуем открыть какие-нибудь сайты на сервере (80 порт). Если есть хосты по защищённому протоколу HTTPS (443 порт), то проверям и их.

Убедимся также, что порты, не открытые специально, закрыты для входящего трафика:

telnet IP_сервера 25

В примере выше 25 порт можно заменить на любой другой, который должен быть закрыт. Вывод telnet должен остановиться на «Trying IP_сервера…» без «Connected…». Если соединение устанавливается, значит фаерволл не работает или правила введены не так.

Если всё работает как надо (советую прогнать тесты в течении недели), чтобы не вбивать ручками правила после каждой перезагрузки сервера (или не запускать bash скрипт), устанавливаем iptables-persistent. В Debian-based дистрибутивах будет так:

apt install iptables-persistent

Установщик спросит, сохранить ли текущие правила. Впоследствии, чтобы сохранить активные правила, нужно вызывать следующую команду:

service iptables-persistent save

Буду рад услышать от вас критику и советы по настройке фаерволла для веб-сервера.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *