Категорії
Linux Security

Защита от флуда, DDoS’a, повышение производительности

В статье будет рассмотрен тюнинг системы при помощи sysctl. Так же защита от разного рода сканнирования, DDoS’a.

Все значения используйте на свой страх и риск.

1) Установим такие переменные sysctl:

fs.file-max = 6576702
net.core.rmem_default=201250
net.core.wmem_default=201250
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.core.netdev_max_backlog = 10000
net.core.somaxconn=32768
net.ipv4.tcp_mem= 786432 1048576 996777216
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
net.ipv4.tcp_fin_timeout=15
net.ipv4.tcp_keepalive_time=1800
net.ipv4.tcp_keepalive_intvl=5
net.ipv4.tcp_keepalive_probes=3
net.ipv4.tcp_synack_retries=3
net.ipv4.tcp_syncookies=1
net.ipv4.tcp_mtu_probing=1
net.ipv4.tcp_window_scaling = 1
net.ipv4.tcp_sack=0
net.ipv4.tcp_max_syn_backlog=4096
net.ipv4.tcp_max_tw_buckets = 720000
net.ipv4.tcp_max_orphans = 65536
net.ipv4.tcp_challenge_ack_limit = 999999999 (защита от CVE-2016-5696)

Включаем механизм разрешающий использовать уже существующие сокеты, которые находятся в состоянии TIME_WAIT, если это не повредит безопасности. Внимание: может навредить, обязательно простестировать! Могут наблюдаться проблемы для юзеров из-за NAT’a

net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1

Примечание: я версии ядра 4.12 параметр tcp_tw_reuse удалили.

!!!

net.ipv4.conf.all.send_redirects=0
net.ipv4.conf.all.accept_redirects=0
net.ipv4.conf.default.accept_redirects=0
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0
net.ipv4.conf.all.secure_redirects=0
net.ipv4.conf.all.accept_source_route = 0
net.ipv4.conf.default.accept_source_route = 0
net.ipv4.conf.all.rp_filter=1
net.ipv4.conf.default.rp_filter=1
net.ipv4.ip_local_port_range=1024 65000
net.ipv4.icmp_echo_ignore_broadcasts = 1
net.ipv4.icmp_ignore_bogus_error_responses = 1
net.ipv4.netfilter.ip_conntrack_max = 16777216
net.netfilter.nf_conntrack_max = 16777216
kernel.msgmnb = 65536
kernel.msgmax = 65536
kernel.shmmax = 68719476736
kernel.shmall = 4294967296

При увеличении conntrack нужно и увечичить количество buckets для хэш-таблицы, хранящей все трансляции (это опция модуля nf_conntrack):

создать файл /etc/modprobe.d/nf_conntrack такого содержания (значение должно быть хотя бы половина от nf_conntrack_max)

options nf_conntrack hashsize=8388608

Или изменить налету так:

echo "8388608" > /sys/module/nf_conntrack/parameters/hashsize

Но важно помнить и про выделение памяти при слишком больших значениях

The size of kernel memory used by netfilter connection tracking is:

size_of_mem_used_by_conntrack (in bytes) = CONNTRACK_MAX * sizeof(struct ip_conntrack) + HASHSIZE * sizeof(struct list_head)

where:

sizeof(struct ip_conntrack) can vary quite much, depending on architecture, kernel version and compile-time configuration. To know its size, see the kernel log message at ip_conntrack initialization time.

sizeof(struct ip_conntrack) is around 300 bytes on i386 for 2.6.5, but heavy development around 2.6.10 make it vary between 352 and 192 bytes!

sizeof(struct list_head) = 2 * size_of_a_pointer On i386, size_of_a_pointer is 4 bytes.

Подробнее о них можно прочесть здесь

На сильно загруженных серверах имеет смысл уменьшить число неудачных попыток, после которого уничтожается соединение TCP, закрытое на стороне клиента. Это значение можно указать с помощью параметра net.ipv4.tcp_orphan_retries. По умолчанию обычно указывают 7, но если система сильно загружена, имеет смысл уменьшить это значение так как закрытые соединения могут поглощать достаточно много ресурсов.

net.ipv4.tcp_orphan_retries=2

Рекомендую выставить побольше значение initrwnd/initrwnd (влияют на размер CWND окна):

# ip route change default via DEFAULT_GW dev OUT_INTERFACE initrwnd 20 initcwnd 20

2) ipset

IP Sets – расширение пакетного фильтра ядра iptables, которое позволяет комфортно работать с большими наборами адресов/сетей. При написании правил iptables при этом мы оперируем именованными списками.

Дело в том, что при использовании хостов больше 1000 через iptablesload avarage будет большим, так как сам iptables плохо работает с большим количеством хостов. Намного лучше с ним работает сам ipset. Поэтому используйте именно его.

3) Защита от аттак.

– SYN

iptables -A INPUT -p tcp ! –syn -m state --state NEW -j DROP
iptables -A OUTPUT -p tcp ! –syn -m state --state NEW -j DROP

– SYN Flood

Ставим ограничение в 24 подключения за секунду (максимально разрешено 48 подключений)

iptables -t mangle -N syn-flood
iptables -t mangle -A syn-flood -m limit --limit 24/s --limit-burst 48 -j RETURN
iptables -t mangle -A syn-flood -m limit --limit 10/s --limit-burst 10 -j LOG --log-prefix "IPT: DOS (dropped): "
iptables -t mangle -A syn-flood -j DROP
iptables -t mangle -A PREROUTING -p tcp --syn -j syn-flood

Либо так:

Ставим ограничение в 100 подключения за секунду (максимально разрешено 150 подключений)

iptables -N syn-flood
iptables -A syn-flood -m limit --limit 100/second --limit-burst 150 -j RETURN
iptables -A syn-flood -j LOG --log-prefix "SYN flood: "
iptables -A syn-flood -j DROP

– FIN/X/N

iptables -A INPUT –p tcp –m tcp –-tcp-flags FIN,ACK FIN -j DROP
iptables -A INPUT –p tcp –m tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG FIN,SYN,RST,PSH,ACK,URG –j DROP
iptables -A INPUT –p tcp –m tcp –-tcp-flags FIN,SYN,RST,PSH,ACK,URG NONE –j DROP
iptables -A FORWARD -p tcp -m tcp --tcp-flags FIN,SYN FIN,SYN -j DROP
iptables -A FORWARD -p tcp -m tcp --tcp-flags SYN,RST SYN,RST -j DROP
iptables -A FORWARD -p tcp -m tcp --tcp-flags FIN,RST FIN,RST -j DROP
iptables -A FORWARD -p tcp -m tcp --tcp-flags FIN,ACK FIN -j DROP
iptables -A FORWARD -p tcp -m tcp --tcp-flags ACK,URG URG -j DROP
iptables -A FORWARD -p tcp -m tcp ! --tcp-flags FIN,SYN,RST,ACK SYN -m state --state NEW -j DROP

– NMAP сканирование

## nmap -sS (Scan: SYN+ACK = no defense... )
## nmap -sX (Scan: SYN+ACK+FIN+RST [+PSH+URG] = not implemented in TCP)
iptables -A INPUT -p tcp -m state --state ! ESTABLISHED --tcp-flags SYN,ACK,FIN,RST ALL -j LOG --log-prefix "IPT: Scan: XMAS0: "
iptables -A INPUT -p tcp -m state --state ! ESTABLISHED --tcp-flags SYN,ACK,FIN,RST ALL -j REJECT --reject-with tcp-reset
iptables -A INPUT -p tcp -m state --state ! ESTABLISHED --tcp-flags ALL FIN,URG,PSH -j LOG --log-prefix "IPT: Scan: XMAS1: "
iptables -A INPUT -p tcp -m state --state ! ESTABLISHED --tcp-flags ALL FIN,URG,PSH -j REJECT --reject-with tcp-reset
iptables -A INPUT -p tcp -m state --state ! ESTABLISHED --tcp-flags ALL SYN,RST,ACK,FIN,URG -j LOG --log-prefix "IPT: Scan: XMAS2: "
iptables -A INPUT -p tcp -m state --state ! ESTABLISHED --tcp-flags ALL SYN,RST,ACK,FIN,URG -j REJECT --reject-with tcp-reset
iptables -A INPUT -p tcp -m state --state ! ESTABLISHED --tcp-flags ALL ALL -j LOG --log-prefix "IPT: Scan: XMAS2: "
iptables -A INPUT -p tcp -m state --state ! ESTABLISHED --tcp-flags ALL ALL -j REJECT --reject-with tcp-reset
iptables -A INPUT -p tcp -m state --state ! ESTABLISHED --tcp-flags SYN,RST SYN,RST -j LOG --log-prefix "IPT: Scan: SYN-RST: "
iptables -A INPUT -p tcp -m state --state ! ESTABLISHED --tcp-flags SYN,RST SYN,RST -j REJECT --reject-with tcp-reset

#FINGERPRINTING
iptables -A INPUT -p tcp --dport 0 -j DROP
iptables -A INPUT -p udp --dport 0 -j DROP
iptables -A INPUT -p tcp --sport 0 -j DROP
iptables -A INPUT -p udp --sport 0 -j DROP

## nmap -sN (Scan: none of any flags = not implemented in TCP)
iptables -A INPUT -p tcp -m state --state ! ESTABLISHED --tcp-flags SYN,ACK,FIN,RST NONE -m limit --limit 10/minute --limit-burst 10 -j LOG --log-prefix "IPT: Scan: empty flags: "
iptables -A INPUT -p tcp -m state --state ! ESTABLISHED --tcp-flags SYN,ACK,FIN,RST NONE -j REJECT --reject-with tcp-reset

## nmap -sF (Scan: only FIN)
iptables -A INPUT -p tcp -m state --state ! ESTABLISHED --tcp-flags SYN,ACK,FIN,RST FIN -m limit --limit 10/minute --limit-burst 10 -j LOG --log-prefix "IPT: Scan: only FIN: "
iptables -A INPUT -p tcp -m state --state ! ESTABLISHED --tcp-flags SYN,ACK,FIN,RST FIN -j REJECT --reject-with tcp-reset

###[ hach_scan shain ]---------------------------------------------------------------
iptables -t filter -N hack_scan
## nmap -sS (Scan: SYN+ACK = no defense... )
## nmap -sX (Scan: SYN+ACK+FIN+RST [+PSH+URG] = not implemented in TCP)
iptables -t filter -A hack_scan -p tcp -m state --state ! ESTABLISHED --tcp-flags SYN,ACK,FIN,RST ALL -j LOG --log-prefix "IPT: Scan: SYN+ACK+FIN+RST: "
iptables -t filter -A hack_scan -p tcp -m state --state ! ESTABLISHED --tcp-flags SYN,ACK,FIN,RST ALL -j REJECT --reject-with tcp-reset

## NEW, not SYN
iptables -t filter -A hack_scan -p tcp ! --syn -m state --state NEW -m limit --limit 10/minute --limit-burst 10 -j LOG --log-prefix "IPT: NEW not SYN (rejected): "
iptables -t filter -A hack_scan -p tcp ! --syn -m state --state NEW -j REJECT --reject-with tcp-reset
###[ end of hach_scan chain ]==========================================================

iptables -t filter -A INPUT -p ALL -j hack_scan

4) Прочие ограничения.

Максимум 10 одновременных соединений к 80 порту с одного IP

iptables -A INPUT -p tcp --dport 80 -m iplimit --iplimit-above 10 -j REJECT

либо так

iptables -I INPUT -p tcp -m tcp --dport 80 -m connlimit --connlimit-above 10 --connlimit-mask 32 -j DROP

5) Системы обнаружения вторжения.

Такие системы позволяют быстро анализировать log-файлы на предмет совпадения строк и выполнять нужные действия. К примеру, рекомендую использовать fail2ban в связке с ipset. При выявлении нужной строки – просто выполняйте команду заноса нужного IP в набор от ipset.

6) Работа с памятью, swap.

vm.swappiness=10
vm.vfs_cache_pressure=1000

Подробнее о них можно прочесть здесь

7) Анализ в режиме реального времени.

Вместо netstat для определения соединений, используйте ss. Вот, результаты тестов из сети:

# time (netstat -an|grep ":80\ "|wc -l)
42537
real	      0m7.001s
user	      0m0.388s
sys	       0m6.720s

# time (ss -an|grep ":80\ "|wc -l)
41403
real	      0m0.139s
user	      0m0.168s
sys	       0m0.068s

Как видим, результат налицо.

8 ) различные утилиты.

logtop

9)Дополнительно.

https://habr.com/ru/company/otus/blog/550820/
https://blog.cloudflare.com/syn-packet-handling-in-the-wild/
https://javapipe.com/blog/iptables-ddos-protection/

2 коментарі “Защита от флуда, DDoS’a, повышение производительности”

Здравствуйте, подскажите пожалуйста, как защитить мой сайт на Joomla 2.5 , от атаки? сайт второй день не работает, на хостинге говорят дос атака, перегрузка сервера, хостинг nic.ru.
Зарание спасибо!

Добрый вечер.
Здесь нету однозначного ответа. Вообще нужно определить характер атаки: на порт или на на конкретный сайт. Частенько помогает установка fail2ban и последующая настройка с баном через файервол.

Залишити коментар до skeletor Скасувати коментар

Ваша e-mail адреса не оприлюднюватиметься. Обов’язкові поля позначені *

Домашняя страничка Andy
Записки молодого админа
Самостоятельная подготовка к Cisco CCNA
Самостоятельная подготовка к Cisco CCNP
Powered by Muff