iptables

iptables

iptables — утилита для управления правилами межсетевого экрана Linux, работающего в подсистеме ядра Netfilter. С её помощью фильтруют трафик, ограничивают доступ к портам, настраивают маршрутизацию, NAT и проброс портов.

В современных дистрибутивах iptables часто работает через совместимый слой над nftables. Перед настройкой проверьте используемый backend и не смешивайте ручные правила с ufw, firewalld, Docker или Kubernetes без понимания их взаимодействия.


Основные понятия

Правила объединяются в цепочки, а цепочки находятся в таблицах. Пакеты проверяются по правилам сверху вниз. Первое подходящее завершающее действие обычно прекращает дальнейшую обработку.

Таблицы

Таблица Назначение
filter Разрешение и блокировка трафика; используется по умолчанию
nat Трансляция адресов и портов
mangle Изменение специальных параметров пакетов
raw Управление отслеживанием соединений
security Дополнительные механизмы безопасности

Встроенные цепочки

Упрощённые маршруты пакета:

Входящий локальный трафик:
PREROUTING → INPUT → локальный процесс

Исходящий локальный трафик:
локальный процесс → OUTPUT → POSTROUTING

Транзитный трафик:
PREROUTING → FORWARD → POSTROUTING

Просмотр правил

Показать правила основной таблицы filter:

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

Показать правила таблицы nat:

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

Вывести конфигурацию в форме команд:

sudo iptables -S
sudo iptables -t nat -S

Проверить реализацию команды:

iptables --version
sudo nft list ruleset

Если версия содержит nf_tables, команда использует совместимый backend nftables.


Добавление и удаление правил

Общая форма:

iptables [-t таблица] команда цепочка условия -j действие

Основные команды:

Опция Назначение
-A добавить правило в конец цепочки
-I вставить правило в начало или указанную позицию
-D удалить правило
-R заменить правило
-C проверить наличие правила
-F очистить цепочку или таблицу
-N создать пользовательскую цепочку
-X удалить пустую пользовательскую цепочку
-P установить политику встроенной цепочки
-Z обнулить счётчики

Разрешить входящие TCP-подключения к SSH:

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

Вставить правило первым:

sudo iptables -I INPUT 1 -p tcp --dport 22 -j ACCEPT

Проверить наличие правила:

sudo iptables -C INPUT -p tcp --dport 22 -j ACCEPT

Удалить правило по полному описанию:

sudo iptables -D INPUT -p tcp --dport 22 -j ACCEPT

Удалить правило по номеру:

sudo iptables -L INPUT -n --line-numbers
sudo iptables -D INPUT 3

После удаления нумерация меняется, поэтому перед следующей операцией снова просмотрите цепочку.


Условия выбора пакетов

Протоколы и порты

sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT
sudo iptables -A INPUT -p udp --dport 53 -j ACCEPT
sudo iptables -A INPUT -p icmp -j ACCEPT

Несколько портов:

sudo iptables -A INPUT -p tcp -m multiport --dports 80,443 -j ACCEPT

Диапазон портов:

sudo iptables -A INPUT -p tcp --dport 8000:8100 -j ACCEPT

IP-адреса и сети

Разрешить SSH только из административной сети:

sudo iptables -A INPUT -p tcp -s 192.168.10.0/24 --dport 22 -j ACCEPT

Заблокировать отдельный адрес:

sudo iptables -A INPUT -s 203.0.113.25 -j DROP

Условия назначения задаются через -d:

sudo iptables -A OUTPUT -p tcp -d 203.0.113.10 --dport 443 -j ACCEPT

Сетевые интерфейсы

sudo iptables -A INPUT -i lo -j ACCEPT
sudo iptables -A INPUT -i eth0 -p tcp --dport 443 -j ACCEPT
sudo iptables -A OUTPUT -o eth0 -p tcp --dport 443 -j ACCEPT

Состояния соединений

Модуль conntrack делает firewall stateful — учитывающим состояние соединений:

sudo iptables -A INPUT -m conntrack \
  --ctstate ESTABLISHED,RELATED -j ACCEPT

Основные состояния:

Состояние Значение
NEW новое соединение
ESTABLISHED пакет существующего соединения
RELATED новое соединение, связанное с существующим
INVALID пакет не удалось корректно классифицировать

Типовые правила:

sudo iptables -A INPUT -m conntrack \
  --ctstate ESTABLISHED,RELATED -j ACCEPT
sudo iptables -A INPUT -m conntrack --ctstate INVALID -j DROP

Правило ESTABLISHED,RELATED обычно размещают в начале цепочки. Оно разрешает ответный трафик для соединений, которые были разрешены ранее.


Действия над пакетами

Target Действие
ACCEPT разрешить пакет
DROP молча отбросить пакет
REJECT отклонить пакет и отправить ответ об ошибке
LOG записать информацию и продолжить обработку
RETURN вернуться из пользовательской цепочки
DNAT изменить адрес или порт назначения
SNAT изменить адрес источника
MASQUERADE динамический вариант SNAT
REDIRECT направить трафик на локальный порт

Примеры:

sudo iptables -A INPUT -p tcp --dport 23 \
  -j REJECT --reject-with tcp-reset
sudo iptables -A INPUT -p tcp --dport 25 -j DROP

DROP не отвечает отправителю. REJECT сообщает об отказе, поэтому клиент обычно получает ошибку быстрее.


Политики по умолчанию

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

sudo iptables -P INPUT DROP
sudo iptables -P FORWARD DROP
sudo iptables -P OUTPUT ACCEPT

Перед установкой INPUT DROP на удалённом сервере разрешите текущие соединения и SSH. Иначе можно потерять доступ. Желательно иметь резервную консоль и не закрывать существующую SSH-сессию до проверки новой.

Базовый набор правил веб-сервера:

# Сначала разрешения
sudo iptables -A INPUT -i lo -j ACCEPT
sudo iptables -A INPUT -m conntrack \
  --ctstate ESTABLISHED,RELATED -j ACCEPT
sudo iptables -A INPUT -m conntrack --ctstate INVALID -j DROP
sudo iptables -A INPUT -p tcp -s 192.168.10.0/24 \
  --dport 22 -m conntrack --ctstate NEW -j ACCEPT
sudo iptables -A INPUT -p tcp -m multiport \
  --dports 80,443 -m conntrack --ctstate NEW -j ACCEPT
sudo iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT

# Затем политики
sudo iptables -P INPUT DROP
sudo iptables -P FORWARD DROP
sudo iptables -P OUTPUT ACCEPT

Полностью блокировать ICMP без необходимости не рекомендуется: это мешает диагностике и некоторым сетевым механизмам.


Пользовательские цепочки

Пользовательские цепочки помогают группировать правила:

sudo iptables -N SSH_IN
sudo iptables -A INPUT -p tcp --dport 22 -j SSH_IN
sudo iptables -A SSH_IN -s 192.168.10.0/24 -j ACCEPT
sudo iptables -A SSH_IN -j RETURN

Удаление цепочки:

sudo iptables -F SSH_IN
# Сначала удалите все переходы на SSH_IN
sudo iptables -X SSH_IN

NAT и маршрутизация

Для маршрутизации пакетов между интерфейсами включите IPv4 forwarding:

sudo sysctl -w net.ipv4.ip_forward=1

Постоянная настройка в /etc/sysctl.d/99-forwarding.conf:

net.ipv4.ip_forward = 1

Применить:

sudo sysctl --system

MASQUERADE

Пусть lan0 подключён к сети 192.168.1.0/24, а eth0 — к интернету:

sudo iptables -t nat -A POSTROUTING \
  -s 192.168.1.0/24 -o eth0 -j MASQUERADE
sudo iptables -A FORWARD -i lan0 -o eth0 \
  -s 192.168.1.0/24 -j ACCEPT
sudo iptables -A FORWARD -i eth0 -o lan0 \
  -d 192.168.1.0/24 -m conntrack \
  --ctstate ESTABLISHED,RELATED -j ACCEPT

MASQUERADE обычно применяют при динамическом внешнем IP. Для статического адреса можно использовать SNAT:

sudo iptables -t nat -A POSTROUTING \
  -s 192.168.1.0/24 -o eth0 \
  -j SNAT --to-source 203.0.113.10

Проброс порта через DNAT

Проброс внешнего порта 8080 на 192.168.1.20:80:

sudo iptables -t nat -A PREROUTING -i eth0 \
  -p tcp --dport 8080 \
  -j DNAT --to-destination 192.168.1.20:80

sudo iptables -A FORWARD -i eth0 -o lan0 \
  -p tcp -d 192.168.1.20 --dport 80 \
  -m conntrack --ctstate NEW,ESTABLISHED,RELATED -j ACCEPT

sudo iptables -A FORWARD -i lan0 -o eth0 \
  -p tcp -s 192.168.1.20 --sport 80 \
  -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

Для работы нужны корректная маршрутизация и включённый IP forwarding.

Перенаправление на локальный порт

sudo iptables -t nat -A PREROUTING -i eth0 \
  -p tcp --dport 80 -j REDIRECT --to-ports 8080

Логирование

Target LOG не блокирует пакет, а только записывает информацию:

sudo iptables -A INPUT -m limit \
  --limit 5/min --limit-burst 10 \
  -j LOG --log-prefix "iptables denied: " --log-level 4
sudo iptables -A INPUT -j DROP

Ограничение частоты защищает журнал от переполнения. Просмотр сообщений:

sudo journalctl -k -f
sudo dmesg -w

На системах с rsyslog записи также могут находиться в /var/log/kern.log или /var/log/messages.

Счётчики пакетов и байтов:

sudo iptables -L -n -v
sudo iptables -Z

Сохранение и восстановление

Изменения обычно хранятся в памяти и могут исчезнуть после перезагрузки.

Экспорт правил:

sudo iptables-save > firewall.rules
sudo ip6tables-save > firewall6.rules

Восстановление:

sudo iptables-restore < firewall.rules
sudo ip6tables-restore < firewall6.rules

В Debian/Ubuntu можно использовать iptables-persistent:

sudo apt update
sudo apt install iptables-persistent
sudo netfilter-persistent save

Обычно IPv4- и IPv6-правила сохраняются в:

/etc/iptables/rules.v4
/etc/iptables/rules.v6

В других дистрибутивах механизм зависит от используемого firewall-стека. Не включайте одновременно несколько сервисов управления одними правилами.


IPv6 и ip6tables

IPv4-правила не защищают IPv6. Для него используется ip6tables:

sudo ip6tables -L -n -v --line-numbers
sudo ip6tables -A INPUT -m conntrack \
  --ctstate ESTABLISHED,RELATED -j ACCEPT

Если узел доступен по IPv6, настройте отдельный набор правил. Не блокируйте весь ICMPv6: он нужен для обнаружения соседей, Path MTU Discovery и других базовых функций IPv6.


Очистка правил

Очистить конкретную цепочку:

sudo iptables -F INPUT

Очистить таблицу filter и пользовательские цепочки:

sudo iptables -F
sudo iptables -X

Очистить таблицу nat:

sudo iptables -t nat -F
sudo iptables -t nat -X

Очистка правил и изменение политик могут немедленно оборвать сеть. Перед экспериментом сохраните конфигурацию:

sudo iptables-save > /root/iptables.before-change.rules

Откат:

sudo iptables-restore < /root/iptables.before-change.rules

Диагностика

Проверить интерфейсы и маршруты:

ip -br address
ip route

Проверить слушающие сервисы:

sudo ss -lntup

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

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

Проверить порт с другого узла:

nc -vz example.com 443
curl -v https://example.com/

Если порт разрешён, но недоступен, проверьте:

Docker, Kubernetes и libvirt могут автоматически создавать цепочки. Команды iptables -F и iptables -t nat -F способны нарушить работу их сетей.


iptables и nftables

nftables — современная замена классическому интерфейсу iptables. Во многих системах существуют варианты:

Проверка:

iptables --version
sudo nft list ruleset

Практические рекомендации:


Пример скрипта веб-сервера

#!/usr/bin/env bash
set -Eeuo pipefail

# Внимание: сначала протестируйте через резервную консоль.
iptables -F
iptables -X

iptables -P INPUT ACCEPT
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT

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

# Замените сеть на реальную административную сеть.
iptables -A INPUT -p tcp -s 192.168.10.0/24 \
  --dport 22 -m conntrack --ctstate NEW -j ACCEPT
iptables -A INPUT -p tcp -m multiport \
  --dports 80,443 -m conntrack --ctstate NEW -j ACCEPT
iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT

# Блокирующая политика устанавливается последней.
iptables -P INPUT DROP

Скрипт необходимо выполнять от root. Пример не учитывает специфические требования Docker, VPN, IPv6 и конкретной инфраструктуры.


Краткая памятка

# Просмотр
sudo iptables -L -n -v --line-numbers
sudo iptables -S
sudo iptables -t nat -L -n -v

# Разрешения
sudo iptables -A INPUT -i lo -j ACCEPT
sudo iptables -A INPUT -m conntrack \
  --ctstate ESTABLISHED,RELATED -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT
sudo iptables -A INPUT -p tcp -m multiport \
  --dports 80,443 -j ACCEPT

# Удаление правила
sudo iptables -D INPUT НОМЕР

# Политики
sudo iptables -P INPUT DROP
sudo iptables -P FORWARD DROP
sudo iptables -P OUTPUT ACCEPT

# Сохранение и восстановление
sudo iptables-save > firewall.rules
sudo iptables-restore < firewall.rules

# IPv6
sudo ip6tables -L -n -v --line-numbers

Правила безопасной работы