Если вы администрируете сервер, который подключён к сети, обязательно стоит позаботиться о безопасности системы. Злоумышленники в любой момент могут попытаться использовать уязвимости в программном обеспечении, которое установлено на вашем устройстве. Так, например, если у вас открыт 22 порт, хакеры могут пытаться перебором получить пароль к вашей системе.
Читайте также: DDoS-атака на сервер: как обнаружить и защитить свой бизнес
Для защиты устройства от подобных сетевых атак нужно как можно сильнее сузить пространство для взаимодействия с сервером через интернет — открывать только те порты, которые необходимы для работы, разрешать доступ только надёжным сетям и подсетям, блокировать входящий трафик, если он превышает заданные лимиты.
Такие правила позволяет установить брандмауэр — сетевой экран, который предусмотрен в большинстве современных систем. Часто он встроен в ядро операционной системы, иногда поставляется в составе антивирусных программ.
На устройствах с операционной системой Gnulinux брандмауэром является Netfilter, а его управление осуществляется с помощью утилит iptables или Nftables. Программа работает так: все сетевые пакеты просеиваются через фильтр iptables, и в случае, если все проверки пройдены, пакет передаётся дальше. В противном случае пакет отбрасывается.
Принцип работы iptables в Linux
Работа утилиты iptables основана на концепции цепочек. Это список правил, которые применяются для обработки сетевых пакетов. Существуют отдельные цепочки для входящих, исходящих и транзитных пакетов.
Такие цепочки могут объединяться в таблицы, группируясь по задаче. Например, можно выделить таблицы модификации заголовков, фильтрации пакетов и так далее.
Основные понятия
Сетевые пакеты
Сетевые пакеты делятся на входящие (input), транзитные (forward), исходящие (output):
- INPUT — пакеты, передаваемые при входящих запросах. Когда вы открываете веб-сайт, браузер отправляет запрос на сервер, чаще всего на 80 или 443 порты. Пакеты запроса от клиента серверу относятся к входящим.
- FORWARD — пакеты, которые проходят через сервер, но направлены другому хосту. Если сервер выступает в роли маршрутизатора, брандмауэр регистрирует транзитные пакеты и выстраивает правила взаимодействия с ними.
- OUTPUT — пакеты исходящих запросов. Продолжим пример с веб-сайтом. Когда сервер успешно обрабатывает запрос, он отправляет ответ браузеру. Такие пакеты относятся к исходящим.
Правила
Для каждого типа сетевых пакетов, с которыми взаимодействует сервер, можно установить набор правил. Каждое правило состоит из условия, действия и счётчика.
Если условие применимо, выполняется действие, которое учитывается счётчиком. Если условия нет, действие выполняется для всех пакетов. В случае, если нет даже действия, брандмауэр только регистрирует пакет, так как правило состоит только из счётчика.
Действия могут разными:
- ACCEPT — принять пакет, пропустить его дальше по цепочке.
- REJECT — отклонить пакет, уведомив отправителя.
- DROP — удалить пакет.
- LOG — сделать запись о пакете в файл.
- QUEUE — отправить пакет приложению.
Условия также могут быть разными — например, проверка по IP-адресам отправителя или получателя, проверка по заголовкам запроса и так далее.
Кстати, в официальном канале Timeweb Cloud собрали комьюнити из специалистов, которые говорят про IT-тренды, делятся полезными инструкциями и даже приглашают к себе работать.
Цепочки
Цепочка — последовательность правил. Они бывают базовыми и пользовательскими. Базовая — это цепочка по умолчанию, которая создаётся при инициализации таблицы. Обычно их названия пишут в верхнем регистре.
Пользовательские цепочки создаются пользователем, называются в нижнем регистре.
В фильтрах iptables цепочки делятся в соответствии с типом пакетов — входящие, исходящие и транзитные. Кроме основных цепочек существуют дополнительные:
- prerouting — цепочка правил перед обработкой, утилита не знает даже тип пакета.
- postrouting — все входящие транзитные пакеты обрабатываются правилами этой цепочки.
Таблицы
В таблицы объединяются и базовые, и пользовательские цепочки, которые группируются по назначению. Таблицы нужны для выполнения действий над пакетами.
Виды таблиц:
- raw — таблица для пакетов, которые ещё не прошли обработку;
- mangle — таблица для модификации пакетов;
- nat — преобразует сетевые адреса;
- filter — основная таблица для фильтрации пакетов.
Утилита iptables
Принцип работы утилиты iptables мы будем рассматривать на сервере с операционной системой Ubuntu. Вы можете подобрать любую конфигурацию облачного решения для себя на Timeweb Cloud.
Установка iptables
Хотя утилита поставляется в составе всех современных дистрибутивов, всё равно полезно знать, как установить на Ubuntu iptables:
sudo apt install iptables
Синтаксис
Теперь, когда у нас в распоряжении сервер с iptables, мы можем приступить к изучению синтаксиса.
Использовать утилиту несложно. Аргументы команды идут друг за другом — «таблица → действие с таблицей → цепочка». Далее можно дописать дополнительные параметры.
Действия, которые позволяет выполнить утилита:
- -A — добавить новое правило в цепочку;
- -С — проверить все существующие правила;
- -D — удалить правило;
- -I — вставить правило;
- -L — вывести все правила в цепочке;
- -S — вывести вообще все правила;
- -F — очистить все правила;
- -N — создать новую цепочку;
- -X — удалить цепочку;
- -P — сделать действием по умолчанию;
- -p — указать протокол;
- -s — указать IP-адрес отправителя пакета;
- -d — указать IP-адрес получателя;
- -i — входящий сетевой интерфейс;
- -o — исходящий сетевой интерфейс;
- -j — выбрать действие.
После изучения синтаксиса и основных понятий можем приступить к базовой настройке iptables. Во всех примерах ниже мы будем работать с таблицей filter.
Просмотр правил
Перед началом работы с утилитой проверим, какие правила уже действуют:
sudo iptables -S
На свежеустановленной системе в ответе вы увидите следующие строки:
-P INPUT ACCEPT
-P FORWARD ACCEPT
-P OUTPUT ACCEPT
Флаг -L позволяет осуществить с помощью утилиты iptables просмотр правил:
sudo iptables -L
В ответе мы увидели пустые таблицы, значит на нашем сервере ещё не применяются правила iptables:
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Теперь рассмотрим правила для цепочки OUTPUT, чтобы вывести правила только этой цепочки.
sudo iptables -L OUTPUT
Ответ:
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Разберём подробнее пример вывода. Первая строчка указывает на имя цепочки (в примере выше — OUTPUT), дальше — используемые правила, в нашем случае ACCEPT.
Далее идёт таблица, которая состоит из следующих столбцов:
- target — правила, которые указывают, что нужно сделать с пакетом, если выполняются условия;
- prot — протокол;
- opt — опции IP;
- source — исходный IP-адрес или подсеть;
- destination — IP-адрес назначения или подсеть.
В последней колонке расположены опции правила, которые не вбирает в себя основная таблица. Там могут быть указаны, например, порты.
Если использовать флаг -V при просмотре правил, утилита также отобразит два столбца pkts, bytes — количество пакетов и их общий размер соответственно.
Вы также можете отобразить номера строк в выводе утилиты с помощью флага --line-numbers. Это полезно при работе с удалением или очисткой цепочек — утилита позволяет выбирать строки по номерам.
Добавление правил
В iptables команда DROP позволяет блокировать пакеты по любому критерию. Например, чтобы заблокировать входящие пакеты, отправленные с устройства, IP-адрес которого 8.10.8.10 нужно выполнить:
sudo iptables -A INPUT -s 8.10.8.10 -j DROP
Рассмотрим эту команду подробнее. Так как мы добавляем новое правило для цепочки INPUT, нужно использовать флаг -A. -s указывает на то, что дальше будет передан IP-адрес отправителя. Если условие выполнено, отклоняем пакет; за это отвечает конструкция -j DROP.
То же самое можно сделать и с исходящими пакетами, но уже, например, на всю подсеть:
sudo iptables -A OUTPUT -d 8.10.8.0/24 -j DROP
Нередкая задача — с помощью iptables открыть порт. Если вы публикуете на сервере веб-страницы, они должны быть доступны по протоколу HTTP. Для этого нужно открыть все входящие соединения на 80 и 443 (https) порты:
iptables -A INPUT -p tcp -m tcp --sport 80 -j ACCEPT
iptables -A OUTPUT -p tcp -m tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp -m tcp --sport 443 -j ACCEPT
iptables -A OUTPUT -p tcp -m tcp --dport 443 -j ACCEPT
В этом примере используются флаги --sport и --dport — порт-источник (--source-port) и порт-назначение (--destination-port). Так браузер сможет обмениваться информацией с сервером и пользователь без проблем получит веб-страницу по любому из протоколов.
Так же можно ограничить подключения по ssh:
sudo iptables -A INPUT -p tcp --dport ssh -j DROP
Правила по умолчанию
Если для пакета не подходит ни одно условие, то выполняется действие по умолчанию. Задать такие действия можно с помощью флага -p.
Например, можно запретить все входящие запросы по умолчанию:
sudo iptables -p INPUT DROP
Очистка правил
При настройке iptables всегда что-то может пойти не так, в таком случае вам придётся очистить правила. Это можно сделать как для конкретной цепочки, так и глобально — с помощью флага -F:
sudo iptables -F
Или в случае, когда нужно очистить правила только цепочки OUTPUT:
sudo iptables -F OUTPUT
Сброс счётчиков
Если вам необходимо обнулить счётчики пакетов для правил, нужно воспользоваться опцией -Z:
sudo iptables -Z
Или в случае, когда нужно сбросить счётчик для конкретной цепочки:
sudo iptables -Z INPUT
Или для третьего правила цепочки INPUT:
sudo iptables -Z INPUT 3
Удаление
Также вы можете с помощью утилиты iptables удалить правило.
Удаление правила осуществляется с помощью флага -D. Удалим наше правило, в котором мы блокируем все входящие запросы с устройства 8.10.8.10. Сначала проверим, существует ли такое правило для цепочки INPUT:
sudo iptables -L INPUT
Если в результате видим такой ответ, правило существует:
in INPUT (policy ACCEPT)
target prot opt source destination
DROP all -- 8.10.8.10 anywhere
Удаление правил идентично по синтаксису с добавлением. Разница только в использовании флага -D:
sudo iptables -D INPUT -s 8.10.8.10 -j DROP
Проверим таблицу после удаления:
sudo iptables -L INPUT
Если строка пропала, значит удаление прошло успешно.
Вы также можете удалять правила по номеру строки цепочки:
sudo iptables -D INPUT 3
Сохранение
Правила Netfilter хранятся в течение одного сеанса. Это значит, что после каждой перезагрузки устройства изменения пропадают, и выполняются правила по умолчанию.
Для того, чтобы не добавлять одни и те же правила после каждой перезагрузки устройства существует способ сохранения настроек iptables — утилита iptables-save. Правила можно сохранить в любую директорию, затем загрузив их оттуда с помощью iptables-restore.
На операционных системах Ubuntu и Debian вы также можете воспользоваться утилитой iptables-persistent.
Использование iptables-persistent
Сначала нужно установить пакет:
sudo apt-get install iptables-persistent
В процессе установки вам будет предложено сохранить текущие правила iptables, они сохранятся в директории /etc/iptables. В каталоге будет два набора правил — для IPv4 и IPv6. Синтаксис точно такой же, как и в файлах, сохранённых с помощью iptables-save.
Вносить новые правила нужно в этих файлах. Для управления брандмауэром в системе появилась новая служба — netfilter-persistent.
Если вы внесли изменения в файл и хотите их применить:
sudo netfilter-persistent reload
Для сохранения текущей конфигурации iptables:
sudo netfilter-persistent save
Когда нужно очистит правила брандмауэра, выполните:
sudo netfilter-persistent flush
Синтаксис iptables-save
В общем случае синтаксис утилиты состоит из указания таблицы, имени файла и указания modprobe — утилиты управления модулями ядра (по умолчанию — /proc/sys/kernel/modprobe):
iptables-save [-c] [-t таблица] [-f имя файла]
Так, чтобы сохранить все изменения в файл /etc/ipt/rules.cnf нужно выполнить:
sudo iptables-save -f /etc/ipt/rules.cnf или sudo iptables-save > /etc/ipt/rules.cnf
Если не указать имя файла, утилита сохранит вывод в стандартный поток STDOUT.
Восстановление правил
Для восстановления правил, сохранённых с помощью iptables-save, нужно использовать утилиту iptables-restore.
iptables-restore [-chntvV] [-w секунды] [-W миллисекунды] [-M modprobe] [-T таблица] [имя файла]
Аргументы утилиты:
- -с — восстанавливает значения счётчиков;
- -n — если не указать, правила, добавленные в текущем сеансе перезапишутся. Если указать — добавятся в конец;
- -t — правила проверяются утилитой, но не применяются;
- -v — вывод отладочной информации;
- -V — версия утилиты;
- -w — количество секунд до запуска утилиты. Используется для предотвращения одновременных запусков;
- -W — количество миллисекунд между запусками утилиты, применяется только совместно с -w;
- -M — путь к modprobe;
- -T — таблица правил.
Имя файла — путь до файла с правилами, по умолчанию утилита применяет правила из потока STDIN.
Для того, чтобы восстановить правила из нашего файла /etc/ipt/rules.cnf, используем:
sudo iptables-restore /etc/ipt/rules.cnf
Заключение
Любые облачные серверы должны быть надёжно защищены от атак через сеть, поскольку злоумышленники могут попытаться через уязвимости в программном обеспечении получить контроль над устройством. Для предотвращения таких попыток администратор сервера должен использовать брандмауэр. В этой статье мы в общих чертах ознакомились с принципом его работы.
На Linux-системах для защиты сетевого интерфейса используется netfilter. Мы рассмотрели синтаксис брандмауэра Iptables, на распространённых примерах научились добавлять правила, использовать их по умолчанию и удалять.
Так как при каждой перезагрузке устройства правила сбрасываются, мы также коснулись утилит iptables-save и iptables-restore, чтобы сохранять и восстанавливать настройки соответственно.
Статья оказалась полезной? Подписывайтесь, ставьте лайки и поделитесь ссылкой с друзьями.