iptables (Русский)

From ArchWiki
Jump to: navigation, search

Tango-preferences-desktop-locale.pngЭта страница нуждается в сопроводителеTango-preferences-desktop-locale.png

Статья не гарантирует актуальность информации. Помогите русскоязычному сообществу поддержкой подобных страниц. См. Команда переводчиков 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

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

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

По умолчанию в 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 доступен в официальных репозиториях.

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