# iptables (Русский)

Ссылки по теме

- Firewalls
- Simple stateful firewall (Русский)
- Sysctl#TCP/IP stack hardening
- Sshguard
- Fail2ban
- Nftables

Эта страница нуждается в сопроводителе

Статья не гарантирует актуальность информации. Помогите русскоязычному сообществу поддержкой подобных страниц. См. Команда переводчиков ArchWiki

iptables представляет собой утилиту командной строки для настройки интегрированного в ядро Linux межсетевого экрана, разработанного в рамках проекта netfilter. Термин iptables также широко используется для обозначения самого межсетевого экрана Linux. Он может быть настроен напрямую с помощью iptables, либо с использованием одного из множества front-end утилит и графических оболочек. iptables используется для IPv4; для IPv6 существует ip6tables.

nftables была выпущена вместе с ядром Linux версии 3.13, и в один прекрасный день заменит iptables как основную утилиту для настройки межсетевого экрана Linux.

## Установка

Стандартная сборка ядра Arch Linux включает в себя поддержку iptables. Все, что потребуется – установить пользовательские утилиты, предоставляемые пакетом iptables из официальных репозиториев (пакет iproute2 из группы base зависит от iptables, поэтому пакет iptables уже должен быть установлен в вашей системе).

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

iptables используется для проверки, модификации, перенаправления и отбрасывания пакетов. Код для фильтрации пакетов IPv4 уже встроен в ядро. Он основан на наборе таблиц, каждая из которых служит конкретной цели. Таблицы составляют набор предопределенных цепочек, которые, в свою очередь, содержат список правил, организованных в определенном порядке. Каждое правило состоит из критерия (набора условий) и действия, которое применяется к пакетам, подпадающим под этот критерий, то есть, если все условия выполнены. iptables является утилитой, которая позволяет вам работать с этими цепочками и правилами. Большинство пользователей находят IP маршрутизацию в Linux сложной и запутанной, однако, на практике наиболее распространенные варианты использования (NAT и/или межсетевой экран для интернета) являются значительно менее сложными.

Ключ к пониманию принципа работы в этой блок-схеме. Слова в нижнем регистре наверху каждого блока являются именами таблиц, а слова в верхнем регистре – цепочками. Каждый пакет IP, который принимается на любом сетевом интерфейсе, проходит через эту блок-схему сверху вниз. Часто возникает заблуждение в том, что пакеты, приходящие, скажем, на внутренний интерфейс, обрабатываются каким-то иным образом нежели те, что приходят на интерфейс, подключенный к интернету. Пакеты со всех интерфейсов обрабатываются одинаково; это ваша задача в том, чтобы написать правила, которые будут обрабатывать их по-разному. Конечно, некоторые пакеты предназначены для локальных процессов, следовательно, они проходят через верхний блок на блок-схеме и останавливаются на блоке <Local Process> (локальный процесс), в то время как пакеты, которые генерируются локальными процессами, начинают проходить по схеме с блока <Local Process> и продолжают движение вниз. Более подробное описание этой блок-схемы вы можете найти на этой странице.

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

                                   XXXXXXXXXXXXXXXXXX
                                 XXX      Сеть      XXX
                                   XXXXXXXXXXXXXXXXXX
                                           +
                                           |
                                           v
    +---------------+             +-------------------+
    |таблица: filter| <---+       |таблица: nat       |
    |цепочка: INPUT |     |       |цепочка: PREROUTING|
    +-------+-------+     |       +--------+----------+
            |             |                |
            v             |                v
    [локальный процесс]   |         ***************          +----------------+
            |             +-------+  Маршрутизация  +------> |таблица: filter |
            v                       ***************          |цепочка: FORWARD|
     ***************                                         +-------+--------+
      Маршрутизация                                                  |
     ***************                                                 |
            |                                                        |
            v                       ***************                  |
    +---------------+     +------>   Маршрутизация   <---------------+
    |таблица: nat   |     |         ***************
    |цепочка: OUTPUT|     |                +
    +------+--------+     |                |
            |             |                v
            v             |      +---------------------+
    +---------------+     |      | таблица: nat        |
    |таблица: filter| +---+      | цепочка: POSTROUTING|
    |цепочка: OUTPUT|            +---------+-----------+
    +---------------+                      |
                                           v
                                   XXXXXXXXXXXXXXXXXX
                                 XXX      Сеть      XXX
                                   XXXXXXXXXXXXXXXXXX

### Таблицы

iptables содержит пять таблиц:

1. `raw` используется только для настройки пакетов, поэтому они освобождаются от отслеживания.
2. `filter` – это таблица по умолчанию, в которой сосредоточены все действия типичные для межсетевых экранов.
3. `nat` используется для преобразования сетевых адресов (например, проброс портов).
4. `mangle` служит для специальных преобразований пакетов (смотрите также Преобразованный пакет).
5. `security` используется для контроля доступа (например, SELinux – смотрите эту статью для получения подробной информации).

Скорее всего, вам нужно будет использовать только две из них: filter и nat. Остальные таблицы используются в сложных конфигурациях затрагивающих множество маршрутизаторов и точек маршрутизации и в любом случае выходят за рамки данной статьи.

### Цепочки

Таблицы состоят из цепочек, которые состоят из списка правил, расположенных в определенном порядке. Таблица по умолчанию, filter, содержит три встроенные цепочки: `INPUT`, `OUTPUT` и `FORWARD`, которые активируются в разных точках процесса фильтрации пакетов, как показано на диаграмме. Таблица nat включает стандартные цепочки `PREROUTING`, `POSTROUTING`, и `OUTPUT`.

Описания стандартных цепочек для других таблиц вы можете найти в руководстве `man 8 iptables`.

По умолчанию, все цепочки пустые и не содержат каких-либо правил. Ваша задача в том, чтобы добавить правила в цепочки, которые вы хотите использовать. У цепочек, однако, есть стандартное правило (политика), которое в основном имеет действие `ACCEPT`, но может (и должно) быть изменено на `DROP`, если вы хотите быть уверены в том, что даже если пакет проскочит сквозь набор ваших правил, он будет отброшен. Стандартное правило применяется к пакетам только тогда, когда они достигают конца цепочки, пройдя по остальным правилам.

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

### Правила

Фильтрация пакетов основана на правилах, каждое из которых задается набором условий и целевым действием. Если пакет соответствует всем условиям, к нему будет применено указанное действие. Типовые условия могут проверять, например, с какого интерфейса пришел пакет (например, eth0 или eth1), какого он типа (ICMP, TCP или UDP), или на какой порт пакет направляется.

Целевое действие указывается с помощью опций `-j` или `--jump`. Действием может быть одно из стандартных действий, действий расширений или переход на пользовательскую цепочку. Стандартные действия включают `ACCEPT`, `DROP`, `QUEUE` и `RETURN`. Примерами действия расширений могут быть `REJECT` и `LOG`. Если применено одно из стандартных действий, участь пакета решается незамедлительно и обработка пакета в таблице прекращается. Если действием указан переход на пользовательскую цепочку, и пакет проходит через нее, он возвращается на исходную цепочку и продолжает со следующего после перехода правила. Действия расширений могут быть терминальными (как стандартные действия) или нетерминальными (как пользовательские цепочки). Смотрите также `man 8 iptables-extensions` для получения более подробной информации.

### Прохождение по цепочке

Принятый на сетевом интерфейсе пакет проходит по цепочкам таблиц в порядке, изображенном на диаграмме. На первой точке маршрутизации (routing decision) принимается решение, направляется ли пакет на локальную машину (в таком случае пакет проходит через цепочки INPUT) или куда-то в другое место (в этом случае пакет проходит через цепочки FORWARD). На второй точке маршрутизации принимается решение, на какой сетевой интерфейс перенаправить исходящий пакет. В каждой цепочке по пути следования пакета, для каждого из правил, в которых удовлетворяются все условия, выполняется соответствующее действие. Три наиболее часто используемые действия – `ACCEPT`, `DROP` и переход на пользовательскую цепочку. В противоположность стандартным цепочкам, которые имеют действия по умолчанию, цепочки пользователя такого действия не имеют. Если не удовлетворены условия ни одного из правил пользовательской цепочки, пакет возвращается обратно в вызвавшую ее цепочку, как изображено здесь. Если в какое-то время выполнились все условия цепочки с действием `DROP`, пакет немедленно отбрасывается и над ним более не производится никаких действий. Обратите, однако, внимание, что если пакет принят действием `ACCEPT`, он принимается только на уровне текущей цепочки и всех вышележащих цепочках в текущем стеке вызовов. Он не обрабатывается более той стандартной цепочкой, которая инициировала последовательность переходов, но продолжает проходить по следующим цепочкам в других таблицах, в порядке, изображенном на диаграмме.

### Модули

Существует множество модулей которые могут использоваться для расширения возможностей iptables, такие как connlimit, conntrack, limit и recent. Эти модули дополняют iptables новой функциональностью для того, чтобы были возможны более сложные правила фильтрации.

## Настройка и запуск iptables

Для iptables есть служба systemd, которую, соответственно, можно запустить командой:

    # systemctl start iptables

Однако, эта служба не будет стартовать, пока отсутствует файл `/etc/iptables/iptables.rules`, который не создается пакетом iptables по умолчанию. Поэтому, чтобы запустить службу в первый раз, скопируйте в него "пустой" набор правил:

    # cp /etc/iptables/empty.rules /etc/iptables/iptables.rules
    # systemctl start iptables

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

    # systemctl enable iptables

### Настройка из командной строки

#### Отображение текущих правил

Вы можете проверить текущий набор правил и количество срабатываний каждого используя команду:

    # iptables -nvL

    Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
     pkts bytes target     prot opt in     out     source               destination

    Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
     pkts bytes target     prot opt in     out     source               destination

    Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
     pkts bytes target     prot opt in     out     source               destination

Если вывод команды выглядит как в примере выше, это значит, что правила не заданы, все пакеты пропускаются.

Чтобы показать номера строк при просмотре правил, запустите команду с опцией `--line-numbers`. Это полезно во время добавления и удаления отдельных правил.

#### Сброс правил

Вы можете сбросить правила iptables, используя эти команды:

    # 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
    # iptables -t security -F
    # iptables -t security -X
    # iptables -P INPUT ACCEPT
    # iptables -P FORWARD ACCEPT
    # iptables -P OUTPUT ACCEPT

Опция `-F` без аргументов просто очищает все цепочки в текущей таблице. Аналогично, опция `-X` удаляет все пустые пользовательские цепочки в таблице.

Отдельные цепочки могут быть очищены от правил или удалены указанием имени цепочки после опциям `-F` и `-X` соответственно.

#### Редактирование правил

Новые правила могут быть добавлены в конец цепочки либо на указанное по индексу место в цепочке.

Обратите внимание, что примеры здесь приведены из соображения, что ваш компьютер не выполняет роль маршрутизатора. Поэтому, первым делом, мы поменяем стандартное действие цепочки `FORWARD` с `ACCEPT` на `DROP`:

    # iptables -P FORWARD DROP

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

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

    # iptables -A INPUT -p tcp --dport 17500 -j REJECT --reject-with icmp-port-unreachable

    # iptables -nvL --line-numbers

    Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
    num   pkts bytes target     prot opt in     out     source               destination
    1        0     0 REJECT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:17500 reject-with icmp-port-unreachable

    Chain FORWARD (policy DROP 0 packets, 0 bytes)
    num   pkts bytes target     prot opt in     out     source               destination

    Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
    num   pkts bytes target     prot opt in     out     source               destination

Примечание: Здесь мы использовали действие `REJECT`, а не `DROP`, так как RFC 1122, раздел 3.3.8 требует, чтобы хосты возвращали ошибки ICMP всегда, когда это возможно вместо просто игнорирования отбрасываемых пакетов. На этой странице поясняется, почему почти всегда `REJECT` лучше чем `DROP`.

Теперь, скажем мы поменяли наш взгляд касательно Dropbox и решили установить его на наш компьютер. Мы также хотим использовать возможность синхронизации по локальной сети, но только с единственным компьютером в сети, IP-адрес которого нам известен, пусть это будет, например, `10.0.0.85`. Нам следует использовать ключ `-R` для того, чтобы заменить старое правило новым:

    # iptables -R INPUT 1 -p tcp --dport 17500 ! -s 10.0.0.85 -j REJECT --reject-with icmp-port-unreachable

    # iptables -nvL --line-numbers

    Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
    num   pkts bytes target     prot opt in     out     source               destination
    1        0     0 REJECT     tcp  --  *      *      !10.0.0.85            0.0.0.0/0            tcp dpt:17500 reject-with icmp-port-unreachable

    Chain FORWARD (policy DROP 0 packets, 0 bytes)
    num   pkts bytes target     prot opt in     out     source               destination

    Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
    num   pkts bytes target     prot opt in     out     source               destination

Теперь новое правило позволит хосту `10.0.0.85` отправить данные на порт `17500` нашего компьютера. Но теперь мы поняли, что наше правило не самое удачное: новые правила в этой цепочке смогут все равно заблокировать пакет. Мы не просто хотим пропустить пакет дальше по цепочке, а хотим сразу пометить его как принятый и пропустить в другие цепочки.

Здесь мы используем ключ `-I` для того, чтобы вставить новое правило в самое начало цепочки, перед старым:

    # iptables -I INPUT -p tcp --dport 17500 -s 10.0.0.85 -j ACCEPT -m comment --comment "Friendly Dropbox"

Мы установили также комментарий к правилу, который теперь отображается рядом с ним в списке:

    # iptables -nvL --line-numbers

    Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
    num   pkts bytes target     prot opt in     out     source               destination
    1        0     0 ACCEPT     tcp  --  *      *       10.0.0.85            0.0.0.0/0            tcp dpt:17500 /* Friendly Dropbox */
    2        0     0 REJECT     tcp  --  *      *      !10.0.0.85            0.0.0.0/0            tcp dpt:17500 reject-with icmp-port-unreachable

    Chain FORWARD (policy DROP 0 packets, 0 bytes)
    num   pkts bytes target     prot opt in     out     source               destination

    Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
    num   pkts bytes target     prot opt in     out     source               destination

Второе правило теперь можно переписать так, чтобы оно отбрасывало пакеты, приходящие на порт `17500` с других хостов:

    # iptables -R INPUT 2 -p tcp --dport 17500 -j REJECT --reject-with icmp-port-unreachable

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

    # iptables -nvL --line-numbers

    Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
    num   pkts bytes target     prot opt in     out     source               destination
    1        0     0 ACCEPT     tcp  --  *      *       10.0.0.85            0.0.0.0/0            tcp dpt:17500 /* Friendly Dropbox */
    2        0     0 REJECT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:17500 reject-with icmp-port-unreachable

    Chain FORWARD (policy DROP 0 packets, 0 bytes)
    num   pkts bytes target     prot opt in     out     source               destination

    Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
    num   pkts bytes target     prot opt in     out     source               destination

Обратите внимание, что пакеты на другие порты все еще будут беспрепятственно пропущены, так как они попадут под стандартное действие цепочки `INPUT` – `ACCEPT`.

### Файл настроек

По умолчанию в Arch Linux файл с правилами iptables располагается в `/etc/iptables/iptables.rules`. Эти правила, однако, не будут загружаться автоматически при старте системы, пока вы не включите службу `iptables.service`, которая загружает из него все правила:

    # systemctl enable iptables
    # systemctl start iptables

Правила iptables для IPv6 должны находиться в файле `/etc/iptables/ip6tables.rules`. Для этого файла, соответственно, существует служба `ip6tables.service`, которую тем же образом вы можете активировать, если вы используете IPv6.

Примечание: Файлы служб `iptables.service` и `ip6tables.service` в iptables версии 1.4.21-1 устарели. Начиная с systemd 214 в целях безопасности рекомендуется запускать межсетевые экраны перед `network-pre.target`, чтобы экран начинал работать перед установкой сети. В ожидании обновления пакета iptables, создайте каталог `/etc/systemd/system/iptables.service.d` и файл `00-pre-network.conf` в нем со следующим содержимым:

    [Unit]
    Before=network-pre.target
    [Install]
    RequiredBy=network-pre.target

Если система использует службу `ip6tables.service`, создайте аналогичный файл в каталоге `/etc/systemd/system/ip6tables.service.d`. Подробнее смотрите на страницах https://bugs.freedesktop.org/show_bug.cgi?id=79600, http://lists.freedesktop.org/archives/systemd-devel/2014-June/019925.html, а также FS#33478.

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

    # iptables-save > /etc/iptables/iptables.rules

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

    # systemctl reload iptables

Того же эффекта вы сможете достичь, используя следующую команду:

    # iptables-restore < /etc/iptables/iptables.rules

### Руководства по настройке iptables

- Простой межсетевой экран с внутренним состоянием
- Маршрутизатор

## Логирование

Действие `LOG` полезно для логирования пакетов, когда к нему применяется правило. В отличие от других действий вроде `ACCEPT` или `DROP`, `LOG` ничего не делает с пакетом, он просто продолжает свое продвижение по цепочке. Обычно условия для правила с действием `LOG` полностью дублируют условия какого-нибудь другого правила, которое следует логировать, а само логирующее правило идет непосредственно перед ним. Это значит, что, например, если вы хотите включить логирование всех отброшенных пакетов, вам следует добавить правило с действием `LOG` перед каждым правилом с `DROP`. Это не слишком удобно и плохо влияет на эффективность, поэтому вы можете вместо этого создать пользовательскую цепочку, скажем, `logdrop`:

    # iptables -N logdrop

И добавить в нее следующие правила:

    # iptables -A logdrop -m limit --limit 5/m --limit-burst 10 -j LOG
    # iptables -A logdrop -j DROP

В разделе #Ограничение скорости логирования дано разъяснение опций `limit` и `limit-burst`. Теперь, когда мы захотим отбросить пакет и добавить запись в лог об этом, мы просто выполним переход на цепочку `logdrop`:

    # iptables -A INPUT -m conntrack --ctstate INVALID -j logdrop

### Ограничение скорости логирования

Цепочка `logdrop` из предыдущего раздела использует модуль `limit`, который служит для предотвращения разрастания лога и падения эффективности при частых операциях записи на диск, ограничивая скорость логирования. Без этого, недобросовестный пользователь может быстро заполнить все свободное пространство вашего диска (как минимум, раздела `/var`), посылая вам мусорные пакеты.

Опция `-m limit` используется для вызова модуля `limit`. Вы можете использовать опции `--limit` чтобы указать среднюю допустимую скорость логирования и `--limit-burst` для определения ограничения количества пакетов, принятых за раз. Например, команда из предыдущего раздела,

    # iptables -A logdrop -m limit --limit 5/m --limit-burst 10 -j LOG

добавляет правило в цепочку `logdrop`, которое логирует все проходящие через него пакеты. За короткое время только 10 пакетов будут добавлены в лог, а затем максимальная скорость логирования не будет превышать 5 пакетов в минуту. Если скорость приходящих пакетов станет ниже 5 в минуту, со временем возможность принять 10 пакетов в пике восстановится. Эти опции работают подобно бассейну с постоянной скоростью оттока, но переменной скоростью притока. Если вода заливается очень быстро, бассейн переполняется и приток приходится сокращать (скорость логирования становится ограниченной значением `limit`, то есть, скорости оттока). Но, если дать возможность бассейну опустеть, он снова сможет принять большое количество воды за раз (равное значению `limit-burst`), пока вновь не заполнится.

### Просмотр логированных пакетов

Логированные пакеты сохраняются как сообщения ядра в журнале systemd.

Чтобы отобразить все пакеты, которые были залогированы с момента последнего перезапуска, выполните

    # journalctl -k | grep "IN=.*OUT=.*" | less

### syslog-ng

Если вы используете syslog-ng, вы можете настроить куда будут попадать записи лога iptables. Замените:

    filter f_everything { level(debug..emerg) and not facility(auth, authpriv); };

на

    filter f_everything { level(debug..emerg) and not facility(auth, authpriv) and not filter(f_iptables); };

Это предотвратит попадание вывода iptables в `/var/log/everything.log`.

Если вы также хотите чтобы лог iptables записывался в какой-нибудь другой файл вместо `/var/log/iptables.log`, вы можете просто изменить путь назначения `d_iptables` здесь же (`syslog-ng.conf`):

    destination d_iptables { file("/var/log/iptables.log"); };

### ulogd

ulogd – это специализированный демон логирования пакетов пользовательского уровня для netfilter, который может заменить стандартное действие `LOG`. Пакет ulogd доступен в официальных репозиториях.

## Смотрите также

- Iptables в Википедии
- Port knocking
- Официальный сайт iptables
- Руководство по iptables версии 1.2.2 от Оскара Андреассона
- статья iptables на Debian Wiki

Categories:

- Firewalls (Русский)
- Русский