Найти тему
ИнфоКомм

Курс "Сети и безопасность в Linux" 2-й блок: Продвинутая настройка безопасности в Linux. NAT (погружение)

Оглавление

Всем привет! Как и обещал начало второго блока.

2.1 Iptables/netfilter

Netfilter - важнейший модуль ядра Linux, отвечающий за безопасность и манипуляции с сетевыми пакетами.

Iptables - это интерфейс управления netfilter-ом. Этакий front end.

Iptables “говорит” ядру, что необходимо сделать с пакетом который входит, проходит транзитом, выходит в/через/из Linux box (так мы будем называть машину с установленной Linux).

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

Если отвечать в двух словах о том как это работает, то звучать это будет так:

Админ инструктирует ядро правилами (rules), указывая критерии интересующего трафика и что с ним делать;

Linux box анализирует заголовки входящих пакетов;

Если анализируемый пакет попадает под правило к нему применяется указанное действие.

Общее описание дает ложное представление о простоте. Но все довольно не тривиально. Не пугайтесь! Я проделал большую работу, чтобы все стало более менее понятно и у вас сложилась та самая картинка!

Итак…

Давайте начнем с общей схемы. В интернете много схем и в основной своей массе они пугают и путают. Но я нашел ту самую схему! Она действительно позволяет увидеть логику и она запоминается. Делюсь ею с вами и указываю источник:

http://linux-ip.net/nf/nfk-traversal.png

По умолчанию в ядре загружено три таблицы:

mangle - манипуляции с полями пакетов кроме src, dst и port (коричневый кружок)

nat - NAT/PAT (синий кружок)

filter - фильтрация (бордо).

По умолчанию отображается таблица filter. Для того чтобы поработать с таблицами nat и mangle необходимо указать таблицу через опцию -t:

Выведем содержимое таблицы filter, nat и mangle:

Примечание: Если смотреть на схему, то вы увидите еще одну таблицу conntrack. Ее в ядре по умолчанию нет.

-2
-3
-4

INPUT, FORWARD, OUTPUT, PREROUTING, POSTROUTING - это все в терминах iptables/netfilter цепочки обработки трафика. По факту это то куда будут помещаться правила. Если вы сетевик, то это аналог ACL (access control list).

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

1 Пакет попадает в сетевой интерфейс (ip_rcv):

1.1 Пакет попадает в цепочку PREROUTING - mangle;

1.2 Пакет попадает в цепочку PREROUTING - nat;

1.3 Далее заголовки пакета передаются процессу routing/forwarding где принимается решение передавать пакет в цепочку FORWARDING (транзит) или в цепочку INPUT (на прикладной уровень системе);

2 Если на этапе 1.3 ядро определило, что пакет предназначается прикладному уровню системы - INPUT(локальная система), то пакет обрабатывается начиная с 2.1, если пакет адресован другому узлу - FORWARDING(транзит), то идем сразу к пунктам 3.x:

2.1 Пакет попадает в цепочку INPUT - mangle;

2.2 Пакет попадает в цепочку INPUT - filter;

2.3 Ядро принимает решение в какой сокет маршрутизировать пакет и тут же при необходимости формируются локальные ответы (local responses);

2.4 Сокет отдает пакет приложению, приложение отвечает и ответ попадает в цепочку OUTPUT - mangle;

2.5 Пакет попадает в цепочку OUTPUT - nat;

2.6 Пакет попадает в цепочку OUTPUT - filter;

3 На этапе 1.3 ядро определило, что пакет транзитный:

3.1 Пакет попадает в цепочку FORWARD - mangle;

3.2 Пакет попадает в цепочку FORWARD  - filter;

4 Для любого исходящего трафика транзитного (п.3.2) и исходящего от локальной системы (п.2.6)

4.1 Пакет попадает в цепочку POSTROUTING - mangle;

4.2 Пакет попадает в цепочку POSTROUTING - nat.

5 Пакет отправляется с интерфейса в сеть (packets outbound to network)

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

п. 1.1 PREROUTING - mangle. На этом этапе мы можем менять байт TOS сетевого пакета, помечать и производить экзотические манипуляции с пакетами; В ручную редко когда что-то тут вносят. 99,9% сетевых устройств это Linux box с интерфейсом вендора. Сетевое железо должно уметь работать с QoS и TOS. Вот через интерфейс производителя обычно и вносятся туда правила, позволяющие приоритезировать трафик и выполнять задачи связанные с трафик инжинирингом;

В этом курсе я не рассматриваю, но в следующих, которые будут посвящены теме маршрутизации в Linux я затрону тему как с помощью mangle маркировать пакеты с целью применения PBR (policy base routing).

Более подробно в теории о том что такое PBR - СДСМ_PBR

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

1.2 PREROUTING - nat. Обычно используется для настройки DNAT. D - destination, меняется адрес назначения. Может и используется в связке с PAT для проброса портов (подробно далее в п.3 Схемы и виды NAT). Практически необходим при публикации ресурсов в Интернет и Интранет.

Пример:

-5

В этом примере любой пакет протокола TCP (prot tcp), приходящий на порт HTTP (tcp dpt:http) и интерфейс enp0s3 подвергается замене адреса назначения на адрес 192.168.0.3.

1.3. На этом этапе ядро Linux box-а принимает решение: “Этот пакет для меня?”. Если ответ “ДА”, то дальше пакет передается этапу, описанному пунктом 2.1, если “НЕТ”, то пункту 3.1.

Ответ “ДА” - пакет для локальной системы:

2.1 INPUT - mangle. Все тоже самое, что и в п.1.1 с одним исключением - для трафика адресованного локальной системе. В п.1.1 - для всего входящего трафика;

2.2 INPUT - filter. Вот эта таблица-цепочка как раз для настройки безопасности локальной системы. Проходя этот этап к пакету может применяться одно из следующих действий: ACCEPT, REJECT, DROP.  По умолчанию ко всем пакетам применяется ACCEPT (мы видим это в выводе команды sudo iptables -L);

2.3 На этом этапе ядро принимает решение в какой сокет отправлять пакет (при условии, что у нас ACCEPT) и в месте с этим формирует ответ (response) в адрес отправителя;

2.4 Для ответов ядра и исходящего ответного трафика приложения применяется OUTPUT - mangle. Тут все аналогично - не буду повторяться;

2.5  OUTPUT - nat. Возможность натировать исходящий трафик до того как пакет пойдет в цепочку POSTROUTING. Используется для повышения безопасности путем скрытия реального адреса;

2.6  OUTPUT - filter. Возможность фильтрации исходящего трафика.

Ответ “НЕТ” - пакет адресован другому узлу:

3.1 FORWARD - mangle.  Пакет считается транзитным и на этом этапе можно с ним что-то сделать;

3.2 FORWARD  - filter. Применение политики безопасности;

Далее исходящий пакет, который может исходить из бокса п.2.6 или быть транзитным 3.2 поступают в:

4.1 POSTROUTING - mangle.

4.2 POSTROUTING - nat. Обычно используется для настройки SNAT. S - source, меняется адрес назначения (подробно далее в п.3 Схемы и виды NAT). Практически необходим для маскарадинга трафика в Интернет, сокрытия адреса

Пример:

-6

Давайте приступим к практике!

Пример №2.1. Ограничиваем адреса с которых можно подключиться по ssh

В данном примере предполагается, что машина Ubuntu20_04_1 это пограничный маршрутизатор с функцией межсетевого экрана. Управление данной машиной должно происходить через внешний интерфейс enp0s3 из подсети администратора по протоколу SSH. В моем случае сеть хоста на котором установлена среда виртуализации VirtualBox имеет такое значение: 192.168.31.0/24.

Внимание! Работая со своим стендом не забывайте учитывать, что ваша домашняя сетка скорее всего будет отличаться.

Доступ по SSH должен быть разрешен только с адресов из вашей домашней сетки. Из внутренних сетей LAN1 и LAN2 доступ по SSH должен быть запрещен. Давайте посмотрим как выглядит исходная ситуация. Для начала проверяем активен ли ssh сервер и на каких интерфейсах он “слушает” входящие подключения:

-7

0.0.0.0:22 указывает на то, что ssh порт прослушивается на любом интерфейсе. Можно было бы однозначно указать интерфейс enp0s3 в настройках ssh сервера, но мы с вами все сделаем с помощью iptables. Ну как минимум для того, чтобы иметь возможность логировать попытки подключения к нашей машине из внутренних сетей. Попробуем подключиться к Ubuntu20_04_1 из внутренних сетей, а именно с машины Centos9:

-8

Удостоверились, что пока из внутренних сетей доступ открыт!

Начинаем выполнение задачи:

В Iptables есть возможность создавать дополнительные цепочки. Давайте в таблице filter создадим для удобства цепочку с именем SSH:

sudo iptables -N SSH

Внимание! Когда работаем с таблицей filter нет необходимости указывать -t filter, так как эта таблица используется по умолчанию.

Чтобы воспользоваться этой цепочкой необходимо указать ее в качестве <TARGET>.

В общем виде синтаксис добавления правила выглядит так:

iptables -A <CHAIN_NAME> …<filtering specifications>... -j <TARGET>

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

iptables -A INPUT -p tcp --dport 22 -j SSH

Таблица filter теперь выглядит так:

-9

Но это не все. Мы создали линковку цепочки INPUT и SSH. Теперь нам необходимо внести правила в саму SSH цепочку:

sudo iptables -A SSH -s 192.168.31.0/24 -j ACCEPT #разрешаем коннекты с адресов админской сети (ваша домашняя сеть)

sudo iptables -A SSH -j DROP #остальной трафик мы должны запретить

-10

Попробуем теперь подключиться по SSH с машины Centos9:

-11

Попытка просто подвисает. И по таймауту ssh-клиент завершает свою работу. В чем особенность данного поведения? Мы указали в качестве действия DROP для источников коннектов не входящих в сеть 192.168.31.0/24 (ваша домашняя сетка). При таком варианте netfilter просто молча дропает пакеты и ничего не сообщает клиенту. Давайте изменим действие DROP на REJECT:

-12

Можно сделать не удалением, а заменой:

-R - заменить правило с указанным номером

Попробуем теперь подключиться по SSH с машины Centos9 и смотрим, что изменилось:

-13

Теперь подключение не подвисает, а клиент получает информацию о том, что подключение отвергнуто политикой безопасности. При этот ответ записывается в сообщение icmp = “icmp-port-unreachable

-14

Внимание!

Утилита iptables, как и маршрутизаторы Cisco, не сохраняет правила, если это явно не указать и после перезагрузки возвращается в предыдущее состояние.

Для того чтобы сохранить правила на постоянной основе необходимо установить пакет iptables-persistent:

sudo apt install iptables-persistent

Примечание: Если apt не находит данный пакет, то сначала следует сделать apt update.

После того как работа с iptables закончена выполняем следующую команду:

service netfilter-persistent save # система при следующей загрузке будет использовать последние сохраненные правила

В процессе работы с iptables часто возникает необходимость вернуться к предыдущей версии правил. Netfilter-persistent сохраняет правила в файле /etc/iptables/rules.v4.

Если не успели сохранить правила, то вернуться к предыдущему состоянию можно так:

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

Пример №2.2 Логируем срабатывание правил в цепочках

Задача логировать попытки подключения по SSH из внутренних сетей. Полезно знать и быть в курсе если вдруг нас атакуют!

Важно! Если мы планируем ставить логирование на постоянную основу, то необходимо защититься от SYN flood атаки на 22-й порт. Если этого не сделать, при условии, что в системе не настроена ротация логов, то мы рискуем получить DoS атаку на переполнение дискового пространства :)

Итак, в качестве <TARGET> нужно указать LOG:

sudo iptables -I SSH 2 -j LOG

-I (input aka вставка в указанное место списка), в отличии от -A (append aka добавить в конец). Т.е. указывая -I SSH 2 мы указываем netfilter разместить правило вторым в таблице. Как вы уже поняли в нашем случае мы вставляем правило логирования перед запрещающим правилом REJECT, чтобы фиксировать попытки подключится по ssh.

-15

По умолчанию будут логироваться syslog сообщения до уровня 4 (Warning) включительно, т.е. с нулевого до 4-го.

Уровни syslog сообщений:

-16

Если необходимо сменить уровень логирования, то для этого у iptables имеются опция --log-level <level>. В качестве <level> можно указывать как цифровое значение, так и использовать имена: debug, info, notice, warning, err, crit, alert и emerg.

Логи будут отображаться как в dmesg, так и в /var/log/syslog:

-17
-18

dmesg (сокр. от diagnostic message) команда, используемая в UNIX‐подобных операционных системах для вывода буфера сообщений ядра в стандартный поток вывода (stdout) (по умолчанию на экран).

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

  1. dmesg -T | tail -n 10 #Вывод на экран 10 последних строк сообщений буфера ядра;
  2. dmesg -w -T # Вывод буфера в режиме реального времени. (наподобие tailf/tail -f)

Чтобы не капаться в кучах логов можно очистить буфер командой: sudo dmesg -c

В начале примера я упоминал про возможность  SYN flood атаки на 22-й порт в результате чего буфер dmesg, ровно как и syslog файл могут переполнится и дисковая подсистема может отказаться обрабатывать запросы операционной системы. Чтобы этого не допустить мы можем установить ограничение на логирование:

sudo iptables -I SSH 2 -m limit --limit 1/s -j LOG

-19

Мы задали среднее количество логирований равное 1, при максимально возможном всплеске не более 5. На видео видно, что за раз мы произвели 6 коннектов, но в лог попало только 5.

Такое ограничение позволит снизить интенсивность логирования и предотвратит скорое переполнение дисковой подсистемы не защищенной ротацией логов. Это даст время на реакцию и принятия решений!

Помните, что буфер dmesg и файл syslog обнуляются после перезагрузки. Поэтому если вы хотите хранить ретроспективу логов, то используйте коллектор логов. К примеру есть популярная связка LogAnalyzer + rsyslog. Это бесплатно и в целом свои задачи решает!

Следующий выпуск будет на темы: Bash скрипт базовой настройки iptables, Схемы и виды NAT, двойной NAT или неприятная ситуация

Пишите комментарии, делитесь с друзьями, ставьте лайки - этим вы помогаете материалу быть виднее!