# iptables - правила netfilter (legacy) _Команды · LinuxLab Knowledge Base_ **TL;DR:** iptables = userland для netfilter. 5 таблиц (filter/nat/mangle/raw/security), цепочки INPUT/OUTPUT/FORWARD/PRE/POSTROUTING, jump-targets ACCEPT/DROP/MASQUERADE. Legacy, но в проде ещё везде. ## Зачем знать iptables в 2026 RHEL 8/9 и Debian 11/12 формально перешли на nftables, но `iptables`-команда на них зачастую - просто frontend (`iptables-nft`), и старые скрипты работают. На Alpine, Ubuntu LTS до 22.04, embedded-системах и в куче legacy - всё ещё чистый iptables. Docker до сих пор пишет правила через iptables. Знать его - читать прод. Новый код пиши на [[cmd-nft|nft]]: один синтаксис вместо iptables/ip6tables/arptables/ebtables, поддержка sets, namespaces, atomic update. ## Архитектура: таблицы и цепочки Пакет идёт через **netfilter hooks** в ядре. iptables навешивает на hook'и **цепочки** (chains), сгруппированные в **таблицы** (tables) по предназначению: | Таблица | Что делает | |---------|------------| | **filter** | разрешать/блокировать (default) | | **nat** | трансляция адресов (SNAT, DNAT, [[nat|MASQUERADE]]) | | **mangle** | модификация заголовков (TOS, TTL, MARK) | | **raw** | до conntrack (NOTRACK для исключений) | | **security** | SELinux MAC-метки | Стандартные цепочки и где они срабатывают: ``` ┌─PREROUTING─→─routing─┬─FORWARD──→─POSTROUTING─┐ in iface ────┤ │ ├──→ out iface └────────────────────────→ INPUT → local proc OUTPUT ``` - **PREROUTING** (raw, mangle, nat) - сразу при входе - **INPUT** (filter, mangle) - предназначенные локально - **OUTPUT** (raw, mangle, nat, filter) - локально сгенерированные - **FORWARD** (filter, mangle) - транзитные (нужен [ip-forwarding](/kb/ip-forwarding.md)) - **POSTROUTING** (mangle, nat) - перед отправкой ## Базовый синтаксис ``` iptables [-t TABLE] -A CHAIN [-s SRC] [-d DST] [-p PROTO] [--dport N] [-i IFACE] -j TARGET ``` | Опция | Что | |-------|-----| | `-A CHAIN` | append - добавить в конец | | `-I CHAIN [N]` | insert на позицию N (1 - в начало) | | `-D CHAIN N` | delete по номеру; или `-D CHAIN <правило>` точно | | `-L [CHAIN]` | list (обычно с `-n -v --line-numbers`) | | `-F [CHAIN]` | flush - удалить все правила | | `-P CHAIN POLICY` | дефолтная политика (ACCEPT/DROP) | | `-N CHAIN` | создать кастомную цепочку | | `-X CHAIN` | удалить пустую цепочку | ## Targets (jump) | Target | Что | |--------|-----| | `ACCEPT` | пропустить | | `DROP` | молча отбросить | | `REJECT` | отбросить и послать ICMP unreachable | | `LOG` | в dmesg/syslog (`--log-prefix`) | | `MASQUERADE` | SNAT с автоопределением src-IP | | `SNAT --to-source IP` | source NAT | | `DNAT --to-destination IP[:PORT]` | destination NAT | | `MARK --set-mark N` | пометить для policy-routing | | `<кастомная-цепочка>` | jump в свою цепочку | | `RETURN` | выйти из текущей цепочки | ## Простые рецепты ### Базовый firewall на хосте ```bash iptables -P INPUT DROP iptables -P FORWARD DROP iptables -P OUTPUT ACCEPT iptables -A INPUT -i lo -j ACCEPT # localhost iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT iptables -A INPUT -p tcp --dport 22 -j ACCEPT # ssh iptables -A INPUT -p tcp --dport 443 -j ACCEPT # https iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT # ping ``` Без conntrack-правила исходящие соединения не получат ответы - первое что забывают. ### NAT для контейнерной сети ```bash echo 1 > /proc/sys/net/ipv4/ip_forward # см. [ip-forwarding](/kb/ip-forwarding.md) iptables -t nat -A POSTROUTING -s 172.17.0.0/16 -o eth0 -j MASQUERADE ``` ### Проброс порта ```bash iptables -t nat -A PREROUTING -p tcp --dport 8080 -j DNAT --to-destination 10.0.0.5:80 iptables -A FORWARD -p tcp -d 10.0.0.5 --dport 80 -j ACCEPT ``` ### Rate-limit брутфорса ```bash iptables -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW \ -m recent --set --name SSH iptables -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW \ -m recent --update --seconds 60 --hitcount 5 --name SSH -j DROP ``` Не больше 5 новых SSH-соединений с одного IP за минуту. ## Сохранение и восстановление Изменения через `iptables -A` живут до перезагрузки. Сохранять надо явно: ```bash iptables-save > /etc/iptables/rules.v4 # экспорт текущего состояния iptables-restore < /etc/iptables/rules.v4 # импорт (атомарно) ip6tables-save > /etc/iptables/rules.v6 # IPv6 - отдельная команда! ``` Distribution-специфика: - **Debian/Ubuntu**: `apt install iptables-persistent` - сохраняет в `/etc/iptables/rules.v[46]`, грузит на boot - **RHEL**: `iptables-services`, `systemctl enable iptables ip6tables` ## iptables-legacy vs iptables-nft На современных дистрибутивах команда `iptables` - shim над nftables: ```bash iptables --version # iptables v1.8.7 (nf_tables) ← nft бэкенд # iptables v1.8.7 (legacy) ← старый xt_-бэкенд ``` Смешивать нельзя: правила в legacy и в nft - разные пространства. Если Docker и kube-proxy пишут разными - можно получить дыру в файрволе. Решение: `update-alternatives --config iptables` либо явный `iptables-legacy` / `iptables-nft`. ## ip6tables и ebtables IPv6 - отдельный набор правил, отдельная команда: ```bash ip6tables -A INPUT -p tcp --dport 22 -j ACCEPT ``` Ethernet bridge-фильтр - `ebtables` (на L2). nftables всё это объединяет в одну `nft` команду - сильное преимущество. ## Когда что-то пошло не так - **Закрыл себе SSH** - первое правило `INPUT DROP` без явного разрешения 22-го. Лекарство: `at +5 'iptables -F'` ДО любого rules-up, или работа через console/serial. - **`Permission denied`** - iptables нужен root и cap NET_ADMIN. - **Правило не срабатывает** - проверь порядок: `iptables -L INPUT -n -v --line-numbers`. Первый match выигрывает; счётчик байтов покажет что прошло. - **NAT не работает** - забыли `ip_forward=1`, забыли `MASQUERADE` или забыли разрешить FORWARD. - **Conntrack overflow** - `dmesg | grep nf_conntrack` показывает `table full`. Увеличь `nf_conntrack_max` через [[cmd-sysctl|sysctl]] или вынь stateful trackable траф из conntrack через `-t raw -j NOTRACK`. - **iptables-restore тихо не применил часть** - синтаксическая ошибка в середине файла; читает построчно, до ошибки применяется атомарно, после - нет. Проверь exit-code. ## Альтернативы - **[[cmd-nft|nftables]]** - современный преемник - **firewalld** - high-level demon, абстракция над nft/iptables (RHEL default) - **ufw** - simplified frontend над iptables (Ubuntu) - **shorewall** - старый-добрый rules-compiler ## Команды ```bash iptables -L INPUT -n -v --line-numbers ``` Показать INPUT с числовыми адресами, счётчиками и номерами строк ```bash iptables -t nat -L -n -v ``` NAT-таблица - кто делает MASQUERADE/DNAT ```bash iptables -A INPUT -p tcp --dport 22 -j ACCEPT ``` Разрешить SSH - первое правило при настройке хост-firewall ```bash iptables -t nat -A POSTROUTING -s 10.0.0.0/24 -o eth0 -j MASQUERADE ``` NAT для подсети 10.0.0.0/24 на исходящем eth0 ```bash iptables-save > /etc/iptables/rules.v4 ``` Snapshot текущих правил - сохраняй ПЕРЕД любыми изменениями ```bash iptables -F && iptables -X && iptables -P INPUT ACCEPT ``` Сбросить всё к дефолту ACCEPT - локально для отладки, не на проде! ```bash iptables -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW -m limit --limit 3/min -j ACCEPT ``` Rate-limit новых SSH-соединений до 3 в минуту - простой anti-bruteforce ## См. также - [nft - современный файрвол (nftables)](/kb/cmd-nft.md) - [firewalld vs nftables - что выбрать](/kb/firewalld-vs-nftables.md) - [Conntrack - память Linux о всех сетевых соединениях](/kb/conntrack.md) - [NAT и masquerade](/kb/nat.md) - [IP forwarding - превратить хост в роутер](/kb/ip-forwarding.md) - [Kubernetes Service и Ingress - сетевая публикация подов](/kb/kubernetes-services-and-ingress.md)