Атаки DoS на веб-сервер Apache. Как бороться. Метод 1.

Очень интересный метод атаки на любой веб-сервер это Slow Http Post. Подробно описывать не буду, в сети это все есть. Вкратце, злоумышленник передает серверу запрос. В запросе есть поле Content-Length, в нем содержится инфа об объеме данных в запросе. Веб-сервер начинает принимать данные… И злоумышленник начинает передавать данные с очень-очень медленной скоростью(потому и slow). Этим вытягиваем ресурсы сервера и несколько сот запросов кладут  Apache с дефолтными настройками на небольшой VDS/VPS.
Я проверил не только апач, но и мелкософтовский IIS. Если бомбить хидерами, то сервер просто временно не доступен(при отмене атаки все возвращается). А вот если бомбить именно slow post запросы, то сервак ложится наглухо и вернуть можно все только перезапуском.
Тестировать можно утилитой OWASP Http DoS tool
Утилита общедоступна, проста в использовании, так что любой школьник-кулхацкер может положить вам сайт, если вы конечно не позаботились об безопасности.

Итак, метод 1. Ставим mod_security на Apache 2.2 в Centos 6.5

Mod_security является по сути фаерволлом для веб-сервера Apache. Модуль ставится очень просто, но нужна его настройка, так как по дефолту правил от slow post нету…

1.  Подключаем Epel репозиторий

rpm -Uvh http://mirrors.kernel.org/fedora-epel/6/i386/epel-release-6-8.noarch.rpm

2. Ставим модуль

yum install mod_security

3. Рестартуем апач и проверим что модуль установлен.

service httpd restart

 

apachectl -M | grep sec
security2_module (shared)
Syntax OK

4. Правим конфиг для mod_security
Все правила выбираем по вкусу https://github.com/SpiderLabs/owasp-modsecurity-crs
Создаем конфиг /etc/httpd/conf.d/mod_sec.conf  и херачим туда правила

LoadModule unique_id_module modules/mod_unique_id.so
LoadModule security2_module modules/mod_security2.so
SecRuleEngine On
SecAuditEngine Off
SecDataDir /tmp
SecRule REMOTE_ADDR “^127.0.0.1$” “id:’400000′,phase:1,nolog,allow”
SecRule REQUEST_BASENAME “!(.avi$|.bmp$|.css$|.doc$|.flv$|.gif$|
.htm$|.html$|.ico$|.jpg$|.js$|.mp3$|
.mpeg$|.pdf$|.png$|.pps$|.ppt$|.swf$|
.txt$|.wmv$|.xls$|.xml$|.zip$)”
“id:’400001′,phase:1,nolog,pass,initcol:ip=%{REMOTE_ADDR},setvar:ip.requests=+1,expirevar:ip.requests=1”
SecRule ip:requests “@eq 5” “id:’400002′,phase:1,pass,nolog,setvar:ip.block=1,expirevar:ip.block=5,setvar:ip.blocks=+1,expirevar:ip.blocks=3600”
SecRule ip:blocks “@ge 5” “id:’400003′,phase:1,deny,log,logdata:’req/sec: %{ip.requests}, blocks: %{ip.blocks}’,status:403”
SecRule ip:block “@eq 1” “id:’400004′,phase:1,deny,nolog,status:403”
#Limit argument name length
SecRule &TX:ARG_NAME_LENGTH “@eq 1” “chain,phase:2,t:none,block,msg:’Argument name too long’,id:’960209′,severity:’4′,rev:’2′,ver:’OWASP_CRS/2.2.9′,maturity:’9′,accuracy:’9′,tag:’OWASP_CRS/POLICY/SIZE_LIMIT'”
SecRule ARGS_NAMES “@gt %{tx.arg_name_length}” “t:none,t:length,setvar:’tx.msg=%{rule.msg}’,setvar:tx.anomaly_score=+%{tx.notice_anomaly_score},setvar:tx.%{rule.id}-OWASP_CRS/POLICY/SIZE_LIMIT-%{matched_var_name}=%{matched_var}”
# Limit value name length
SecRule &TX:ARG_LENGTH “@eq 1” “chain,phase:2,t:none,block,msg:’Argument value too long’,id:’960208′,severity:’4′,rev:’2′,ver:’OWASP_CRS/2.2.9′,maturity:’9′,accuracy:’9′,tag:’OWASP_CRS/POLICY/SIZE_LIMIT'”
SecRule ARGS “@gt %{tx.arg_length}” “t:none,t:length,setvar:’tx.msg=%{rule.msg}’,setvar:tx.anomaly_score=+%{tx.notice_anomaly_score},setvar:tx.%{rule.id}-OWASP_CRS/POLICY/SIZE_LIMIT-%{matched_var_name}=%{matched_var}”
# Maximum number of arguments in request limited
SecRule &TX:MAX_NUM_ARGS “@eq 1” “chain,phase:2,t:none,block,msg:’Too many arguments in request’,id:’960335′,severity:’4′,rev:’2′,ver:’OWASP_CRS/2.2.9′,maturity:’9′,accuracy:’9′,tag:’OWASP_CRS/POLICY/SIZE_LIMIT'”
SecRule &ARGS “@gt %{tx.max_num_args}” “t:none,setvar:’tx.msg=%{rule.msg}’,setvar:tx.anomaly_score=+%{tx.notice_anomaly_score},setvar:tx.%{rule.id}-OWASP_CRS/POLICY/SIZE_LIMIT-%{matched_var_name}=%{matched_var}”
# Limit arguments total length
SecRule &TX:TOTAL_ARG_LENGTH “@eq 1” “chain,phase:2,t:none,block,msg:’Total arguments size exceeded’,id:’960341′,severity:’4′,rev:’2′,ver:’OWASP_CRS/2.2.9′,maturity:’9′,accuracy:’9′,tag:’OWASP_CRS/POLICY/SIZE_LIMIT'”
SecRule ARGS_COMBINED_SIZE “@gt %{tx.total_arg_length}” “t:none,setvar:’tx.msg=%{rule.msg}’,setvar:tx.anomaly_score=+%{tx.notice_anomaly_score},setvar:tx.%{rule.id}-OWASP_CRS/POLICY/SIZE_LIMIT-%{matched_var_name}=%{matched_var}”

## — File upload limits —
# Individual file size is limited
SecRule &TX:MAX_FILE_SIZE “@eq 1” “chain,phase:1,t:none,block,msg:’Uploaded file size too large’,id:’960342′,severity:’4′,rev:’2′,ver:’OWASP_CRS/2.2.9′,maturity:’9′,accuracy:’9′,tag:’OWASP_CRS/POLICY/SIZE_LIMIT'”
SecRule REQUEST_HEADERS:Content-Type “@beginsWith multipart/form-data” “chain”
SecRule REQUEST_HEADERS:Content-Length “@gt %{tx.max_file_size}” “t:none,setvar:’tx.msg=%{rule.msg}’,setvar:tx.anomaly_score=+%{tx.notice_anomaly_score},setvar:tx.%{rule.id}-OWASP_CRS/POLICY/SIZE_LIMIT-%{matched_var_name}=%{matched_var}”
# Combined file size is limited
SecRule &TX:COMBINED_FILE_SIZES “@eq 1” “chain,phase:2,t:none,block,msg:’Total uploaded files size too large’,id:’960343′,severity:’4′,rev:’2′,ver:’OWASP_CRS/2.2.9′,maturity:’9′,accuracy:’9′,tag:’OWASP_CRS/POLICY/SIZE_LIMIT'”
SecRule FILES_COMBINED_SIZE “@gt %{tx.combined_file_sizes}” “t:none,setvar:’tx.msg=%{rule.msg}’,setvar:tx.anomaly_score=+%{tx.notice_anomaly_score},setvar:tx.%{rule.id}-OWASP_CRS/POLICY/SIZE_LIMIT-%{matched_var_name}=%{matched_var}”
SecReadStateLimit 100
#
# Mitigate Slow HTTP POST attacks
#
# Must have the mod_reqtimeout module installed
# You should adjust the RequestReadTimeout body directive setting to a limit
# that will allow any legitimate slow clients or large file uplaods.
#

RequestReadTimeout body=30
SecRule RESPONSE_STATUS “@streq 408” “phase:5,id:’981051′,t:none,nolog,pass,setvar:ip.slow_dos_counter=+1,expirevar:ip.slow_dos_counter=60”
SecRule IP:SLOW_DOS_COUNTER “@gt 5” “phase:1,id:’981052′,t:none,log,drop,msg:’Client Connection Dropped due to high # of slow DoS alerts'”
SecRule IP:DOS_BLOCK “@eq 1” “chain,phase:1,id:’981044′,drop,msg:’Denial of Service (DoS) Attack Identified from %{tx.real_ip} (%{tx.dos_block_counter} hits since last alert)’,setvar:ip.dos_block_counter=+1”
SecRule &IP:DOS_BLOCK_FLAG “@eq 0” “setvar:ip.dos_block_flag=1,expirevar:ip.dos_block_flag=60,setvar:tx.dos_block_counter=%{ip.dos_block_counter},setvar:ip.dos_block_counter=0”
#
# Block and track # of requests but don’t log
SecRule IP:DOS_BLOCK “@eq 1” “phase:1,id:’981045′,t:none,drop,nolog,setvar:ip.dos_block_counter=+1”
#
# skipAfter Check
# There are different scenarios where we don’t want to do checks –
# 1. If the current IP address has already been blocked due to high requests
# In this case, we skip doing the request counts.
#
SecRule IP:DOS_BLOCK “@eq 1” “phase:5,id:’981046′,t:none,nolog,pass,skipAfter:END_DOS_PROTECTION_CHECKS”
#
# DOS Counter
# Count the number of requests to non-static resoures
#
SecRule REQUEST_BASENAME “!.(jpe?g|png|gif|js|css|ico)$” “phase:5,id:’981047′,t:none,nolog,pass,setvar:ip.dos_counter=+1”
#
# Check DOS Counter
# If the request count is greater than or equal to user settings,
# we then set the burst counter
#
SecRule IP:DOS_COUNTER “@gt %{tx.dos_counter_threshold}” “phase:5,id:’981048′,t:none,nolog,pass,t:none,setvar:ip.dos_burst_counter=+1,expirevar:ip.dos_burst_counter=%{tx.dos_burst_time_slice},setvar:!ip.dos_counter”
#
# Check DOS Burst Counter and set Block
# Check the burst counter – if greater than or equal to 2, then we set the IP
# block variable for 5 mins and issue an alert.
#
SecRule IP:DOS_BURST_COUNTER “@ge 2” “phase:5,id:’981049′,t:none,log,pass,msg:’Potential Denial of Service (DoS) Attack from %{tx.real_ip} – # of Request Bursts: %{ip.dos_burst_counter}’,setvar:ip.dos_block=1,expirevar:ip.dos_block=%{tx.dos_block_timeout}”
SecMarker END_DOS_PROTECTION_CHECKS

SecRule ARGS “^” “chain,phase:2,t:none,nolog,pass,capture,id:’900032′,rev:’2.2.9′,setvar:tx.%{matched_var_name}=+1”
SecRule TX:/^ARGS:/ “@gt 1” “chain,t:none”
SecRule MATCHED_VARS_NAMES “TX:(ARGS:.*)” “chain,capture,t:none,setvar:tx.hpp_names=%{tx.1}”
SecRule ARGS “.*” “chain,t:none,capture,setvar:tx.arg_counter=+1,setvar:’tx.hppnamedata_%{tx.arg_counter}=%{matched_var_name}=%{tx.0}'”
SecRule TX:/HPPNAMEDATA_/ “@contains %{tx.hpp_names}” “chain,setvar:tx.hpp_counter=+1,setvar:tx.hpp_counter_%{tx.hpp_counter}=%{matched_var}”
SecRule TX:/HPP_COUNTER_/ “ARGS:(.*)?=(.*)” “capture,setvar:’tx.hpp_data=%{tx.hpp_data},%{tx.2}'”

5. Рестартуем апач и проверяем утилитой от Owasp.
До мода  у меня разрастались процессы httpd до безумия и сайт ложился. После мода, процессы в норме и сайт работает.
p.s. конфиг в нормальном виде http://pastebin.com/XPRdFiS4

 

Comments

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *