Info
Content

iptables

Тоже хорошая статья (более короткая)
https://wiki.archlinux.org/index.php/Iptables_(Русский)
Большая и подробная статья на русском


rtfm-1
rtfm-2
rtfm-3
rtfm-4


Чтобы посмотреть текущие правила

iptables -nvL

Что бы сохранить правила в отдельный файл — используйте:

iptables-save > /root/iptables_bkp

Что бы восстановить из него:

iptables-restore < /root/iptables_bkp

Привилегированные порты - порты для использования которых нужно иметь права суперпользователя
Это порты с 0 по 1023

[vandud@desktop ~]$ nc -l -p 88
Error: Couldn't setup listening socket (err=-3) # не разрешило слушать привилегированный порт

[vandud@desktop ~]$ nc -l -p 1088               # прекрасно повисло на прослушивание порта
^C

При добавления правил нужно понимать что после рестарта они пропадут. Поэтому нужно сохранять их в /etc/iptables/iptables.rules


docker,ferm,iptables

При использовании ferm совместно с docker возникает проблема. Докер создает правила на ходу (при создании контейнеров), а ферм про них ничего не знает
Для решения этой проблемы можно использовать ferment (github.com/diefans/ferment)

Лучше использовать ferment-ng, так как в новых версия докера правила создаются иначе

Он ставится через pip и умеет генерировать ферм конфиг для докера

Достаточно в конец ferm.conf дописать

@include '/usr/local/bin/ferment docker config|';

Tables, chains, rules

Каждое правило состоит из критерия (набора условий), действия и счетчика пакетов попавших под это правило. Правило применяется к пакетам подходящим под все условия (критерия)

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

Цепочки - это упорядоченные последовательности правил (их можно разделить на базовые и пользовательские)

Базовые цепочки создаются по-умолчанию, пользовательские цепочки создаются пользователем)

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

Таблица - это совокупность базовых и пользовательских цепочек, объединенных общим фунуциональным назначением. Имена таблиц пишутся в нижнем регистре

2020-09-08-214650_1077x550_scrot.png

Таблицы:

  • raw - пакет проходит таблицу raw до передачи системе определения состояний (может использоваться для маркировки пакетов)
  • mangle - содержит правила модификации ip-пакетов и разные специальные преобразования
  • nat - подмена адреса отправителя или получателя, проброс портов, итд
  • filter - основная таблица, используется по-умолчанию если название таблицы не указано. Используется для фильтрации пакетов
  • security - используется для контроля доступа (SELinux)

Таблицы состоят из цепочек правил (правила в цепочках расположены в определенном порядке)

Например таблица по умолчанию filter содержит 3 встроенные цепочки:

  • INPUT
  • OUTPUT
  • FORWARD

А таблица nat содержит:

  • PREROUTING (для DNAT)
  • POSTROUTING (для SNAT)
  • OUTPUT

5 базовых цепочек:

  • PREROUTING - для изначальной обработки входящих пакетов
  • INPUT - для входящих пакетов, адресованных непосредственно локальному компьютеру
  • FORWARD - для проходящих (маршрутизируемых) пакетов
  • OUTPUT - для пакетов создаваемых локальным компьютером
  • POSTROUTING - для окончательной обработки исходящих пакетов

Также можно создавать собственных цепочки


У всех цепочек есть стандартное правило (политика). Оно применяется к пакету, когда он прошел все остальные правила. То есть политика - это правило по умолчанию


Критерий (условие)

Критерий это логическое условие, которое определяет, соответствует ли пакет этому правилу. В одном правиле может быть несколько критериев (они неявно объединяются логическим AND). Если критерий не указан, то предполагается что правило действует для всех пакетов

Критерий можно инвертировать знаком ! перед ним (логическое НЕ)
Восклицательный знак нужно ставить перед названием критерия, а не между названием критерия и его значением (так стало в новых версиях):
--option ! this - is deprecated
! --option this - is actual

Универсальные критерии

Универсальные критерии применимы к пакетам независимо от протокола транспортного уровня и они не требуют подключения модулей через ключ -m

  • -p - протокол (tcp, udp, icmp, all, etc). Также протокол можно указать числом или названием из /etc/protocols. После указания протола можно использовать специфичные для него критерии, например --sport, --dport или --icmp-type

  • -s - адрес отправителя. Можно указывать как имя, так и адрес (адрес можно указывать с маской в классическом формате или в CIDR). Можно указать более одного адреса разделяя их запятой (для каждого адреса будет созданно отдельное правило)
    Стоит понять что команда с множеством адресов перобразуется в несколько команд с одним адресом, поэтому например добавление правил в конец цепочки добавит правила в порядке перечисления адресов, а вставка в начало цепочки добавит правила в порядке обратном порядку перечисления адресов
    При использовании доменов нужно знать что они резолвятся в адреса единожды - при создании правила. Если в будущем адрес домена изменится, то на правило это не повлияет, в правиле останется старый адрес

    iptables -I FORWARD -s deimos.vandud.ru -j DROP     # команда (используется таблица forward из-за докера)
    DROP       all  --  185.211.247.85       0.0.0.0/0  # итоговое правило которое работает
    

    А вот если попробовать добавить правило для несуществующего хоста, то возникнет ошибка

    root@mars:~# iptables -I FORWARD -s deimos.vandaoeuud.ru -j DROP
    iptables v1.8.2 (nf_tables): host/network `deimos.vandaoeuud.ru' not found
    Try `iptables -h' or 'iptables --help' for more information.
    
  • -d - то же что и -s только destination address

    Интересный момент: если использовать одновременно и -d и -s, и в обоих критериях по несколько адресов, то в итоге будет созданно d*s правил. То есть все возможные комбинации

  • -i - входящий интерфейс. В конце имени интерфейса можно поставить +, тогда под него будут подходить все интерфейсы, имена которых начинаются на слово до плюса. Данный критерий можно использовать в цепочках PREROUTING, INPUT и FORWARD

  • -o - исходящий интерфейс. То же что и -i, но для цепочек FORWARD, OUTPUT и POSTROUTING

Критерии специфичные для протоколов

TCP
  • --sport - source-port
  • --dport - destination-port

Можно указывать как диапазон - --sport 1:20

  • --tcp-flags - позволяет отфильтровать пакеты по установленным в них tcp-флагам. Синтаксис:
    --tcp-flags маска установленные-флаги - маска это список флагов на которые смотрим, а установленные-флаги это те флаги, которые установлены на пакете (установленные флаги это подмножество маски, но не наоборот). Те флаги, которые не перечислены в маске - могут быть как установлены, так и нет, на них мы не смотрим вообще
    А вот подмножество флагов маска - установленные-флаги должно быть в неустановленном состоянии

  • --syn - позволяет отлавливать SYN-пакеты

  • --tcp-option - проверка наличия какого-либо tcp-параметра

UDP
  • --sport, --dport - аналогично соотв. критериям из tcp
IPv4
  • -f - позволяет отлавливать фрагменты пакетов начиная со второго

  • addrtype - позволяет проверить тип адреса источника и/или назначения с точки зрения подсистемы маршрутизации сетевого стека ядра (UNICAST, LOCAL, UNREACHABLE, etc.)

    • --src-type, --dst-type - пренадлежит ли src/dst адрес указанному типу
  • ecn - разные проверки ECN

  • ttl - проверка поля TTL, можно сравнивать TTL пакета с каким-то значением

ICMP
  • --icmp-type - проверка типа icmp-пакета (допустимые типы можно посмотреть командой iptables -p icmp -h)

Критерии состояния соединения - ConnTrack

В netfilter также есть механизм определения состояний. Он позволяет определить какому состоянию пренадлежит пакет

ConnTrack позволяет делать stateful-фильтрацию

Для протоколов в которых есть понятие "соединение" (tcp), conntrack активно его использует, тесно взаимодействуя с базовой сетевой подсистемой ядра Linux. А в тех протоколах где соединений нет (udp) он вводит его искусственно

У conntrack есть разные модули, которые помогают ему анализировать пакеты и понимать разные факты о них. Например протокол FTP использует два соединения, conntrack это понимает и, проанализировав пакеты управляющего соединения, знает куда будет устанавливаться передающее

С помощью утилит conntrack и iptstate можно наблюдать таблицы состояний соединений
Примерно то же самое что и conntrack показывает cat /proc/net/nf_conntrack

Типы состояний (критерий --ctstate):

  • NEW - новое соединение
  • ESTABLISHED - уже установленное соединение
  • RELATED - дополнительное к уже существующему соединению
  • INVALID - пакет должен принадлежать уже сущ. соединению, но такого соединения не зарегистрировано. Обычно такие пакеты дропают
  • UNTRACKED - пакет для которого было отключено отслеживание состояния (в таблице raw)
  • DNAT, SNAT - пакет был изменен подменой адреса

Типы статусов (критерий --ctstatus):

  • EXPECTED - ожидаемое соединение (например передающее соединение в FTP, conntrack проанализировал предыдущие пакеты и понял что скоро будет новое соединение)
  • CONFIRMED - подтвержденное соединение (что бы это не значило)
  • SEEN_REPLY - соединение по которому поступил ответ, то есть имеет место передача в обоих направлениях
  • ASSURED - полностью уставноленное соединение, этот статус присваивается после определенного колчества переданных данных. После присвоения этого статуса увеличивается conntrack timeout
  • NONE - нет статуса

Существует также понятие «связанных соединений». Например, когда в ответ на UDP-пакет с нашего хоста удаленный хост отвечает ICMP-пакетом icmp-port-unreachable, формально этот ответ является отдельным соединением, так как использует совсем другой протокол. netfilter отслеживает подобные ситуации и присваивает таким соединениям статус «связанных» (RELATED), позволяя корректно пропускать их через фильтры фаервола.


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

2020-09-08-232019_1202x527_scrot.png

На схеме видно что и входящие и исходящие пакеты первым делом попадают в таблицу raw

Эта таблица предназначена для выполнения действий с пакетами до их обработки системой conntrack
В ней невозможно использовать критерии связанные с conntrack'ом (т.к. до него очередь еще не дошла)


Критерий conntrack предоставляет:

  • --ctstate - позволяет выбрать состояние пакета
    Например:

    iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
    
  • --ctstatus - опеределение статуса соединения

  • --ctproto - протокол транспортного уровня. Аналогично критерию -p

  • --ctdir - направление пакета

    • ORIGINAL - от инициатора к отвечающему
    • REPLY - ответ инициатору
  • --ctorigsrc, --ctorigdst, --ctreplsrc, --ctrepldst + 4 таких же критерия, но с приставкой port справа - позволяют определять адреса/порты источника/назначения в разных направлениях

  • --ctexpire - позволяет указать оставшееся до таймаута время жизни соединения (принимает минимально оставшееся время, но также можно указать и диапазон). Важно помнить что таймауты для разных протоколов (и даже на разных стадиях одного протокола) - разные

Дополнительные критерии

Дополнительные критерии можно подгружать с помощью параметра -m. Можно подгружать сразу несколько модулей в одной команде (в одном правиле), но нельзя смешивать параметры (критерии) этих модулей, после каждого модуля строго его параметры
Также допустимо использовать отрицание для каждого критерия (параметра) в отдельности:

-m conntrack ! --ctstate NEW

Справку по модулю можно получить так:

iptables -m название_критерия -h

Список критериев:

  • multiport - позволяет указать несколько (до 15) портов
    iptables -A DOCKER-USER -p tcp -m multiport --dports 80,81,82,83,84,85,86 -j ACCEPT
    ACCEPT tcp -- anywhere anywhere multiport dports http,81,82,83,84,85,86
    Также этот критерий имеет параметр --ports, который объединяет sport и dport
  • iprange - позволяет указать диапазон адресов не являющихся подсетью
  • mark - позволяет выделять пакеты по маркировке
  • connmark - то же что и mark но для соединений
  • limit - позволяет ограничить количество пакетов в единицу времени
  • hashlimit - то же что и limit но позволяет применять одно правило для групп хостов, подсетей
  • connlimit - позволяет ограничивать количество одновременно открытых соединений с каждого IP-адреса
  • connbytes - позволяет ограничивать количество переданных байт или пакетов
  • quota - позволяет задать квоту в байтах для данного конкретного правила
    Chain INPUT (policy DROP 13166 packets, 684K bytes)
     pkts bytes target     prot opt in     out     source               destination         
        3   171 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp  dpt:33 quota: 200 bytes
        9   780 DROP       tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:33
    
  • length - ограничение по размеру пакета (размер пакета протокола сетевого уровня (IP, IPv6) за вычетом размера заголовков сетевого уровня)
  • recent - мощный критерий, умеет много всего относительно запоминания информации о проходящих через него пакетах и принятия решения на основе собранных знаний. С помощью него можно строить крутые вещи
  • u32 - супер штука для глубокого анализа трафика. Для него нужно писать программы на местном языке

Если действия не указано, то правило будет работать как счетчик

Путь пакета по цепочкам и таблицам

Схема прохождения пакета:

2020-09-08-215602_1223x368_scrot.png

Чуть более удобная схема:

2020-09-08-232019_1202x527_scrot.png

Как видно, пакет вначале проходит по цепочкам PREROUTING в трех таблицах (raw, mangle, nat)
Важно понимать, что это три разные цепочки (с одинаковым именем) в трех разных таблицах

Далее, пройдя по трем цепочкам, пакет уходит в цепочки INPUT или FORWARD, таблиц mangle и filter

И т.д.

Не важно с какого интерфейса был получен пакет. В каждом случае он обрабатывается одинакого и проходит одинаковый путь по таблицами и цепочкам


Действие над пакетом указывается через ключ -j или --jump. В него передается либо стандартное действие, либо действие расширения, либо переход на пользовательскую цепочку
Примеры стандартных действий:

  • ACCEPT
  • DROP
  • QUEUE
  • RETURN

Примеры действий расширений:

  • REJECT
  • LOG

Если выбрано стандартное действие, то участь пакета ясна (он допускается, отбрасывается, итд)

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

А действия расширений могут вести себя и как переход на пользовательскую цепочку, и как стандартное действие (зависит от расширения)
Более правильными словами: действия расширений могут быть терминальными (как стандартные действия) или нетерминальными (как пользовательские цепочки)
Более подробно про расширения man iptables-extensions


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


Также важно, если пакет отброшен действием DROP, то он отброшен окончательно. Но если пакет принят действием ACCEPT, то он принят на уровне этой таблицы и цепочки в ней. Он просто продолжает свой путь по следующим цепочкам (как указано на общей схеме)


Комментарии

Можно добавлять комментарии к правилам
Это делается через модуль comment и его параметр --comment (max-len 256 символов)
Пример:

iptables -A DOCKER-USER -p tcp --dport 77 -j DROP -m comment --comment "supper comment"

Результат:

Chain DOCKER-USER (1 references)
target     prot opt source               destination         
RETURN     all  --  anywhere             anywhere            
DROP       tcp  --  anywhere             anywhere             tcp dpt:77 /* supper comment */

Основные действия

Работа с цепочками

  • iptables -N chain - New chain

  • -F - Flush chain
  • -L [chain-name] - List all rules
  • -Z - Zero the packet and byte counters in all chains

  • -P - Set Policy for built-in chain

  • -X - Delete user-defined chain. There must be no references to the chain
  • -E - Rename user-chain

Работа с правилами

  • -I chain-name [rulenum] - вставить правило в начало или в указанную позицию (при вставке в указанную позицию, уже существующее на этой позиции правило сдвигается вниз)
  • -R chain-name rulenum - заменить правило с указанным номером
  • -A - добавить в конец
  • -C - проверить что такое правило уже есть
  • -D - удалить правило по описанию или по номеру

Действие (target)

  • ACCEPT – принять пакет, и передать следующей цепочке (или приложению, или передать для дальнейшего роутинга)

  • DNAT — (Destination Network Address Translation) используется для преобразования адреса места назначения в IP заголовке пакета; если пакет подпадает под критерий правила, выполняющего DNAT, то этот пакет, и все последующие пакеты из этого же потока, будут подвергнуты преобразованию адреса назначения и переданы на требуемое устройство, хост или сеть; действие DNAT может выполняться только в цепочках PREROUTING и OUTPUT таблицы nat, и во вложенных под-цепочках

    важно запомнить, что вложенные подцепочки, реализующие DNAT не должны вызываться из других цепочек, кроме PREROUTING и OUTPUT

  • DROP – просто «сбрасывает» пакет и IPTABLES «забывает» о его существовании; «сброшенные» пакеты прекращают свое движение полностью, т.е. они не передаются в другие таблицы, как это происходит в случае с действием ACCEPT

  • LOG — действие, которое служит для журналирования отдельных пакетов и событий; в журнал могут заноситься заголовки IP пакетов и другая полезная информация; информация из журнала может быть затем прочитана с помощью dmesg или syslogd, либо с помощью других программ; обратите ваше внимание так же на цель ULOG, которое позволяет выполнять запись информации не в системный журнал, а в базу данных MySQL и т.п.

  • MARK — используется для установки меток для определенных пакетов; это действие может выполняться только в пределах таблицы mangle; установка меток обычно используется для нужд маршрутизации пакетов по различным маршрутам, для ограничения трафика и т.п.; «метка» пакета существует только в период времени пока пакет не покинул брандмауэр, т.е. метка не передается по сети

  • MASQUERADE — в основе своей представляет то же самое, что и SNAT только не имеет ключа --to-source; причина тому то, что маскарадинг может работать, например, с dialup подключением или DHCP, т.е. в тех случаях, когда IP адрес присваивается устройству динамически; если у вас имеется динамическое подключение, то нужно использовать маскарадинг, если же у вас статическое IP подключение, то лучше будет использование SNAT

  • MIRROR — может использоваться вами только для экспериментов и в демонстрационных целях, поскольку это действие может привести к «зацикливанию» пакета и в результате к «Отказу от обслуживания»; в результате действия MIRROR в пакете, поля source и destination меняются местами и пакет отправляется в сеть; допускается использовать только в цепочках INPUT, FORWARD и PREROUTING, и в цепочках, вызываемых из этих трех

  • QUEUE – ставит пакет в очередь на обработку пользовательскому процессу; оно может быть использовано для нужд учета, проксирования или дополнительной фильтрации пакетов

  • REDIRECT — выполняет перенаправление пакетов и потоков на другой порт той же самой машины; можно пакеты, поступающие на HTTP порт перенаправить на порт HTTP-proxy; удобен для выполнения «прозрачного» проксирования (transparent proxy), когда машины в локальной сети даже не подозревают о существовании прокси; может использоваться только в цепочках PREROUTING и OUTPUT таблицы nat

  • REJECT — используется, как правило, в тех же самых ситуациях, что и DROP, но в отличие от DROP, команда REJECT выдает сообщение об ошибке на хост, передавший пакет

  • RETURN — прекращает движение пакета по текущей цепочке правил и производит возврат следующему правилу в вызывающей (предыдущей) цепочке, если текущая цепочка была вложенной, или, если текущая цепочка лежит на самом верхнем уровне (например INPUT), то к пакету будет применена политика по-умолчанию; обычно, в качестве политики по-умолчанию назначают действия ACCEPT или DROP

  • SNAT — используется для преобразования сетевых адресов (Source Network Address Translation), т.е. изменение исходящего IP адреса в IP в заголовке пакета; SNAT допускается выполнять только в таблице nat, в цепочке POSTROUTING; если первый пакет в соединении подвергся преобразованию исходящего адреса, то все последующие пакеты, из этого же соединения, будут преобразованы автоматически и не пойдут через эту цепочку правил

  • TOS — используется для установки битов в поле Type of Service IP заголовка; поле TOS содержит 8 бит, которые используются для маршрутизации пакетов; важно помнить, что данное поле может обрабатываться различными маршрутизаторами с целью выбора маршрута движения пакета; в отличие от MARK, сохраняет свое значение при движении по сети, а поэтому может использоваться для маршрутизации пакета; лучше всего использовать это поле для своих нужд только в пределах WAN или LAN

  • TTL — используется для изменения содержимого поля Time To Live в IP заголовоке

  • ULOG — система журналирования пакетов, которая заменяет традиционное действие LOG, базирующееся на системном журнале; при использовании этого действия, пакет, через сокеты netlink, передается специальному демону который может выполнять очень детальное журналирование в различных форматах (обычный текстовый файл, база данных MySQL и пр.), может формировать отчёты в CSV, XML, Netfilter’s LOG, Netfilter’s conntrack; подробнее смотрите на домашней странице проекта


No Comments
Back to top