Настройка Linux-файрвола с помощью iptables в CentOS / RHEL 7

Настройка Linux-файрвола с помощью iptables в CentOS / RHEL 7

 

В этой статье мы покажем, как управлять файерволом Linux с помощью классическгого iptables вместо firewalld в CentOS / RHEL 7 для фильтрации входящего и исходящего трафика. В этой статье рассмотрена настройка iptables на CentOS 7 для фильтрации входящего трафика, на примере развернутого с нуля облачного виртуального сервера myserver01, доступного из Интернета.

 

Отключение firewalld в CentOS 7

В CentOS 7 для управления файрволом по умолчанию используется системная служба firewalld. Она предоставляет свой интерфейс, но в итоге также работает через утилиту iptables. При этом управление файроволом должно осуществляться либо через firewalld, либо напрямую через iptables.

 

firewalld не замена, а обертка вокруг iptables, пользоваться из этого можно тем, что больше нравится, или больше подходит в конкретных условиях. iptables более универсален, это базовый инструмент, но он немного сложнее в освоении. firewalld предоставляет более простой интерфейс, но, например, в CentOS 6 воспользоваться им не получится, да и для других дистрибутивов необходимо наличие нужных установочных пакетов. К тому же, если вы используете приложения, которые производят свои настройки в файрволе, они должны быть совместимы с firewalld (пример таких приложений docker, fail2ban).

Проверим статус firewalld и отключим его.

systemctl status firewalld

В выводе команды обведенная красным область со словом enabled, означает включенную автозагрузку, а область, обведенная желтым, со словом active, означает, что служба запущена.

Останавливаем службу и выключаем для нее автозагрузку:

systemctl stop firewalld
systemctl disable firewalld

Повторно проверяем статус:

Теперь вывод команды показывает disabled для автозагруки (выключена), и inactive означает, что служба выключена.

Синтаксис и правила iptables в CentOS/Red Hat

Iptables – это утилита, с помощью которой настраиваются правила для файрвола в Linux.

Iptables группирует правила файрвола в таблицах, основные это:

  • Таблица filter – используется для фильтрации трафика, то есть разрешения и запрещения соединений
  • nat – используется для преобразования адресов (NAT)
  • Таблица mangle – прочие модификации заголовков ip пакетов.

Для начала проверим, что iptables установлен в системе(должен быть умолчанию):

rpm -q iptables

Вывод команды показывает, что текущая установленная версия iptables – 1.4.21.

Работа с iptables в командной строке требует root привилегий, поэтому далее будем работать под пользователем root.

Чтобы вывести текущие правила, выполним команду:

iptables [-t таблица] -L [цепочка] [параметры]

Примечание: если не указать название таблицы при вызове команды, по умолчанию используется таблица filter.

Например, результат команды iptables -L, когда в таблицах еще не создано правил:

Рассмотрим вывод команды подробнее.

Таблица filter содержит три типа правил, так называемые chain(цепочки):

  • INPUT – в этой цепочке обрабатываются входящие ip пакеты, предназначенные для самого хоста;
  • OUTPUT – в этой цепочке обрабатываются исходящие ip пакеты от самого хоста;
  • FORWARD – эта цепочка нужна для перенаправления ip пакетов. Используется, если вы хотите использовать сервер, как маршрутизатор.

Напротив каждой цепочки указана политика по умолчанию (policy), которая определяет, что нужно делать, в случае, если соединение не попало ни в одно из правил. Политика по умолчанию может принимать два значения и определяет сам подход к организации файрвола:

  • ACCEPT – по умолчанию все соединения разрешены, правилами блокируются нежелательные соединения;
  • DROP – по умолчанию все соединения запрещены, правилами разрешаются нужные соединения.

Создание правил фильтрации трафика в iptables

Фильтр iptables по интерфейсу

Начнем создавать правила. Синтаксис команды для добавления нового правила в конец указанной цепочки выглядит так:

iptables [-t таблица] -A <цепочка> <критерии> -j <действие>

Для начала, разрешим трафик через локальный loopback интерфейс(127.0.0.1), что необходимо для работы некоторых приложений:

iptables -A INPUT -i lo -j ACCEPT

Разберем по порядку:

  1. Мы указываем цепочку INPUT, т.е. правило будет применяться для входящих соединений.
  2. Далее, используем ключ -i(—in-interface), чтобы определить входящий интерфейс, на который приходит ip пакет.
  3. Завершаем команду ключом -j(—jump), определяющим действие, которое будет выполнено для всех ip пакетов, соответствующих критерию из пункта 2. В данном случае ACCEPT – разрешить соединение. Кроме того, к основным действиям с соединениями также относятся:
    • DROP – запретить соединение, источник соединения не информируется, ip пакет просто отбрасывается;
    • REJECT – запретить соединение, источник соединения информируется сообщением.

Фильтр iptables по порту, протоколу или IP адресу

Теперь добавим разрешающее правило для подключения к нашему Linux серверу по SSH на порт 22.

iptables -A INPUT -p tcp --dport 22 -j ACCEPT

В этом правиле критериями являются порт и протокол. Протокол (tcp, udp, icmp, all) задается ключом -p(protocol), порт назначения (т.е. порт на который будут приходить ip пакеты к серверу) —dport.

Примечание: если вы хотите использовать в критериях порт назначения или порт источник(—dport или —sport), то указывать протокол обязательно.

Допустимо указывать диапазон портов через двоеточие, например

--dport 6000:6063

Если нам известны ip адреса клиентов, с которых мы будет подключаться к серверу, более безопасным будет разрешить доступ только с этих ip адресов. В этом случае, в критерии нужно добавить ключ –s(—src, —source), задающий ip адрес или подсеть источника соединения, например, таким правилом:

iptables -A INPUT -p tcp -s 94.41.174.122 --dport 22 -j ACCEPT

доступ на 22 порт будет разрешен только с ip адреса 94.41.174.122.

Частично разрешим icmp запросы, 3-х типов:

iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
iptables -A INPUT -p icmp --icmp-type destination-unreachable -j ACCEPT
iptables -A INPUT -p icmp --icmp-type time-exceeded -j ACCEPT

Эти правила разрешают работу утилит ping, traceroute и позволяют работать механизму для определения MTU между двумя хостами.

Фильтр iptables по состоянию соединения

Для корректной работы потребуется создать правило, разрешающее уже установленные соединения:

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

Здесь в критерии используется ключ -m, для загрузки модуля state, который дает возможность определить текущее состояние ip пакета из возможных:

  • NEW – относится к входящим ip пакетам, участвующим в установке соединения;
  • ESTABLISHED и RELATED – относится к входящим ip пакетам, участвующим в уже установленных соединениях, или соединениях, инициированных из уже установленных(связанные соединения);
  • INVALID — относится к входящим ip пакетам, если к ним не применимо ни одно из указанных выше состояний.

Задание политики iptables по умолчанию

Минимальный набор разрешающих правил для файрвола готов, осталось установить политику по умолчанию, запрещающую все входящие соединения, не соответствующие нашим правилам. Для этого в команде iptables служит ключ -P, устанавливает политику по умолчанию для заданной цепочки, в нашем случае:

iptables -P INPUT DROP

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

Посмотрим на результатурующую таблицу правил iptables, добавим ключ -v, чтобы показать более подробный вывод:
iptables -L -v

Включить логи iptables

Iptables позволяет записывать информацию о проходящих ip пакетах в системный журнал. Реализуется это с помощью специфичного действия LOG над соединением, после которого, ip пакет продолжает движение по цепочке нетронутым. Для примера, создадим правило, которое будет записывать в системный журнал все события соединений на порт 445 (tcp):

iptables -A INPUT -p tcp --dport 445 -j LOG --log-prefix "IN SMB DROP: "

здесь —log-prefix задает префикс для всех сообщений, логируемых нашим правилом. Это удобно, если у вас несколько разных правил логирования, или для дальнейшей программной обработки. Если теперь попробовать подключиться снаружи к нашему серверу на порт 445, например через telnet, в файле /var/log/messages появятся записи:

Разберем вывод:

  • IN SMB DROP: префикс, который мы задали опцией —log-prefix
  • IN=eth0 интерфейс, на который принят ip пакет, для исходящих соединений содержит пустое значение
  • OUT= интерфейс, с которого отправлен ip пакет, для входящих соединений, содержит пустое значение
  • MAC= соединенные вместе в следующем порядке: MAC-адрес назначения, MAC-адрес источника, EtherType — 08:00 соответствует IPv4.
  • SRC= ip адрес источника, от которого отправлен ip пакет
  • DST= ip адрес назначения, на который отправлен ip пакет
  • LEN= размер ip пакета в байтах
  • SPT= порт источника, от которого отправлен ip пакет
  • DPT= порт назначения, на который отправлен ip пакет

Сохранение и восстановление правил фильтрации iptables

В заключении, настроим автозагрузку правил, после перезагрузки сервера. Для этого должен быть установлен пакет iptables-services и активирован сервис. Установим пакет через yum:

yum install iptables-services
systemctl enable iptables

Проверим статус службы iptables:

systemctl status iptables

Параметр автозагрузки установлен в enabled (включена), параметр active указывает, что служба запущена.

При загрузке сервис будет читать содержимое файла /etc/sysconfig/iptables, и восстанавливать сохраненные правила. Чтобы сохранить в него наши правила, воспользуемся командой:

iptables-save > /etc/sysconfig/iptables

Можно восстановить правила из файла командой:

iptables-restore < /etc/sysconfig/iptables

Теперь можно перезагрузить сервер, и убедиться, что правила файервола восстановились при загрузке.