Iptables - пошаговая настройка надежного Firewall для Linux сервера




Каждому администратору Linux рано или поздно приходится сталкиваться с обеспечением безопасности сервера. Одним из самых проверенных, надежных и распространенных инструментов для фильтрации сетевого трафика является iptables.

Когда дома работает полноценный сервер на базе Linux (особенно с публичным веб-сервером на 80 и 443 портах), вопрос безопасности перестает быть теоретическим. Стандартная политика «всё открыто по умолчанию» — прямой путь к незваным гостям в логах.

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

1. Что такое iptables и как оно работает?

iptables — это инструмент командной строки, который используется для настройки ядра Linux по фильтрации пакетов (netfilter).

В основе работы iptables лежат четыре ключевых понятия:

  • Таблицы (Tables) — определяют общую категорию правил (например, фильтрация или нат).
  • Цепочки (Chains) — точки прохождения пакета, в которых применяются правила.
  • Правила (Rules) — конкретные инструкции: если пакет соответствует условию, то сделать с ним определенное действие.
  • Действия (Targets/Policy) — что именно сделать с пакетом (принять, сбросить, перенаправить).

2. Архитектура: Таблицы и Цепочки

Основные таблицы:

  • filter (основная по умолчанию) — используется для принятия или отклонения пакетов.
  • nat (Network Address Translation) — используется для перенаправления портов и подмены IP-адресов (например, для шлюзов или Docker).
  • mangle — для специального изменения заголовков пакетов.
  • raw — для работы с пакетами до того, как ядро начнет отслеживать соединения (connection tracking).

Стандартные цепочки в таблице filter:

  • INPUT — обрабатывает входящий трафик, направленный на сам сервер.
  • OUTPUT — обрабатывает исходящий трафик, генерируемый самим сервером.
  • FORWARD — обрабатывает транзитный трафик (когда сервер работает как маршрутизатор).

3. Установка iptables

В большинстве дистрибутивов Linux iptables уже установлен по умолчанию. Проверить это можно командой:

iptables --version

Если утилита отсутствует или требуется установить пакет для сохранения правил после перезагрузки, необходимо выполнить следующие действия:

sudo apt update
sudo apt install iptables iptables-persistent -y

Пакет iptables-persistent автоматически сохраняет текущие правила и восстанавливает их при каждой загрузке системы.

4. Базовые команды для управления

Прежде чем писать правила, надо вспомнить основные команды для проверки текущего состояния.

Посмотреть правила в виде списка с номерами и счетчиками пакетов:

sudo iptables -L -v -n --line-numbers

Посмотреть правила конкретной таблицы (например, filter):

sudo iptables -t filter -L -v -n

Основные ключи команд:

-A (Append) — добавить правило в конец цепочки.
-I (Insert) — вставить правило в начало цепочки (под определенным номером).
-D (Delete) — удалить правило.
-F (Flush)— очистить все правила в цепочке/таблице.
-P (Policy) — установить политику по умолчанию для цепочки.

5. Сохранение правил

По умолчанию любые изменения в iptables действуют до первой перезагрузки системы. Чтобы сохранить конфигурацию:

sudo netfilter-persistent save
sudo netfilter-persistent reload

6. Базовая политика: запретить всё, что не разрешено

Первое и главное правило безопасного сервера — изменить политики по умолчанию для цепочек INPUT и FORWARD на DROP. Это значит, что любой входящий пакет по умолчанию будет отброшен, если для него нет явного разрешающего правила.

*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [28:2551]

7. Зеленый свет для локального интерфейса и установленных соединений

Сервер должен общаться сам с собой (loopback) и уметь отвечать тем, кому он сам уже разрешил подключение (state tracking):

-A INPUT -i lo -j ACCEPT
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A INPUT -m conntrack --ctstate INVALID -j DROP

Пакеты интерфейса lo принимаются без ограничений.
Установленные соединения (ESTABLISHED, RELATED) продолжают работать штатно.
Битые и поврежденные пакеты (INVALID) сразу отбрасываются.

8. Защита от сканеров и мусорных TCP-флагов

Злоумышленники часто сканируют порты с помощью нестандартных комбинаций флагов (NULL, XMAS-сканирование и т.д.). Для этого создаю отдельную цепочку bad_tcp_flags, которая мгновенно рубит подобные трафики:

-A INPUT -p tcp -j bad_tcp_flags

-A bad_tcp_flags -p tcp -m tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG NONE -j DROP
-A bad_tcp_flags -p tcp -m tcp --tcp-flags FIN,SYN FIN,SYN -j DROP
-A bad_tcp_flags -p tcp -m tcp --tcp-flags SYN,RST SYN,RST -j DROP
-A bad_tcp_flags -p tcp -m tcp --tcp-flags FIN,RST FIN,RST -j DROP
-A bad_tcp_flags -p tcp -m tcp --tcp-flags FIN,ACK FIN -j DROP
-A bad_tcp_flags -p tcp -m tcp --tcp-flags PSH,ACK PSH -j DROP
-A bad_tcp_flags -p tcp -m tcp --tcp-flags ACK,URG URG -j DROP
-A bad_tcp_flags -p tcp -j RETURN

9. Отражение SYN-flood атак

Чтобы сервер не захлебнулся от лавины полуоткрытых соединений при DDoS-атаке или сканировании, настраиваю лимиты для SYN-пакетов:

-A INPUT -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -j syn_flood
-A syn_flood -m limit --limit 222/sec --limit-burst 2000 -j RETURN
-A syn_flood -j DROP

А также ограничиваю ICMP (ping), чтобы сеть не забивали мусорным эхо-запросами, оставляя скромный лимит в 2 пакета в секунду:

-A INPUT -p icmp -m icmp --icmp-type 8 -m limit --limit 2/sec -j ACCEPT
-A INPUT -p icmp -m icmp --icmp-type 8 -j DROP

10. Публичные службы (доступы извне)

Мой веб-сервер должен быть доступен всему миру, поэтому порты 80 (HTTP) и 443 (HTTPS) открыты для новых входящих соединений (--ctstate NEW):

-A INPUT -p tcp -m tcp --dport 80 -m conntrack --ctstate NEW -j ACCEPT
-A INPUT -p tcp -m tcp --dport 443 -m conntrack --ctstate NEW -j ACCEPT

11. Закрытый контур: администрирование только из локальной сети

Всё, что связано с управлением сервера, не должно торчать в публичный интернет. Доступ по SSH, принтеры (CUPS), панель Webmin, SNMP-мониторинг и локальные порты жестко привязаны к домашней подсети 192.168.0.0/24:

-A INPUT -s 192.168.0.0/24 -p tcp -m tcp --dport 22 -m conntrack --ctstate NEW -j ACCEPT
-A INPUT -s 192.168.0.0/24 -p tcp -m tcp --dport 631 -m conntrack --ctstate NEW -j ACCEPT
-A INPUT -s 192.168.0.0/24 -p tcp -m tcp --dport 10000 -m conntrack --ctstate NEW -j ACCEPT
-A INPUT -s 192.168.0.0/24 -p udp -m udp --dport 161 -m conntrack --ctstate NEW -j ACCEPT
-A INPUT -s 192.168.0.0/24 -p tcp -m tcp --dport 5000 -m conntrack --ctstate NEW -j ACCEPT

12. Защита от IP-спуфинга в таблице raw

На уровне таблицы raw в самом начале прохождения пакетов активирую фильтрацию обратного пути (rpfilter), что защищает от подделки IP-адресов отправителя (IP spoofing):

*raw
:PREROUTING ACCEPT [27:3015]
:OUTPUT ACCEPT [0:0]
-A PREROUTING -m rpfilter --invert -m comment --comment "spoofing attacks" -j DROP
COMMIT

13. Пример создания и настройки скрипта /etc/iptables/firewall.sh

Итак как пример, создам свои правила с учетом всего описанного выше и помещу в скрипт /etc/iptables/firewall.sh, который будет автоматически применяется при запуске системы. Такая конфигурация гарантирует, что снаружи видны исключительно веб-страницы сайта, а все административные инструменты остаются за надежной стеной локальной сети.

Цель: Перенести набор команд iptables в исполняемый Bash-скрипт, настроить правильные права доступа и автоматизировать его применение при загрузке системы или изменении конфигурации.

13.1 Создание файла скрипта

Создаю файл firewall.sh конфигурации брандмауэра в директории /etc/iptables/ с помощью текстового редактора (например, nano):

sudo nano /etc/iptables/firewall.sh

13.2 Внутрь вставлю готовый набор правил:

#!/bin/sh

# 1. Полная очистка всех таблиц
iptables -F
iptables -X
iptables -t nat -F
iptables -t nat -X
iptables -t mangle -F
iptables -t mangle -X
iptables -t raw -F
iptables -t raw -X

# 2. Дефолтные политики
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT

# 3. Защита от IP Spoofing (таблица raw)
iptables -t raw -A PREROUTING -m rpfilter --invert -m comment --comment "spoofing attacks" -j DROP

# 4. Базовые правила (Loopback и установленные соединения)
iptables -A INPUT -i lo -j ACCEPT 
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT 

# 5. Блокировка невалидных пакетов (Invalid)
iptables -A INPUT -m conntrack --ctstate INVALID -j DROP

# 6. Блокировка аномальных TCP-флагов (Сканеры портов)
iptables -N bad_tcp_flags
iptables -A INPUT -p tcp -j bad_tcp_flags
iptables -A bad_tcp_flags -p tcp --tcp-flags ALL NONE -j DROP
iptables -A bad_tcp_flags -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP
iptables -A bad_tcp_flags -p tcp --tcp-flags SYN,RST SYN,RST -j DROP
iptables -A bad_tcp_flags -p tcp --tcp-flags FIN,RST FIN,RST -j DROP
iptables -A bad_tcp_flags -p tcp --tcp-flags ACK,FIN FIN -j DROP
iptables -A bad_tcp_flags -p tcp --tcp-flags ACK,PSH PSH -j DROP
iptables -A bad_tcp_flags -p tcp --tcp-flags ACK,URG URG -j DROP
iptables -A bad_tcp_flags -p tcp -j RETURN

# 7. Защита от SYN-Flood (Лимит burst 2000, 222 req/s)
iptables -N syn_flood
iptables -A INPUT -p tcp --syn -j syn_flood
iptables -A syn_flood -m limit --limit 222/s --limit-burst 2000 -j RETURN
iptables -A syn_flood -j DROP

# 8. Защита от Ping-of-Death / ICMP Flood (оставляем мягкий лимит на пинги)
iptables -A INPUT -p icmp --icmp-type echo-request -m limit --limit 2/s --limit-burst 5 -j ACCEPT
iptables -A INPUT -p icmp --icmp-type echo-request -j DROP

# 9. Разрешающие правила для сервисов:
# HTTP (80)
iptables -A INPUT -p tcp --dport 80 -m conntrack --ctstate NEW -j ACCEPT

# HTTPS (443) 
iptables -A INPUT -p tcp --dport 443 -m conntrack --ctstate NEW -j ACCEPT

# Стандартный SSH (порт 22) только для устройств из локальной сети 192.168.0.0/24
iptables -A INPUT -s 192.168.0.0/24 -p tcp --dport 22 -m conntrack --ctstate NEW -j ACCEPT

# Разрешаем доступ к CUPS (порт 631) только из локальной сети 192.168.0.0/24
iptables -A INPUT -s 192.168.0.0/24 -p tcp --dport 631 -m conntrack --ctstate NEW -j ACCEPT

# Webmin (порт 10000) только из локальной сети 192.168.0.0/24
iptables -A INPUT -s 192.168.0.0/24 -p tcp --dport 10000 -m conntrack --ctstate NEW -j ACCEPT

# SNMP (порт 161 UDP) для всех устройств из локальной сети 192.168.0.0/24
iptables -A INPUT -s 192.168.0.0/24 -p udp --dport 161 -m conntrack --ctstate NEW -j ACCEPT

# SSH на нестандартном порту 14922 если доступ к серверу осуществляется из WAN
iptables -A INPUT -p tcp --dport 14922 -m conntrack --ctstate NEW -j ACCEPT

# 10. Сохранение
netfilter-persistent save

13.3 Назначение прав и запуск

Чтобы файл можно было запускать как исполняемый скрипт от имени суперпользователя, делаю файл исполняемым и запускаю для применения правил прямо сейчас:

sudo chmod +x /etc/iptables/firewall.sh
sudo /etc/iptables/firewall.sh

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

13.4 Автоматизация при загрузке системы (Systemd Service)

Чтобы скрипт автоматически применялся при каждом включении сервера, создам системный сервис systemd:

sudo nano /etc/systemd/system/firewall.service

Добавляю в него следующий конфигурационный блок:

[Unit]
Description=Apply custom iptables firewall rules
After=network.target

[Service]
Type=oneshot
ExecStart=/etc/iptables/firewall.sh
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

Включить и активировать созданный сервис:

sudo systemctl daemon-reload
sudo systemctl enable firewall.service
sudo systemctl start firewall.service

Заключение

Зачем вообще это нужно: Настройка iptables превращает уязвимый домашний сервер в защищенную крепость, которая отражает сетевые атаки, блокирует сканеры портов и предотвращает несанкционированный доступ к административным панелям из интернета.

Зачем столько читать: Чтобы не просто скопировать чужой набор команд, а досконально понять архитектуру сетевого экрана (таблицы, цепочки, логику обработки пакетов) и научиться самостоятельно управлять правилами фильтрации.

Главный результат: Теперь сервер надежно защищен, веб-сайты доступны всему миру, а управление скрыто в безопасном контуре локальной сети и автоматически восстанавливается после любых перезагрузок.