notes/iptables.md

14 KiB
Raw Permalink Blame History

iptables


Таблицы

  • filter - основная таблица для фильтрации пакетов, используется по умолчанию;
  • nat - управление преобразованием сетевых адресов;
  • mangle - модификация и замена содержимого сетевых пакетов вне контекста NAT и фильтрации пакетов;
  • raw - предназначена для работы с сырыми пакетами, пока они еще не прошли обработку

Цепочки

Цепочки бывают базовые/встроенные и пользовательские (можно создать самому).

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

  • INPUT - входящий трафик (адресованный локальному хосту);
  • FORWARD - транзитный трафик поступающий на локальную машину с целью передачи его на другую машину (трафик передаваемый в docker контейнер тоже будет считаться транзитным), при этом транзитный трафик проходит в обоих направлениях;
  • OUTPUT - исходящий из локального хоста трафик

Правила - условия и действия

Правило - состоит из условия/критерия (если нет значит применяется ко всему трафику) действия (может не быть) и счетчика (для учета пакетов попавших под правило).

основные действия с правилами:

  • -A - добавить правило в цепочку;
  • -С - проверить все правила;
  • -D - удалить правило;
  • -I - вставить правило с нужным номером;
  • -L - вывести все правила в текущей цепочке;
  • -S - вывести все правила;
  • -F - очистить все правила;
  • -N - создать цепочку;
  • -X - удалить цепочку;
  • -P - установить действие по умолчанию.

Условия:

  • -p - протокол (TCP, UDP, ICMP, ALL);
  • -s - ip адрес источника (можно с маской 10.0.0.0/24), допускается отрицание (т.е. все кроме) -s ! 10.0.0.0/24;
  • -d - ip адрес получателя (аналогично -s);
  • -i - интерфейс с которого пришел пакет (только для INPUT, FORWARD, PREROUTING), например ens3, допускается указать ens+ что означает все имена интерфейсов начинающиеся с заданной строки, допускается отрицание -i ! ens+;
  • -o - интерфейс локального хоста, из которого выходит трафик (только для OUTPUT, FORWARD, PREROUTING);
  • --sport - порт с которого был отправлен TCP/UDP пакет (допускаются имена служб из /etc/services), поддерживаются диапазоны вида 20:80 что значит от 20 до 80 порта, так же можно опустить одно из значений :80 (от 0 до 80) или 20: (от 20 до 65535), отрицание поддерживается даже к диапазонам --sport ! 20:80;
  • --dport - аналогично --sport только речь идет про порт, которому адресован пакет;
  • --icmp-type - тип ICMP сообщения (номер или название), поддерживается отрицание. RFC 792 или iptables --protocol icmp --help;
  • -m mac --mac-source - MAC адрес устройства передавшего пакет, поддерживается отрицание;
  • -m state --state - состояние соединения:
    • INVALID - неизвестное соединение, возможно ошибочное;
    • NEW - новое соединение;
    • ESTABLISHED - уже установленное соединение;
    • RELATED - пакет принадлежит уже существующему соединению, но он отправляется по новому
  • -m ttl - Time To Live:
    • --ttl-eq N - TTL пакета равен N;
    • --ttl-lt N - TTL пакета меньше N;
    • --ttl-gt N - TTL пакета больше N
  • -m multiport - указать в правиле несколько портов, диапазон или набор:
    • -m multiport --dports 8080,22,80 - применяется к указанным портам;
    • -m multiport --dports 1024:65535 - применяется к диапазону портов

Действия:

  • ACCEPT - пакет принят в текущей таблице;
  • DROP - пакет сбрасывается и перестает движение в системе;
  • LOG - пакет журналируется и продолжает дальнейшие движение по цепочке правил и таблицам (рассмотрим ниже)
  • REJECT - аналогично DROP только отдает сообщение об ошибке на хост отправителя (работает на всех цепочках таблицы filter):
    • --reject-with - тип ответа, RFC 793 или iptables -j REJECT -h
  • RETURN - возврат пакета в вышестоящую цепочку для применения действия по умолчанию, при отсутствии вышестоящей цепочки применится действие по умолчанию

Просмотр

  • Просмотр текущих правил
iptables -L

только для конкретной цепочки

iptables -L INPUT

более наглядно

iptables -vnL --line-numbers
  • Список текущих правил
iptables -S
  • Очистка правил
 iptables -F

очистка правил конкретной цепочки

 iptables -F INPUT

Стоит иметь ввиду, что очистка правил не изменяет правило по-умолчанию, если оно установлено в DROP, после очистки всех правил можно потерять доступ к узлу.

  • Для полной очистки правил и отключения фильтрации
iptables -P INPUT ACCEPT
iptables -P OUTPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -F

Управление правилами и цепочками

Добавить правило (разрешить весь трафик с tun интерфейсов) в конец цепочки INPUT (-A, --append):

iptables -A INPUT -i tun+ -j ACCEPT

Вставить правило в позицию 2 цепочки INPUT (-I, --insert):

iptables -I INPUT 2 -i lo -j ACCEPT

Установить политику по умолчанию DROP для цепочки INPUT (-P, --policy):

iptables -P INPUT DROP

Создание новой цепочки правил:

iptables -N LOGGING

Примеры

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

Разрешим трафик на локальный DNS сервер, без этого могут быть долгие подключения по ssh:

iptables -A INPUT -p udp -m udp --dport 53 -j ACCEPT

Разрешим движение трафика из интерфейсов создаваемых Docker (при политиках по умолчанию DROP, контейнеры не смогут общаться с другими интерфейсами):

iptables -A INPUT -i br+ -j ACCEPT

Разрешим любой входящий трафик из localhost и откроем http/https порты (80/443), например для случая когда у нас есть веб-сервер и наши сайты должны быть доступны снаружи:

iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT

Если не разрешить входящий трафик от localhost то могут быть странные задержки с ответами, а при дебаге можно увидеть отклоенные пакеты от 127.0.0.1

Теперь локальный DNS на 53 порту доступен, docker контейнеры тоже, с localhost трафик разрешен, и для внешнего мира открыты 80 и 443 порты для наших сайтов. Но это все только для установления соединения и рукопожатия. Теперь нам нужно разрешить все установленные и связанные с ними соединения чтобы трафик действительно пошел (еще вот):

iptables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT

Пример первоначальной настройки

iptables -P INPUT ACCEPT
iptables -P OUTPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -F

iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A INPUT -p tcp -m multiport --dports 8080,22,80 -j ACCEPT
iptables -A INPUT -p udp --dport 69 -j ACCEPT
iptables -A INPUT -p tcp --dport 5000:5678 -j ACCEPT

iptables -P INPUT DROP

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

Сброс всех правил цепочки filter

iptables -P INPUT ACCEPT
iptables -P OUTPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -F

Отладка

Логирование отклоненных пакетов journald

Работа iptables происходит на уровне ядра ОС, соответственно все события логируются также на уровне ядра.

Добавляем правило логирования каждого пакета с префиксом:

iptables -A INPUT -j LOG --log-level info --log-prefix "IPTABLES-DROP: "

Вывод сообщений ядра

journalctl -k

или

journalctl -k -f

Логирование отклоненных пакетов Rsyslog

Полезно иметь возможно отладить свои правила, экономия времени и iptables становится понятнее.

Суть отладки правил iptables такова:

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

Создание новой цепочки:

iptables -N LOGGING

Добавляем правило логирования каждого пакета с префиксом:

iptables -A LOGGING -j LOG --log-prefix  "ipt denied: "

Отклоняем пакет:

iptables -A LOGGING -j DROP

В цепочку, откуда будут приходить пакеты для отклонения добавляем новое правило перенаправления в новую цепочку логирования:

iptables -A INPUT -j LOGGING

Теперь добавим конфиг rsyslog:

nano /etc/rsyslog.d/10-iptables.conf

Вставим следующий текст:

:msg, contains, "ipt denied: " -/var/log/iptables.log
& ~

Сохраним и перезагрузим демона rsyslog:

service rsyslog restart

Теперь откроем файл и будем следить за 20 последних строк:

echo > /var/log/iptables.log
tail -f -n 20 /var/log/iptables.log