LINUX.ORG.RU
ФорумAdmin

Тестирую SYNPROXY, куки не отправляются

 , , ,


0

1

Хочу сделать SYNPROXY, для смягчения syn флуда. Вроде все понятно, делаю как тут https://www.opennet.ru/tips/info/2928.shtml или тут https://habr.com/ru/company/infobox/blog/232227/

Общий смысл ясен, исключить из conntrack syn, метить INVALID ложные ACK, отправлять куку, потом все это дело отправлять в SYNPROXY, там проверяется ACK от клиента и если он правильный, то создавать соединение, если нет, то следующее правило дропает пакеты.

Не пойму почему не отправляются куки, смотрю изменения через

netstat -s | grep -Ei "cook"
10 SYN cookies sent
2 SYN cookies received


Видно, что куки не отсылаются, хотя пакеты SYN идут с бешеной скоростью ~50 000PPS

Переполнения очереди SYN тоже нет
netstat -s | grep -Ei "listen"
0 SYNs to LISTEN sockets dropped



Однако, tcpdump показывает, что SYN+ACK пакеты отсылаются

tcpdump -i any -n port 80 and src 10.0.0.2
23:22:03.259081 IP 10.0.0.2.80 > 46.39.196.229.5827: Flags [S.], seq 515620665, ack 1531057089, win 0, length 0
23:22:03.259094 IP 10.0.0.2.80 > 191.24.222.41.5829: Flags [S.], seq 2946937250, ack 1684158566, win 0, length 0
23:22:03.259305 IP 10.0.0.2.80 > 73.95.252.199.5830: Flags [S.], seq 4071935182, ack 825496706, win 0, length 0
23:22:03.259382 IP 10.0.0.2.80 > 68.156.77.164.5831: Flags [S.], seq 3453282316, ack 1806698451, win 0, length 0
23:22:03.259417 IP 10.0.0.2.80 > 136.74.64.98.5832: Flags [S.], seq 966049922, ack 1438489520, win 0, length 0
23:22:03.259443 IP 10.0.0.2.80 > 5.39.64.98.5833: Flags [S.], seq 3456217848, ack 1877534406, win 0, length 0
23:22:03.259567 IP 10.0.0.2.80 > 75.2.162.73.5834: Flags [S.], seq 2934636789, ack 2019708598, win 0, length 0
23:22:03.259658 IP 10.0.0.2.80 > 151.8.33.142.5835: Flags [S.], seq 923844625, ack 176880257, win 0, length 0
23:22:03.259849 IP 10.0.0.2.80 > 141.122.230.196.5836: Flags [S.], seq 2816293618, ack 666495559, win 0, length 0
23:22:03.259892 IP 10.0.0.2.80 > 247.21.5.9.5837: Flags [S.], seq 2611127790, ack 1590842067, win 0, length 0
23:22:03.260048 IP 10.0.0.2.80 > 24.170.93.203.5841: Flags [S.], seq 2875532378, ack 1007533654, win 0, length 0
23:22:03.260099 IP 10.0.0.2.80 > 243.236.162.73.5839: Flags [S.], seq 4142336230, ack 855143884, win 0, length 0
23:22:03.260100 IP 10.0.0.2.80 > 106.106.151.181.5840: Flags [S.], seq 3272823395, ack 1830105953, win 0, length 0
23:22:03.260186 IP 10.0.0.2.80 > 46.79.157.229.5842: Flags [S.], seq 464842204, ack 958111797, win 0, length 0
23:22:03.260215 IP 10.0.0.2.80 > 95.152.222.141.5843: Flags [S.], seq 69167228, ack 1910363156, win 0, length 0
23:22:03.262073 IP 10.0.0.2.80 > 73.88.143.121.5844: Flags [S.], seq 404959580, ack 21012037, win 0, length 0
23:22:03.262219 IP 10.0.0.2.80 > 208.27.201.254.5847: Flags [S.], seq 2806492340, ack 715377600, win 0, length 0
23:22:03.262246 IP 10.0.0.2.80 > 154.236.128.246.5846: Flags [S.], seq 3797225913, ack 1438349079, win 0, length 0
23:22:03.262309 IP 10.0.0.2.80 > 157.45.122.93.5848: Flags [S.], seq 2918462004, ack 2056743493, win 0, length 0^C


Если очистить iptables -F то куки начинают отсылаться (смотрю через netstat -s SYN cookies sent)

В принципе, можно вообще отказаться от conntrack и все будет хорошо, но тогда не будут работать правила, которые используют состояния --state

Счечтик SYNPROXY растет, и попутно 1 ядро проца используется на 100%, растут пинги и потери пакетов.

Почему 1 ядро загружено на 100% ksoftirq (думаю отправка SYN+ACK?), хотя прерывания все распределил через rss-ladder и autorps и при входящем все ядра используются пропорционально

Тестирую так(2 виртуалки debian, 10.0.0.2(жертва) и 10.0.0.3(флудер))
hping3  --syn 10.0.0.2  -p 80  --rand-source -i u100
hping3  --syn 10.0.0.2  -p 80  --rand-source --flod


cat /etc/sysctl.conf

fs.file-max = 999999
net.core.netdev_max_backlog=10000
net.core.somaxconn=512 //больше нет смысла ставить, у nginx по умолчанию backlog=512
net.ipv4.tcp_syncookies=2 //отправлять куки всегда
net.ipv4.tcp_max_syn_backlog = 4096
net.ipv4.tcp_max_tw_buckets = 65536
net.ipv4.tcp_tw_recycle = 0
net.ipv4.tcp_timestamps = 1
net.ipv4.tcp_tw_reuse = 0
net.ipv4.tcp_fin_timeout = 5
net.ipv4.tcp_keepalive_time = 1800
net.ipv4.tcp_keepalive_probes = 7
net.ipv4.tcp_keepalive_intvl = 75
net.core.wmem_max = 33554432
net.core.rmem_max = 33554432
net.core.rmem_default = 8388608
net.core.wmem_default = 4194394
net.ipv4.tcp_rmem = 4096 8388608 16777216
net.ipv4.tcp_wmem = 4096 4194394 16777216

net.netfilter.nf_conntrack_max=3000000
net.netfilter.nf_conntrack_tcp_loose = 0
net.netfilter.nf_conntrack_tcp_timeout_syn_recv = 1
net.netfilter.nf_conntrack_tcp_timeout_syn_sent = 1
net.ipv4.ip_forward = 0
net.ipv4.tcp_synack_retries = 1



iptables -t raw -nvL
Chain PREROUTING (policy ACCEPT 2871K packets, 115M bytes)
 pkts bytes target     prot opt in     out     source               destination
2851K  114M CT         tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp flags:0x17/0x02 CT notrack

Chain INPUT (policy ACCEPT 21481 packets, 1127K bytes)
 pkts bytes target     prot opt in     out     source               destination
2602K  104M SYNPROXY   tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp ctstate INVALID,UNTRACKED SYNPROXY sack-perm timestamp wscale 7 mss 1460
    6   240 DROP       all  --  *      *       0.0.0.0/0            0.0.0.0/0            ctstate INVALID

★★★★

SYNPROXY само генерит SYN+ACK пакет, это не тот syn-cookie, который генерит ядро. Заверните в SYNPROXY часть трафика, для остального будет расти счётчки в netstat.

mky ★★★★★
()
Ответ на: комментарий от mky

SYNPROXY само генерит SYN+ACK

То есть есть реализация в ядре и своя в netfilter? Я как понимаю единственный плюс от SYNPROXY в netfilter это предотвращение переполнения conntrack? Тогда наверное проще на время атаки вообще этот conntrack отключать или совсем отказаться от него?

Кстати как отключить conntrack на время?
Пробовал

rmmod nf_conntrack
rmmod: ERROR: Module nf_conntrack is in use by: ipt_SYNPROXY nf_conntrack_ipv4 xt_connlimit nf_conntrack_netlink xt_CT xt_conntrack nf_synproxy_core


Или так пойдет?
-A PREROUTING -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -j CT --notrack

gobot ★★★★
() автор топика
Последнее исправление: gobot (всего исправлений: 2)
Ответ на: комментарий от gobot

-A PREROUTING -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -j CT --notrack

В таблице RAW и на нужном порте, а не все подряд:

iptables -t raw -A PREROUTING -i $INET_IFACE -d $INET_IP -p tcp --dport 80 -j CT --notrack
iptables -t raw -A OUTPUT -o $INET_IFACE -s $INET_IP -p tcp --sport 80 -j CT --notrack
Тогда -m state --state RELATED,ESTABLISHED будет работать для всех остальных портов.

funky
()
Ответ на: комментарий от gobot

В принципе, можно вообще отказаться от conntrack и все будет хорошо, но тогда не будут работать правила, которые используют состояния --state

funky
()
Ответ на: комментарий от gobot

Я как понимаю единственный плюс от SYNPROXY в netfilter это предотвращение переполнения conntrack?

Если считать, что сервер ничем не прикрыт, то да. А так, он поэтому и proxy, что на маршрутизаторе работает (может работать).

На ходу (при работающих iptables) модуль conntrack точно не выгрузить, отключать весь файервол при DoS тоже не вариант. Так что только notrack, но мне это кажется как-то неправильно. Уж проще тогда совсем отказаться от conntrack, а то потом ещё появятся у вас какие-нибудь правила в iptables, завязанные на conntrack и внезапное ″-j CT --notrack″ даст неожиданный результат.

mky ★★★★★
()
Последнее исправление: mky (всего исправлений: 1)
Ответ на: комментарий от mky

Ну да, если отказаться от conntrack, то не будет работать

--state INVALID -j DROP

а это от ack флуда спасает (при net.netfilter.nf_conntrack_tcp_loose = 0).

Пока помогло уменьшение таймаутов
net.netfilter.nf_conntrack_tcp_timeout_syn_recv = 10
net.netfilter.nf_conntrack_tcp_timeout_syn_sent = 10
net.netfilter.nf_conntrack_tcp_timeout_time_wait = 10
net.ipv4.tcp_synack_retries = 1

записей в conntrack стало в 5-7 раз меньше при флуде

Кстати почему по умолчанию такой огромный таймаут у nf_conntrack_tcp_timeout_syn_recv = 120? Какой смысл ждать 2 минуты ответа syn+ack? Обычно ответ приходит на доли секунд. Где это может пригодится, при каких условиях?

gobot ★★★★
() автор топика
Ответ на: комментарий от gobot

Таймаут, действительно, большой. ИМХО, при его выборе думали не про SYN-flood, а про потери пакетов. ЕМНИП, повторная передача пакета SYN-ACK идёт через 5 секунд. Если большие потери пакетов, то лучше подольше подержать соединение в SYN-RECEIVED, чтобы у клиента был шанс установить соединение (это я не про ваш случай, а общие мысли по поводу выбора таймаута).

mky ★★★★★
()
3 июля 2020 г.

доброе утро, могу поинтересоваться, чем закончилась история с SYNPOXY? помог ли этот способ в борьбе с syn flood?

lokha
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.