Linux: фильтрация, connection trackering и packet flow, statistics: iptables, ipset, ipfw, nftables, bpfilter, firewalld, conntrack, BPF, packetfilter, netstat, iptraf, jool

Фильтрация на базе DPDK
packet flow (pipeline)

Тут только packet flow, подробнее в отдельном разделе.

Netfilter-packet-flow.svg

         еще одна вариация

iface input -> xdp -> qdisc (ingress) -> brouting -> prerouting -> conntrack -> prerouting -> forward -> postrouting -> qdisc (egress) -> iface output

  • CloudFlare:
XDP -> qdisc -> IPTABLES -> SOCKET -> APPLICATION

XDP

Самый быстрый фильтр, быстрее может быть потенциально только на базе самой NIC и DPDK. XDP используют cloudflare для защиты от DoS/DDoS и это о многом говорит.

numbers-xdp-1

XDP причем более гибкий в сравнении с iptables – там ты можешь написать свою app.

performance
They wrote a filter that filters all UDP traffic (or some UDP traffic? unclear). They tried implementing the rule in iptables and compared it to their custom XDP approach.

iptables: 4.5 million packets/second (у cloudflare хуже результат выше)
XDP: 9.7 million packets/second

performance definitely isn’t the only benefit over iptables though – it’s definitely really important that with XDP you can write arbitrary code.

 

firewalld (firewall-cmd)

Является надстройкой над Iptables. Примеры применения firewall-cmd описаны в статьях по деплою ftp/tftp на базе CentOS7.

 

nftables

Разработчики Netfilter официально объявили инструментарий iptables устаревшим.

nftables является проектом по замене фреймворков iptables, ip6tables, arptables[en], ebtables в межсетевом экране Netfilter.

И nftables и bpfilter  умеют транслировать команды (часть nftables и как понимаю все bpfiler) традиционного синтаксиса iptables в “свои”.

Как я понял nftables в сравнении с iptables:
1) + быстрее за счет уменьшения строк кода + сам код меньше памяти занимает. Это достигается за счет использования ассоциированных масивов (хешей/картежей) в nftables можно создавать правила (например SNAT, DNAT с разных IP на разные IP), аналогичные Iptables, только имеющие значительно меньше строк.

2) + может обновляться без пересборки ядра

3) + использование netlink вместо системных вызовов (огромный ряд плюсов напр. netlink позволяет поддерживать синхронность, ядро может отдавать данные в приложение без опроса)

4) – ipt_netflow нет

 

EBTABLES

В них можно использовать bridge правила – broute/brouting. Схемы выше.

(e)BPF

BPF filters are widely used by the Linux kernel, TCP dump and others. Basically any tcpdump filtering tutorial can be used to define a filter for TRex.

Some simple examples using BPF:
All ARP or ICMP packets:
'arp or icmp'
All UDP packets with destination port 53:
'udp and dst 53'
All packets VLAN tagged 200 and TCP SYN:
'vlan 200 and tcp[tcpflags] == tcp-syn'
Hardware BPF

BPF в целом очень перспективное направление – оно позволяет сделать фильтрацию по байт коду еще до Kernel без всяких kernel bypass (как в случае DPDK) еще на уровне NIC. Но пока не полноценное – сложные фильтры пока не реализуемы, для загрузки BPF кода на NIC нужна поддержка NIC такого действия.

 

bpfilter

Является проектом, который должен заменить всех тех же что и nftables, только и сам nftables))))))))

И nftables и bpfilter  умеют транслировать команды (часть nftables и как понимаю все bpfiler) традиционного синтаксиса iptables в “свои”.

 

EBPF

eBPF (Extended Berkeley Packet Filter)

eBPF очень активно используют CloudFlare для работы с трафиком.

The talk ended up being mostly about BPF. It seems, no matter the question - BPF is the answer.

 

Сессии

Сессии на порту

netstat -na | grep ":33231"
ss | grep ":33231"

Количество сессий

netstat -pant | wc -l

NAT статистика

netstat-nat -n -N # показываем, во что резолвим (напр. src - changed src - dst)
iptraf

Утилита старая (судя по about разработка закончиалсь в далеком 2004), но рабочая. Установка ее простейшая.

apt install iptraf
iptraf

Утилита собирает сетевую статистику с интерфейсов. Неплохо кастомизируется и легко управляется (pseudo-gui): можно выбрать интерфейс, тип статистики.

 

 

Conntrack

Conntrack netfilter — модуль для отслеживания/управления соединениями. Используется при NAT и “улучшенной” пакетной фильтрации.

Conntrackd — демон инструментов netfilter, отслеживающий user-space соединения. Может быть использован в паре с keepalived для создания отказоусточивого кластера шлюзов. Является инструментом из пакета cronntrack-tools.

conntrackd -s # просмотр синхронизации сессий в кластере

Пример настроек conntrack для высокопроизводительных серверов с NAT и для минимизации влияния DOS в статье DOS.

Connection tracking keeps a record of what packets have passed through your machine, in order to figure out how they are related into connections. This is required to do Masquerading or other kinds of Network Address Translation. It can also be used to enhance packet filtering (see `Connection state match support' below).

Usage

# conntrack –E # смотрим онлайн

# conntrack -L # аналог cat /proc/net/ip_conntrack
conntrack v1.2.1 (conntrack-tools): 999889 flow entries have been shown.
 999889 14998333 158996207

# conntrack -F
conntrack v1.2.1 (conntrack-tools): connection tracking table has been emptied.

# /proc/sys/net/ipv4/netfilter/ip_conntrack_max # макс. количество соединений
Про тюнинг размера таблицы iptables conntrack – memory dependent. В целом по опыту одного из подписчиков IETF BMWG (G?bor LENCSE): hashsize лучше настраивать аналогичным значению количества соединений nf_conntrack_max.
As for iptables, I can tune the size of the connection tracking table nearly arbitrarily, it seems that the memory capacity is the only limit.

I can tune two values:
- nf_conntrack_max-- It specifies the maximum of the number of entries in the state table
- hashsize-- It specifies the number of entries of the hash table. (I far as I remember, all of them are linked list heads. The elements of the lists store the parameters of the connections.)

This source https://ixnfo.com/en/tuning-nf_conntrack.html recommends
hashsize=nf_conntrack_max/8, (what would result in linked lists of 8
elements on average) and my experience shows that larger hashsize
ensures higher performance. (When I could, I used
hashsize=nf_conntrack_max.) The value of hashsize is limited by the size
of the memory. E.g. having 384GB of RAM, I could set it to 2^28, but I
could not set it to 2^29. (I got an error message.) With hashsize=2^28,
I used nf_conntrack_max=2^30, and the memory usage was somewhat below
300GB. (Using another computer, I once accidentally exhausted its 256GB
of RAM.)

Нагрузку по CPS на conntrack можно (по идее) извлечь из самого conntrack или с использованием systat.

-bash-4.4# cat /proc/net/stat/ip_conntrack
entries searched found new invalid ignore delete delete_list insert insert_failed drop early_drop icmp_error expect_new expect_create expect_delete search_restart
00000027 00082000 0a4c957c 00156632 000018c4 0a56dc4f 0015660b 00155d1f 00155d46 00000007 00000000 00000000 00000001 00000000 00000000 00000000 00000000
IPSET
 

IP sets are a framework inside the Linux kernel, which can be administered by the ipset utility. Depending on the type, an IP set may store IP addresses, networks, (TCP/UDP) port numbers, MAC addresses, interface names or combinations of them in a way, which ensures lightning speed when matching an entry against a set.

If you want to

  • store multiple IP addresses or port numbers and match against the collection by iptables at one swoop;
  • dynamically update iptables rules against IP addresses or ports without performance penalty;
  • express complex IP address and ports based rulesets with one single iptables rule and benefit from the speed of IP sets
then ipset may be the proper tool for you.
 

IP blacklist

Используется для блокировки спама/DoS/DDoS в связке с iptables. Еще примеры. Пример блокировки пула (китайские IP). Пулы можно взять с сайта https://www.countryipblocks.net/ или сайта2 https://www.ipdeny.com/  (могут быть недоступны из России).

# apt install ipset

# ipset create countryblock nethash
# ipset add countryblock 1.0.1.0/24
# ipset add countryblock 1.0.2.0/23
# ipset add countryblock 1.0.8.0/21
# ipset add countryblock 1.1.0.0/24
# ipset add countryblock 1.1.2.0/23
# ipset -L blacklist

# iptables -A INPUT -m set --match-set countryblock src -j DROP

IP whitelist

Кроме blacklist можно создавать и whitelist, особенно это полезно, когда сервис локализован какой-то страной. Там так же есть скрипт выгрузки с сайта https://www.ipdeny.com/ и формирования списков стран СНГ как whitelist для ipset.

Список подходящих мне стран гораздо меньше, чем список нежелательных. Так что я пошел по другому пути и запретил доступ всем, кроме некоторых стран.
Не забывайте важный момент - чтобы у вас белый список работал, у вас должен весь трафик, который не разрешен явно, блокироваться. 
# ipset -N whitelist nethash  # альтернативное создание/добавление флагами
# ipset -A whitelist 6.43.240.0/21 # ipset -A whitelist 7.100.64.0/18 # ipset -A whitelist 8.159.112.0/21

# iptables -A INPUT -i $WAN -m set --match-set whitenet src -p tcp --dport 80 -j ACCEPT # iptables -A INPUT -i $WAN -m set --match-set whitenet src -p tcp --dport 443 -j ACCEPT

Максимумы можно тюнить тут.

ipset create blacklist nethash hashsize 16348 maxelem 131072

NOT IP OBJECTS

Кроме IP утилита может работать (создавать списки) так же с портами, MAC адресами и номерами интерфейсов. Real example.

ipset -N BAD-PORTS bitmap:port range 135-1512
ipset -A BAD-PORTS 135
ipset -A BAD-PORTS 137-139
ipset -A BAD-PORTS 144
ipset -A BAD-PORTS 445
ipset -A BAD-PORTS 1512
IPtables
    • Разработчики Netfilter официально объявили инструментарий iptables устаревшим. См. Nftables/bpfilter. Схемы обработки выше.
    • Iptables не проверяет существование добавляемого правила

IPtables часто работает в связке с fail2ban. Fail2ban автоматически добавляет правила в iptables: после нескольких некорректных авторизаций (bruteforce), после обнаруженной атаки по порогу (syn flood) или других атак (можно самому паттерны создавать). Причем при массовой атаке в iptables может оказаться до нескольких тысяч-десятков тысяч адресов одновременно. На событие добавления блокировки может служить триггером – отправить email/sms/etc. 

 

Команды

Простейшая установка и настройка.

iptables –list или –L – смотрим правила iptables. Для просмотра нужны права админа.

~$ sudo iptables --list
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination 

$ iptables --list
iptables v1.4.20: can't initialize iptables table `filter': Permission denied (you must be root)

iptables -nvL – смотрим правила по категориям, используя -nat так же смотрим правила prerouting/postrouting. Тут же отображается статистика по пакетам для каждого правила, что очень удобно.

# 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

# iptables -t nat -nvL
Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain POSTROUTING (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

iptables … –line-numbers – нумеруем правила

iptables -L -vn --line-numbers | grep <ip or comment>

iptables … -tee – c помощью IPTABLES можно зеркалировать трафик который идет к хосту, перенаправляя копию пакета к другому хосту используя опцию tee.

There is an experimental target (ROUTE) which offers an option (--tee) that behaves like the good old linux “tee” command.  It copies a packet to a target ip address and then goes on with the normal behaviour (routing it to it’s normal target.)
This will send a copy of all packets to the monitor pc with the ip 192.168.1.254.
iptables -A PREROUTING -t mangle -j ROUTE --gw 192.168.1.254 --tee
iptables -A POSTROUTING -t mangle -j ROUTE --gw 192.168.1.254 --tee

 

nat в IPTABLES

PORT FORWARDING (проброс портов)

Доступ к IP 172.20.1.51 по SSH через подключение к 172.20.1.50:10051: Пробрасываем трафик пришедший на 10051 порт IP 172.20.1.50 на IP 172.20.1.51:22 (SSH default). Для обратного трафика от 172.20.1.51:22 подменяем IP на 172.20.1.50.

sudo iptables -t nat -A PREROUTING -i enp7s0 -p tcp --dport 10051 -j DNAT --to-destination 172.20.1.51:22
sudo iptables -t nat -A POSTROUTING -o enp7s0 -p tcp --dport 22 -d 172.20.1.51 -j SNAT --to-source 172.20.1.50

Доступ к IP 172.20.1.51 по WEB через подключение к 172.20.1.50:18051: Пробрасываем трафик пришедший на 18051 порт IP 172.20.1.50 на IP 172.20.1.518080 (WEB). Для обратного трафика от 172.20.1.51:8080 подменяем IP на 172.20.1.50.

sudo iptables -t nat -A PREROUTING -i enp7s0 -p tcp --dport 18051 -j DNAT --to-destination 172.20.1.51:8080
sudo iptables -t nat -A POSTROUTING -o enp7s0 -p tcp --dport 8080 -d 172.20.1.51 -j SNAT --to-source 172.20.1.50

 

MASQUERADE

Настройка NAT в iptables простейшая – нужно указать вместо enp0s17 название вашего интерфейса через который выходите в интернет.
Работает и для router on a stick в топологии, когда на NAT роутере всего один интерфейс (и внешний и внутренний).

iptables -t nat -A POSTROUTING -o enp0s17 -j MASQUERADE

Смотрим настройки NAT.

iptables --list -t nat

Чистим настройки NAT.

iptables -F -t nat

Удаляем правило №3 nat postrouting/prerouting.

iptables -t nat -D POSTROUTING 3
iptables -t nat -D PREROUTING 3

Смотрим сессии NAT.

netstat-nat -n -N # показываем, во что резолвим (напр. src - changed src - dst)
MISC USAGE

Удалить все правила.

iptables -F

Разрешить весь входящий трафик

sudo iptables -I INPUT -j ACCEPT
sudo iptables -D INPUT 1

Разрешить весь исходящий трафик

sudo iptables -I OUTPUT -j ACCEPT
sudo iptables -D OUTPUT 1

Добавляем входящие правило N 93 c разрешением для определенного TCP порта, определенного хоста.

sudo iptables -I INPUT 93 -s 66.133.109.36 -p tcp -m tcp --dport 80 -m comment --comment "HTTP for let's encrypt certbot" -j ACCEPT

Запретить трафик еще на раннем в цепочке уровне prerouting (смотри выше в схемах).

iptables -t raw -I PREROUTING -m iprange --src-range 1.2.3.0-1.2.3.250 -j DROP
Ограничить rate UDP трафика в 1000 packet/sec на уровне prerouting. По первому правилу происходит пропуск трафика до тех пор, пока очередь (емкость) не заполнится пакетами.
iptables -t raw -A PREROUTING -p udp -m limit --limit 1/sec --limit-burst 1000 -j ACCEPT
iptables -t raw -A PREROUTING -p udp -j DROP

Запретить трафик на порт 80.

iptables -A INPUT -p tcp --dport 80 -j DROP

Запретить трафик на порт 80 с reject и tcp reset или icmp host uncreachable.

iptables -A INPUT -p tcp --dport 80 -j REJECT
iptables -A INPUT -p tcp --dport 80 -j REJECT --reject-with tcp-reset
iptables -A INPUT -p tcp --dport 80 -j REJECT --reject-with icmp-host-unreachable

Удаляем входящие правило N 93

sudo iptables -D INPUT 93

Смотрим трафик (gentoo)

sudo tail -f /var/log/kern.log | grep TCP

Сохранение в постоянные настройки правил iptables.

sudo apt install iptables-persistent
sudo service netfilter-persistent save # deprecated sudo service iptables-persistent save

 

IPTABLES + SSHD

На примере CentOS 7 ограничиваем доступ к SSH серверу. Не забываем на всякий случай сделать аналогичные настройки в самом демоне ssh – реализуем концепцию defense in depth (даже если по какой-то причине “рухнет” iptables, будет продолжать работать защита на базе application).

/etc/ssh/sshd_config
AllowUsers <username>@<ip>

Прописываем конкретный хост для доступа по SSH порту

sudo iptables -I IN_public_allow 5 -s <IP> -p tcp -m tcp --dport <ssh port> -m comment --comment "SSH from <LOCATION>" -j ACCEPT

Удаляем стандартный доступ со всех хостов

sudo iptables -D IN_public_allow 1

 

pfctl

pfctl используется для управления BSD (FreeBSD, OpenBSD) packet filter.

 

IPFW

IPFW – считается очень хорошим файрволом на FreeBSD – быстрым, удобным, с большим количеством функционала. У мелких провайдеров зачастую используются FreeBSD тачки с BRAS-функционалом (политика разрешения + шейпер) на базе IPFW – например, по IP пользователя узнаем его тариф из базы, на его основе назначаем bandwidth в ACL для трафика с этого IP.

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

Один пример (разрешаем конкретные типы ICMP):

${FwCMD} add allow icmp from any to any icmptypes 0,8,11

Еще пример с bash-логикой (режем bandiwdth по ночам чтобы не качали непонятно кто, непонятно что):

Также, необходимо заметить, что сам файл файрволла, по сути является shell-скриптом,  - со всеми вытекающими плюсами - типа регулировка траффика день/ночь, в последнем примере..chour=`date '+%H'`
if [ ${chour} -lt 8 ]; then
    ${FwCMD} add pipe 1 ip from not ${NetIn} to ${NetIn}
    ${FwCMD} pipe 1 config bw 33600 bit/s
fi
if [ ${chour} -ge 22 ]; then
    ${FwCMD} add pipe 1 ip from not ${NetIn} to ${NetIn}
    ${FwCMD} pipe 1 config bw 33600 bit/s
fi

 

Jool (NAT64)
IETF BMWG:
 
I had experience only with iptables (stateful NAT44). Since then, I have some experience with Jool (stateful NAT64).

Leave a Reply