Базовая настройка iptables

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

Базовая настройка iptables

Можно, например, заняться сканированием открытых на сервере портов. На основе этого возможно определение используемых сервисов, их версии, названия и версии операционной системы. Далее — подбор уязвимостей к ним. Или некоторые icmp — сообщения могут выдать лишнюю информацию.

В общем, описание того, зачем нужно настраивать сетевой экран, достойно отдельной статьи, которых бесчисленное множество. И уж если вы читаете эту статью, то определённо знаете, зачем вам это нужно. ;)

Как и все статьи на сайте, эта инструкция написана на основе личного опыта, а-ля «я делаю так», кто-то другой иначе.

Содержание статьи:

  • 1 Установка необходимых компонентов
  • 2 Редактирование правил для ip версии 4

Установка необходимых компонентов

И так, в системе уже присутствует главный из списка необходимых инструмент — iptables. Но этого недостаточно. Также понадобятся фильтр tarpit и iptables-persistent, чтобы загружать правила при старте системы.

# aptitude install iptables-persistent xtables-addons-dkms

Во время установки persistent будет задано два вопроса о сохранении текущих правил. Можно ответить «Да» и тогда в папке /etc/iptables/rules/ будут созданы нужные файлы с правилами, которые мы отредактируем.

Редактирование правил для ip версии 4

Открываем файл /etc/iptables/rules.v4 в любимом редакторе. Вы увидите строки, устанавливающие политику по-умолчанию для цепочек. Во всех значениях она будет иметь значение accept. Для цепочки FORWARD устанавливаем политику DROP. Мы же не роутер и не компьютер, перенаправляющий трафик куда-то ещё. :) Остальное не меняем.

*filter :INPUT ACCEPT [0:0] :FORWARD DROP [0:0] :OUTPUT ACCEPT [0:0] COMMIT

Все остальные правила будем добавлять перед строкой COMMIT. И в первую очередь добавляем правило, разрешающее локальный трафик.

-A INPUT -i lo -j ACCEPT

Далее правило, разрешающее все уже установленные активные соединения как для tcp, так и для udp протоколов. Это нужно для правильной работы сети, так как без него ответы на исходящие соединения будут отклоняться.

-A INPUT -m state --state RELATED,ESTABLISHED -p all -j ACCEPT

Теперь необходимо добавить правило, разрешающее установку новых входящих соединений к определённым сервисам. У меня это web-сервер и почтовый, а также ssh.

Важное замечание! Всегда добавляйте разрешающее правило для ssh, чтобы потом не потерять доступ к серверу после применения правил.

Сюда можно добавлять и другие порты, разделяя запятой. Расширение multiport позволяет указать несколько портов, чтобы не плодить почти одинаковые правила для каждого отдельно. ;)

-A INPUT -m state --state NEW -p tcp -m multiport --dport 22,25,80,443 -j ACCEPT

Если у вас на сервере только один сервис, для которого нужно открыть один порт, то правило будет таким:

-A INPUT -m state --state NEW -p tcp --dport 22 -j ACCEPT

Также вам может понадобиться открыть какие-то udp порты. Отличие от вышеприведённых правил будет только в том, что вместо -p tcp следует указать -p udp.

А при добавлении следующего правила пригодится фильтр tarpit, который мы установили с пакетом xtables-addon-dkms. Если кратко, то он создаёт ловушку для входящих соединений, не отсылая ничего в ответ, но удерживая соединение, что тратит ресурсы подключившегося клиента, но не сервера. Подробнее о tarpit можно узнать на сайте OpenNET. А пока добавляем правило для всех остальных входящих соединений.

-A INPUT -p tcp -m tcp -j TARPIT

Важно иметь в виду, что ловушка работает только с tcp. Подобным образом можно реализовать бан по ip на уровне iptables, вместо стандартного drop. К сожалению, для udp он не пригоден. Поэтому запрещаем все остальные входящие udp — пакеты, для которых не создали исключения ранее.

-A INPUT -p udp -j DROP

И принимаемся за icmp. Здесь в качестве типа icmp можно указать как код, так и эквивалентное ему название. У меня — код. :)

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

-A INPUT -p icmp --icmp-type 0 -j ACCEPT

Затем входящие icmp — сообщения о недоступности адресата.

-A INPUT -p icmp --icmp-type 3 -j ACCEPT

И входящие эхо-запросы, если кто-то пингует наш сервер.

-A INPUT -p icmp --icmp-type 8 -j ACCEPT

А также сообщение об истечении времени действия пакета.

-A INPUT -p icmp --icmp-type 11 -j ACCEPT

Это необходимый минимум сообщений для корректной работы сети. Возможно, вам понадобятся другие коды. Как их разрешить, вы уже знаете. :)

Теперь принимаемся за создание правил для исходящих icmp сообщений. Эти правила выглядят похожими, но цепочкой будет уже OUTPUT. Поэтому описывать их нет смысла.

-A OUTPUT -p icmp --icmp-type 0 -j ACCEPT -A OUTPUT -p icmp --icmp-type 3 -j ACCEPT -A OUTPUT -p icmp --icmp-type 8 -j ACCEPT -A OUTPUT -p icmp --icmp-type 11 -j ACCEPT -A OUTPUT -p icmp --icmp-type 12 -j ACCEPT

Кроме двенадцатого. Оно разрешает отправку сообщения о неверном параметре (ошибка в IP-заголовке или отсутствует необходимая опция).

Все остальные исходящие ICMP запрещаем, чтобы сервер не сболтнул лишнего.

-A OUTPUT -p icmp -j DROP

На этом всё. Сохраняем файл /etc/iptables/rules.v4, активируем правила командой:

cat /etc/iptables/rules.v4 | iptables-restore -c