Настройка 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 [цепочка] [параметры]
Например, результат команды 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
Разберем по порядку:
- Мы указываем цепочку INPUT, т.е. правило будет применяться для входящих соединений.
- Далее, используем ключ -i(—in-interface), чтобы определить входящий интерфейс, на который приходит ip пакет.
- Завершаем команду ключом -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 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-prefixIN=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
Теперь можно перезагрузить сервер, и убедиться, что правила файервола восстановились при загрузке.