Skip to main content

Firewall

Исходя из общей теории брандмауэров, можно сделать вывод: для enterprise решений каждый уровень модели TCP/IP должен быть защищен. Однако статичные правила работают неэффективно. Должны быть межуровневые взаимодействия, позволяющие передавать например информацию о подозрительной активности на уровне приложений, на уровень IP фильтрации и блокировать данную активность на уровне IP. Т е enterprise решение должно объединять в себе данные всех уровней в одну картину. Кроме этого, желательно объединение аппаратных и программных решений, т е данные о необходимости блокировки передаются между физическими устройствами.

Политики блокировки

Адреса - источники, которые нужно блокировать на внешнем интерфейсе

  • Ваш IP адрес, lo
  • IP адреса вашей локальной сети 
  • Частные адреса класса A, B и C
  • Мультикастовые класса D и зарезервированные класса E
  • Также можно блокировать Carrier-grade NAT сети (100.64.0.0-100.127.255.255) и TEST-NET (192.0.2.0-192.0.2.255)
  • Есть стратегия блокировки ненадежных пулов (наверное, где-то есть список)
  • Можно добавить блокировку бродкаста, но это редко используется

Возможно ограничение количества пакетов от источника, порты удаленного источника (>1023), блокировка по флагу статуса TCP соединения (флаг должен быть SYN, не ACK).

Нужно контролировать попытки сканирования портов (могут быть разные источники, но скоординированное сканирование).

netfilter - встроенный firewall. Консольные утилиты для управления netfilter:

  • iptables - для v4 и v6 различные
  • ebtables - mac briging правила
  • arptables - правил трансляции arp

ufw - фронтенд для iptables

nftables - иная реализация

firewalld - реализация в RedHat

Какой firewall сейчас активен

Могут быть установлен и iptables, и nftables. Если вывод следующей команды не пустой, значит убедимся, что модуль nft активен: 

sudo nft list ruleset

Проверяем модуль ядра: 

lsmod | grep nf_tables

Если вывод типа 

nf_tables             376832  114 nft_compat,nft_chain_nat

значит nftables загружен.

Модуль iptables еще присутствует в ядре, но как говорят - для вида. 

sudo lsmod | grep ip_tables
ip_tables              32768  0
x_tables               65536  8 xt_conntrack,nft_compat,xt_tcpudp,xt_addrtype,xt_nat,xt_set,ip_tables,xt_MASQUERADE

Есть промежуточный пакет iptables-nft, который транслирует правила из iptables, Но работает именно nft. Однако редактировать nft таблицы с комментариями 

# Warning: table ip filter is managed by iptables-nft, do not touch!

не стоит. Проблема вот в чем: если не удален/отключен iptables-nft, то после каждого использования команды iptables данные таблицы будут перезаписаны. Поэтому либо не использовать эту команду, включить сервис nft и все, либо создать другие таблицы. 

Iptables

Состоит из 4 таблиц:

  • Filter table Базовая защита, обычно используется
  • NAT table 
  • Mangle table Изменение сетевых пакетов при их прохождении через брандмауэр
  • Security table Используется в системах с установленным SELinux

Каждая таблица состоит из цепочек правил. Filter table состоит из цепочек INPUT, FORWARD, OUTPUT

Просмотр существующих таблиц 

sudo iptables -L <имя цепочки или ничего> --line-numbers -v 

Сохранение правил после перезагрузки сервера

sudo apt install iptables-persistant

После этого правила сохраняются в /etc/iptables*

Пример команды 

sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
Аргумент Описание
-A, -I

Добавить в конец или в определенное место цепочки.

-A INPUT

-I INPUT 1

-P

Задает дефолтную политику для цепочки.

iptables -P FORWARD DROP
-D цепочка номер

Удалить запись 

sudo iptables -D DOCKER-USER 1
-m Модуль.
--ctstate  Состояние пакета. Перечисляется через запятую без пробелов.
-j

Действие при соблюдении условия

ACCEPT разрешить пакет

DROP тихо откинуть пакет

REJECT вернуть ответ о блокировании запрашивающей стороне

RETURN вернуть в родительскую цепочку. Используется в случае родительских / дочерних цепочек.

-p Тип соединения, tcp/udp
--dport

порт назначения

--dport ssh

-i 

Интерфейс

-i lo

Разрешение доступа для ssh

sudo iptables -A INPUT -p tcp --dport ssh -j ACCEPT

Здесь для определения порта по названию использовался файл /etc/services То есть возможно прописать свое название службы в данный файл и использовать его в правилах. 

cat /etc/services | grep http
# Updated from https://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xhtml .
http            80/tcp          www             # WorldWideWeb HTTP
https           443/tcp                         # http protocol over TLS/SSL
http-alt        8080/tcp        webcache        # WWW caching service
http-serg       8081/tcp                        # test server

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

sudo iptables -I INPUT 1 -p tcp --dport http-serg -j ACCEPT

Разрешение доступа к lo 

sudo iptables -I INPUT 1 -i lo -j ACCEPT

Пример настройки iptables

Политика: 

  • Разрешить доступ к службам http, https на докере для всех
  • Разрешить все исходящие соединения
  • Разрешить доступ для ip1
  • Docker должен функционировать корректно
  • Все остальное запретить
sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
sudo iptables -A INPUT -i lo -j ACCEPT
sudo iptables -A INPUT -s 1.1.1.1 -j ACCEPT
sudo iptables -I INPUT 1 -p icmp --icmp-type echo-request -j ACCEPT

sudo iptables -A INPUT -i docker0 -j ACCEPT
sudo iptables -P INPUT DROP

sudo iptables -I DOCKER-USER 1 -s 1.1.1.1 -p tcp --dport 5432 -j ACCEPT
sudo iptables -I DOCKER-USER 2 -p tcp --dport 5432 -j DROP