Базовая настройка iptables
Правильно настроенный брандмауэр – один из основных аспектов безопасности сервера. Брандмауэр позволяет выбрать для сервера индивидуальные правила и политику, которые ограничат трафик. Брандмауэры, такие как iptables, позволяют определять структурные рамки, в которых будут применяться эти правила.
Данное руководство поможет вам составить список базовых правил брандмауэра для сервера Ubuntu 20.04. Такой список легко расширить, и в дальнейшем вы сможете использовать этот шаблон для создания более сложных правил.
Установка iptables-persistent
Начнем с обновления локального кеша пакетов:
sudo apt update
Теперь нужно установить пакет iptables-persistent, который позволяет сохранять наборы правил брандмауэра и автоматически использовать их в дальнейшем:
sudo apt install iptables-persistent
Во время установки пакет предложит вам сохранить текущий набор правил брандмауэра. Чтобы сделать это, выберите yes. Обратите внимание, что нужно выполнить команду netfilter-persistent для запуска службы брандмауэра iptables. Потом мы отредактируем сгенерированные файлы правил.
Команда iptables обрабатывает только трафик IPv4. Для обработки трафика IPv6 существует отдельный инструмент, ip6tables. Правила для IPv4 и IPv6 хранятся в отдельных таблицах и цепочках. Пакет iptables-persistent записывает правила IPv4 в /etc/iptables/rules.v4, а правила IPv6 – в /etc/iptables/rules.v6.
Основные команды iptables
Вывод текущих правил в табличном виде выполняется при помощи вызова команды iptables с ключом -L:
sudo iptables -L
Вывод:
Output:
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
В выводе представлены 3 стандартных цепочки (INPUT, OUTPUT, FORWARD) и действие по умолчанию (default policy) для каждой цепочки – ACCEPT. Как видим, у нас пока нет боевых правил. По умолчанию iptables идет без предустановленных правил и пропускает весь трафик.
Вывод текущих настроенных правил в виде строк выполняется при помощи вызова команды iptables с ключом -S:
sudo iptables -S
Вывод:
Output:
-P INPUT ACCEPT
-P FORWARD ACCEPT
-P OUTPUT ACCEPT
Ключ -P указывает на действие, применяемое к пакету по умолчанию.
Построчный вывод полезен тем, что каждая строка вывода — это полноценная команда в iptables (например, мы можем получить такой вывод уже на настроенном сервере и использовать его для настройки другого сервера, сделав небольшие правки).
Для очистки всех правил используется ключ -F:
sudo iptables -F
Тут стоит отметить важность политик по умолчанию, так как они не удалятся после применения этой команды. Поясним подробней. Допустим у нас есть только удаленный доступ к серверу и в политике iptables по умолчанию выставлено действие DROP. В результате чего после очистки всех правил повторное подключение к серверу будет невозможно. Поэтому, если у нас нет физического доступа или консольного подключения к серверу, то перед сбросом всех правил необходимо убедиться, что действие по умолчанию – ACCEPT. Это позволит нам удаленно подключиться к серверу, создать разрешающее удаленную сессию первое правило. После этого для повышения безопасности можно уже выставить политику по умолчанию – DROP.
Чтобы задать действие по умолчанию ACCEPT и выполнить последующую очистку правил вводим:
sudo iptables -P INPUT ACCEPT
sudo iptables -P OUTPUT ACCEPT
sudo iptables -F
Создание правил в iptables
Создадим правило, которое позволит принимать текущее SSH-соединение между нами и сервером
sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED, RELATED -j ACCEPT
-A INPUT
: флаг -A (append) – добавляет правило в конец цепочки INPUT-m conntrack
: этот параметр вызывает модуль conntrack для отслеживания информации о соединениях.–ctstate ESTABLISHED, RELATED
: выделяем все соединения в состоянии ESTABLISHED (выделяется трафик по уже существующим соединениям) и RELATED (трафик по новым соединениям, но связанных с уже открытыми).-j ACCEPT
: действие (target) – то, что будет произведено с пакетом, если он попал под критерий. В нашем случае это ACCEPT.
Добавим еще два правила, разрешающие SSH-соединения (по умолчанию на 22 порт) и WEB-подключения на 80 порт.
Приведем синтаксис этих правил:
sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT
Разберем новые параметры:
-p tcp
: фильтруем пакеты, использующие протокол TCP–dport
: выделяем TCP-пакеты с портом назначения 22 и 80.
Также есть еще одно правило, которое связано с понятием “петли” (loopback-интерфейса). Используется loopback-интерфейс для взаимодействия служб и приложений в пределах одной локальной системы, без надобности отправления пакетов на сетевой интерфейс.
Правило выглядит так:
sudo iptables -I INPUT 1 -i lo -j ACCEPT
Разберем его:
- Ключ
-I
(insert) указывает вставить правило в цепочку на 1-ое место. Порядковый номер вставки указывается за именем цепочки INPUT (напоминаем, что флаг -A добавляет правило в конец) -i lo
– указываем интерфейс loopback и разрешаем трафик через него.
Мы составили 4 правила, на основании которых iptables будет разрешать трафик на сервер. Но поскольку мы не создали ни одного запрещающего правила, то все соединения с сервером будут по-прежнему разрешены.
Есть два способа реализации блокирования нежелательного трафика:
- Политика запрета по умолчанию.
Достигается написанием правила:
sudo iptables -P INPUT DROP
Тут надо помнить об опасности потери удаленного доступа к серверу. Желательно его применять, когда есть консольный доступ к серверу.
- Добавление запрещающего правила в конец цепочки.
sudo iptables -A INPUT -j DROP
Тут уже нет опасности потери удаленного подключения к серверу, но есть особенность добавления правил. Новые правила необходимо добавлять в цепочку перед запрещающим правилом. Достигается это путем ввода набора из трех правил: удаление запрещающего правила, добавление нового правила, добавление запрещающего правила в конец.
sudo iptables -D INPUT -j DROP
sudo iptables -A INPUT "MY_NEW_RULE"
sudo iptables -A INPUT -j DROP
Также можно вставить новое правило до запрещающего правила, используя порядковый номер. Для этого сперва узнаем нумерацию имеющихся правил:
sudo iptables -L --line-numbers
Потом на основании вывода вставляем правило под нужным порядковым номером:
sudo iptables -I INPUT 4 "MY_NEW_RULE"
Удаление правил iptables
Приведем различные способы удаления правил iptables.
Удаление по имени правила.
В этом случае используется ключ -D после которого следует имя правила в виде строки. Имя правила узнаем при помощи команды, рассмотренной выше:
sudo iptables -S
Допустим в данном выводе мы нашли правило
-A INPUT -i eth0 -p tcp --dport 443 -j ACCEPT
и которое подлежит удалению.
Для этого введем:
iptables -D INPUT -i eth0 -p tcp --dport 443 -j ACCEPT
Обратите внимание, что ключ -A при удалении правила не указывается.
Удаление по номеру правила в цепочке.
Для удаления этим способом нам необходимо знать название цепочки, к которой принадлежит правило и его порядковый номер в ней. Все это определяется командой:
sudo iptables -L --line-numbers
Вывод:
Chain INPUT (policy DROP)
num target prot opt source destination
1 ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED
2 ACCEPT all -- anywhere anywhere
3 DROP all -- anywhere anywhere ctstate INVALID
4 UDP udp -- anywhere anywhere ctstate NEW
5 TCP tcp -- anywhere anywhere tcp flags:FIN,SYN,RST,ACK/SYN ctstate NEW
6 ICMP icmp -- anywhere anywhere ctstate NEW
7 REJECT udp -- anywhere anywhere reject-with icmp-port-unreachable
И само удаление:
sudo iptables -D ИМЯ ЦЕПОЧКИ НОМЕР
Например, удалим привило с номером 5 в цепочке INPUT:
sudo iptables -D INPUT 5
Удаление всех правил iptables
Мы можем удалить все правила в пределах одной цепи. Для этого используется ключ -F. Например, удалим все правила цепочки INPUT:
sudo iptables -F INPUT
Для удаления правил во всех цепочках вводим команду:
sudo iptables -F