パーサーとの戦い方

画像

キーポイント:

*訪問者のPTRを確認するスクリプトの実装。

*マップブランチを使用したIfIsEvilスタイルのnginxの構成。

*マップ変数の場所名。

* try_files / nonexist $ map_varによるブランチコントロール。



負荷の高い人気のあるサイトの多くは、ライブの訪問者に加えて、有益な効果はないが、偽のトラフィックを作成し、既にロードされたシステムに負荷をかけるさまざまなパーサー、ボット、およびその他の自動スキャナーによって訪問されるという事実に苦しんでいます。 この場合、私は検索ボットを意味するわけではありません。検索ボットはプロジェクトをロードすることが多いのですが、標準化されておらず、単にプロジェクトに必要です。

クライアントの1人は、1日の特定の時間に雪崩のような負荷増加の問題を定期的に経験しました。 定期的に、1日に1回、さらに頻繁に訪問が流入し、サーバー上のLAが大幅に増加しました。 スプリアストラフィックに対する保護を構築することが決定されました。







スプリアストラフィックには、特定のパターンの動作とプロパティがあることがわかりました。


*リクエストソース別-Amazon、Torサブネット。

*エントリポイント別-商品セクションへのほとんどのリクエスト。

* UserAgentによると、ボットの主要部分はUA検索エンジンGoogle、Yandex、Bingによって送信されましたが、客観的には送信されませんでした。

*リファラーによる-基本的にリファラーは空でした。



チェック、制限、およびロックの実装:


*ホワイトリストに既知のIPを手動で追加

*以前に侵害されたIP-ブラックリスト

*ホワイトリスト以外のすべてのlimit_req_zoneを制限する

* PTRレコードが検索エンジンの実際のPTRレコードに準拠しているかどうかをUA検索エンジンからの訪問者に確認し、認証済みユーザーのホワイトリストに入れて、常に許可します。

* LAのしきい値「攻撃」の増加:

** UAをブラックリストに登録せず、PTR検証に合格してブロックしません。

**アクセスログでリファラーの再現性を確認し、指定されたエントリ数を超えるリファラーで訪問者をブロックします

**残りをcaptchaで確認し、成功した場合は解決します。



最初の3つのポイントは一般的なソリューションであるため、PTRで訪問者をチェックし、try_files / nonexist $ map_varコンストラクトと複雑なマップを使用してnginxを構成することに集中します。



検索エンジンの実際のPTRレコードとPTRレコードのコンプライアンスについて、UA検索エンジンからの訪問者を非同期にチェックするスクリプトを実装しました。




cronで1分間に1回実行されます。 UAからのIPビジターの一意のリストに基づいて、検索エンジンはPTRをチェックし、第2レベルのドメイン名をチェックします。 ドメインが一致する場合、ホワイトリストにIPを追加し、そうでない場合はブラックリストに追加します。 リストをチェックするとき、スクリプトは、検証プロセスを高速化するために、以前に検証されたIPのPTRをチェックしません。 これにより、高速でアクセスログがいっぱいになった場合でも、アクセスログからIPリストを1分ごとに確認できます。 ブラックリストへのエントリは、大規模なNATネットワークでの共通IPの永続的なブロックを除外するために、ブロックリストから一定の削除時間で入力されます。



したがって、nginx configに含まれるptr_blacklist.mapおよびptr_whitelist.mapファイルを作成して維持します。



それは毎分始まります。

UAおよびPTRコンプライアンス検証スクリプトリスト:
#!/bin/bash #   ,     , #        ,    . # Export inc file for nginx EXPORT_MAP=true # Domain list DOMAIN_LIST="domain" # Block time (in minutes) BLOCK_TIME=1440 # White list IP IP_WHITELIST="" # White list PTR BOTS="google|yandex|bing|Bing|msn" # false - not block IP if there is a PTR record BLOCK_WITH_PTR=true UNBLOCK_ENABLE=true LOGFILE=/var/log/ua-table.log LOGFILE2=/var/log/ua-table-history.log LOCK=/tmp/ua_check.lock D=$DOMAIN_LIST #   ptr_blacklist  ptr_whitelist       map- #      BL_FILE=/etc/nginx/vhosts.d/ptr_blacklist WL_FILE=/etc/nginx/vhosts.d/ptr_whitelist BL_FILE_MAP=$BL_FILE.map WL_FILE_MAP=$WL_FILE.map TMP_LOG=/tmp/$D-acc-temp.log TMP_LOG1=/tmp/$D-acc-temp1.log NGINX_LOG=/srv/www/$D/shared/log/$D-acc.log [ ! -f /usr/bin/host ] && echo "/usr/bin/host not found. Please yum install bind-utils" && exit [ -z "$DOMAIN_LIST" ] && echo "DOMAIN_LIST is empty" [ ! -f $LOGFILE ] && touch $LOGFILE [ ! -f $LOGFILE2 ] && touch $LOGFILE2 debug="0" function e { echo -e $(/bin/date "+%F %T") $1 } #     ,       [ -f $LOCK ] && e "Script $0 is already runing" && exit /bin/touch $LOCK DT=`/bin/date "+%F %T"` if [ ! -f $NGINX_LOG ];then echo "Log ($NGINX_LOG) not found." /bin/rm -rf $LOCK exit fi #    #    acc-,  ,         referer /bin/egrep "Yandex|Google|bingbot|Bing" $NGINX_LOG | /usr/bin/awk '{print $1}' | /bin/sort -n | /usr/bin/uniq > $TMP_LOG if [ "$EXPORT_MAP" == "true" ]; then [ ! -f $BL_FILE_MAP ] && /bin/touch $BL_FILE_MAP [ ! -f $WL_FILE_MAP ] && /bin/touch $WL_FILE_MAP [ ! -f $BL_FILE ] && /bin/touch $BL_FILE || /bin/cp -f $BL_FILE $BL_FILE.bak [ ! -f $WL_FILE ] && /bin/touch $WL_FILE || /bin/cp -f $WL_FILE $WL_FILE.bak fi #   UNBLOCK=0 while read line do if [[ "$line" == *=* ]]; then GET_TIME=`echo $line | /usr/bin/awk -F"=" '{print $2}'` NOW=`/bin/date '+%s'` #echo $NOW #echo $GET_TIME if [ "$NOW" -gt "$GET_TIME" ]; then IP=`echo $line | awk '{print $3}'` e "$IP unblocked." >> $LOGFILE2 /bin/sed -i '/'$IP'/d' $BL_FILE /bin/sed -i '/'$IP'/d' $LOGFILE UNBLOCK=1 #else #e "Nothing to unblock" >> $LOGFILE2 fi fi done < $LOGFILE #   while read line do IP=$line wl=0 bl=0 #    WL for I in $IP_WHITELIST do if [ "$I" = "$IP" ];then wl=1 fi done #       WL for I in $(/usr/bin/awk '{print $1}' < "$WL_FILE" ) do if [ "$I" = "$IP" ];then wl=1 fi done #       BL for I in $(/usr/bin/awk '{print $1}' < "$BL_FILE" ) do if [ "$I" = "$IP" ];then bl=1 fi done #  IP   ,    ,    PTR if [ "$wl" = "1" -o "$bl" = "1" ]; then [ "$debug" -gt "1" ] && e "$IP in white or black list" >> $LOGFILE2 else PTR="" SRCHBOT="" FINDPTR="`/usr/bin/host $IP | /bin/grep -v 'not found' | /bin/grep -v 'no PTR record' | /usr/bin/head -1 | /usr/bin/awk '{ print $5 }' | /bin/sed 's/\.$//'`" if [ -z "$FINDPTR" ];then PTR=" (PTR record not found)" else PTR=" ($FINDPTR)" fi SRCHBOT=`/usr/bin/host $IP | /usr/bin/awk '{ print $5 }' | /usr/bin/rev | /usr/bin/cut -d . -f 2-3 | /usr/bin/rev | /bin/egrep "$BOTS"` [ -n "$SRCHBOT" ] && BOT="YES" || BOT="NO" [ -z "$BLOCK_WITH_PTR" ] && BLOCK_WITH_PTR=true if [ "$EXPORT_MAP" == "true" ]; then if [ "$BOT" == "NO" ]; then e "$IP blocked $BLOCK_TIME minutes. ($D) Unblock = `/bin/date --date="$BLOCK_TIME minute" +%s`" >> $LOGFILE e "$IP$PTR blocked $BLOCK_TIME minutes. ($D)" >> $LOGFILE2 echo "$IP 0;" >> $BL_FILE else echo "$IP 1;" >> $WL_FILE fi fi fi done < $TMP_LOG #     map- if [ "$EXPORT_MAP" == "true" ]; then /bin/sort -u -o $BL_FILE $BL_FILE > /dev/null 2>&1 /bin/sort -u -o $WL_FILE $WL_FILE > /dev/null 2>&1 MAP_CHANGED=0 if ! diff $BL_FILE $BL_FILE.bak > /dev/null 2>&1; then /bin/cp -f $BL_FILE_MAP $BL_FILE_MAP.bak > /dev/null 2>&1 /bin/cp -f $BL_FILE $BL_FILE_MAP > /dev/null 2>&1 MAP_CHANGED=1 fi if ! diff $WL_FILE $WL_FILE.bak > /dev/null 2>&1; then /bin/cp -f $WL_FILE_MAP $WL_FILE_MAP.bak > /dev/null 2>&1 /bin/cp -f $WL_FILE $WL_FILE_MAP > /dev/null 2>&1 MAP_CHANGED=1 fi if [ "$MAP_CHANGED" -eq "1" -o "$UNBLOCK" -eq "1" ]; then RELOAD=`/usr/sbin/nginx -t 2>&1 | /bin/grep ok` if [ -n "$RELOAD" ];then /sbin/service nginx reload e "nginx is reloaded" >> $LOGFILE2 else ERROR_RELOAD=`/sbin/service nginx configtest 2>&1` /bin/cp -f $BL_FILE_MAP.bak $BL_FILE_MAP > /dev/null 2>&1 /bin/cp -f $WL_FILE_MAP.bak $WL_FILE_MAP > /dev/null 2>&1 e "nginx error config test failed" >> $LOGFILE2 fi fi fi /bin/rm -rf $LOCK
      
      







リファラーの頻度と、次の形式のファイルreferer-block.confの形成を確認するスクリプト:


 ~domain.ru 0; ~… 1; ~… 1;
      
      





それは毎分始まります。

リファラーの頻度を確認するリストスクリプト
 #!/bin/bash # referer_protect v.1.0.6 #   ,     , #        ,    . RECORDS=500 DOMAIN_LIST=domain LA=15 # if Load Average > $LA = Referer is block BLOCK_TIME=360 #in minutes #REF_WHITELIST="" BLOCK_ENABLE=true # true/false - enable/disable add firewall rule. email="mail@mail.ru" LOGFILE=/var/log/referer-table.log LOGFILE2=/var/log/referer-table-history.log LOCK=/tmp/referer.lock MSG_ALERT=/tmp/msg-alert.tmp debug="0" LA_CURRENT="`cat /proc/loadavg | awk '{ print $1}' | awk 'BEGIN { FS="."; }{ print $1}'`" DT=`date "+%F %T"` [ ! -f $LOGFILE ] && touch $LOGFILE [ -f "$MSG_ALERT" ] && rm -f $MSG_ALERT function e { echo -e $(date "+%F %T") $1 } function msg { echo "Referer:$REFERER. Domain:$D" >> $MSG_ALERT } function send_mail { if [ "$BLOCK_ENABLE" = "true" -a "$LA_CURRENT" -gt "$LA" ];then cat $MSG_ALERT | mailx -s "Referers report. Warning" $email elif [ "$BLOCK_ENABLE" = "true" -a "$LA_CURRENT" -le "$LA" ];then cat $MSG_ALERT | mailx -s "Referers report. Notice " $email else cat $MSG_ALERT | mailx -s "Referers report. Notice (Test mode)" $email fi } [ -f $LOCK ] && e "Script $0 is already runing" && exit touch $LOCK NEED_NGINX_RELOAD=0 for D in $DOMAIN_LIST do TMP_LOG=/tmp/ddos-$D-acc-referer.log TMP_AWK=/tmp/tmp_$D-awk.tmp #NGINX_LOG=/srv/www/$D/logs/$D-acc NGINX_LOG=/srv/www/$D/shared/log/$D-acc.log REFCONF=/etc/nginx/referer-block-$D.conf [ ! -s "$REFCONF" ] && echo "~$D 0;" >> $REFCONF if [ ! -f $NGINX_LOG ];then echo "Log ($NGINX_LOG) not found." /bin/rm -rf $LOCK exit fi tail -10000 $NGINX_LOG | awk '($9 == "200") || ($9 == "404")' | awk '{print $11}' | sort | uniq -c | sort -n | awk -vx=$RECORDS ' $1 > x {print $2} ' > $TMP_LOG sed -i "s/\"//g" $TMP_LOG #   sed -i "/^-/d" $TMP_LOG #  referer "-" sed -i "/$D/d" $TMP_LOG #    sed -i "/^localhost/d" $TMP_LOG #  localhost awk -F/ '{print $3}' $TMP_LOG > $TMP_AWK #     url cat $TMP_AWK > $TMP_LOG #   referer while read line do if [[ "$line" == *=* ]]; then GET_TIME=`echo $line | awk -F"=" '{print $2}'` NOW=`date +%s` #echo $NOW #echo $GET_TIME if [ "$NOW" -gt "$GET_TIME" ]; then REFERER=`echo $line | awk '{print $4}'` e "Referer $REFERER unblocked." >> $LOGFILE2 /bin/sed -i '/'$REFERER'/d' $LOGFILE /bin/sed -i '/'$REFERER'/d' $REFCONF NEED_NGINX_RELOAD=1 fi fi done < $LOGFILE #  referer while read line do REFERER=$line DOUBLE=`cat $REFCONF | grep "$REFERER"` if [ -n "$DOUBLE" ]; then [ "$debug" != "0" ] && e "referer $REFERER exist in DROP rule" else if [ "$BLOCK_ENABLE" = "true" -a "$LA_CURRENT" -gt "$LA" ];then echo "~$REFERER 1;" >> $REFCONF e "Referer $REFERER blocked $BLOCK_TIME minutes ($D) Unblock = `date --date="$BLOCK_TIME minute" +%s`" >> $LOGFILE e "Referer $REFERER blocked $BLOCK_TIME minutes ($D)" >> $LOGFILE2 NEED_NGINX_RELOAD=1 if [ ! -s "$MSG_ALERT" ];then echo "Status: WARNING" > $MSG_ALERT echo "Date: $DT" >> $MSG_ALERT echo "Referer: $RECORDS matches from 10000" >> $MSG_ALERT echo "LA: $LA_CURRENT" >> $MSG_ALERT echo "Referer(s) is blocked on $BLOCK_TIME minutes:" >> $MSG_ALERT echo "" >> $MSG_ALERT fi msg elif [ "$BLOCK_ENABLE" = "true" -a "$LA_CURRENT" -le "$LA" ];then TESTDOUBLE=`cat $LOGFILE | grep "$REFERER"` if [ -z "$TESTDOUBLE" ]; then e "Referer $REFERER TEST blocked $BLOCK_TIME minutes ($D) Unblock = `date --date="$BLOCK_TIME minute" +%s`" >> $LOGFILE e "TEST. Referer $REFERER TEST blocked $BLOCK_TIME minutes ($D)" >> $LOGFILE2 if [ ! -s "$MSG_ALERT" ];then echo "Status: Notice" > $MSG_ALERT echo "Date: $DT" >> $MSG_ALERT echo "Referer: $RECORDS matches from 10000" >> $MSG_ALERT echo "LA: $LA_CURRENT" >> $MSG_ALERT echo "Referer(s) not blocking:" >> $MSG_ALERT echo "" >> $MSG_ALERT fi msg fi else TESTDOUBLE=`cat $LOGFILE | grep "$REFERER"` if [ -z "$TESTDOUBLE" ]; then e "Referer $REFERER TEST blocked $BLOCK_TIME minutes ($D) Unblock = `date --date="$BLOCK_TIME minute" +%s`" >> $LOGFILE e "TEST. Referer $REFERER TEST blocked $BLOCK_TIME minutes ($D)" >> $LOGFILE2 if [ ! -s "$MSG_ALERT" ];then echo "Date: $DT" > $MSG_ALERT echo "Current referer found over $RECORDS matches from 10000 records, but script working is TEST MODE " >> $MSG_ALERT echo "Current LA - $LA_CURRENT" >> $MSG_ALERT echo "Referer(s) not blocking:" >> $MSG_ALERT echo "" >> $MSG_ALERT fi msg fi fi fi done < $TMP_LOG [ -n "email" -a -s "$MSG_ALERT" ] && send_mail done # reload nginx if config change if [ $NEED_NGINX_RELOAD -eq 1 ]; then /sbin/service nginx reload >/dev/null 2>/dev/null fi /bin/rm -rf $LOCK
      
      







nginx設定ファイルは、シンボリックリンクとして、通常および高LAモードで動作する2つのファイルのいずれかを指します。


モードはCronから毎分実行されるスクリプトによって切り替えられます

モード切り替えスクリプト:
 #!/bin/bash ### check LA level MAX_LA=10 processid=`/sbin/pidof -x $(basename $0) -o %PPID` if [[ $processid ]];then exit fi CFG_DDOS='fpm.domain.ru.ddos' CFG_NODDOS='fpm.domain.ru.noddos' load_average=$(uptime | awk '{print $11}' | cut -d "." -f 1) echo "$(date '+%Y-%m-%d %H:%M') : LA $load_average" if [[ $load_average -ge $MAX_LA ]]; then if [ -f /tmp/la_flag ]; then date '+%s' > /tmp/la_flag exit 1 else # echo "$(date +%Y-%m-%d-%H-%M)" date '+%s' > /tmp/la_flag mv /etc/nginx/vhosts.d/new.domain.ru.conf /etc/nginx/vhosts.d/new.domain.ru.conf.bak > /dev/null 2>&1 ln -s /etc/nginx/vhosts.d/$CFG_DDOS /etc/nginx/vhosts.d/new.domain.ru.conf reload=`/usr/sbin/nginx -t 2>&1 | grep ok` if [ -n "$reload" ];then /sbin/service nginx reload rm -f /etc/nginx/vhosts.d/new.domain.ru.conf.bak > /dev/null 2>&1 echo "$(date '+%Y-%m-%d %H:%M') : DDOS config up $reload" exit 0 else /sbin/service nginx configtest 2>&1 mv /etc/nginx/vhosts.d/new.domain.ru.conf.bak /etc/nginx/vhosts.d/new.domain.ru.conf > /dev/null 2>&1 echo "nginx error config ddos test failed" echo "alarm nginx config ddos test failed" | mail -s alarm root exit 1 fi fi else if [ -f /tmp/la_flag ]; then TIMEA=`cat /tmp/la_flag` TIMEC=`date '+%s'` TIMED=$(( $TIMEC - $TIMEA )) if [ $TIMED -gt 600 ]; then echo "high LA ENDED $(date +%Y-%m-%d-%H-%M)" rm -f /tmp/la_flag > /dev/null 2>&1 mv /etc/nginx/vhosts.d/new.domain.ru.conf /etc/nginx/vhosts.d/new.domain.ru.conf.bak > /dev/null 2>&1 ln -s /etc/nginx/vhosts.d/$CFG_NODDOS /etc/nginx/vhosts.d/new.domain.ru.conf reload=`/usr/sbin/nginx -t 2>&1 | grep ok` echo "$(date '+%Y-%m-%d %H:%M') : NO DDOS config up $reload" if [ -n "$reload" ];then /sbin/service nginx reload rm -f /etc/nginx/vhosts.d/new.domain.ru.conf.bak > /dev/null 2>&1 echo "$(date '+%Y-%m-%d %H:%M') : NO ddos config up" exit 0 else /sbin/service nginx configtest 2>&1 mv /etc/nginx/vhosts.d/new.domain.ru.conf.bak /etc/nginx/vhosts.d/new.domain.ru.conf > /dev/null 2>&1 echo "nginx error config noddos test failed" echo "alarm nginx config noddos test failed" | mail -s alarm root exit 1 fi else exit 1 fi else exit 1 fi fi
      
      







構成の一部は、メイン構成ファイルに含まれる別のファイルに移動されます。


vhosts.d / map.domain.ru.incの両方のモードの一般的な構成パラメーターを含むファイル:
 map_hash_bucket_size 128; geoip_country /usr/share/GeoIP/GeoIP.dat; limit_req_zone $newlimit_addres1 zone=newone:10m rate=50r/m; map $whitelist-$remote_addr:$remote_port $newlimit_addres1 { ~"^0" $binary_remote_addr; ~"^1-(?<match_rap>.*)" $match_rap; } geo $whitelist { default 0; 91.205.47.150 1; 194.87.91.154 1; 83.69.225.78 1; 77.88.18.82 1; 91.143.46.202 1; 213.180.192.0/19 1; 87.250.224.0/19 1; 77.88.0.0/18 1; 93.158.128.0/18 1; 95.108.128.0/17 1; 178.154.128.0/17 1; 199.36.240.0/22 1; 84.201.128.0/18 1; 141.8.128.0/18 1; 188.134.88.105 1; 89.163.3.25 1; 46.39.246.91 1; 84.21.76.123 1; 136.243.83.53 1; 77.50.238.152 1; 83.167.117.49 1; 109.188.82.40 1; 79.141.227.19 1; 176.192.62.78 1; 86.62.91.133 1; 144.76.88.101 1; } #     block_referer.sh map $http_referer $bad_referer { default "0"; include /etc/nginx/referer-block.conf; } map $http_referer:$request_method $bad_post_referer { default "0"; "~*domain.ru.*:POST$" "0"; "~*:POST$" "1"; include /etc/nginx/referer-block.conf; } #      map $query_string $bad_query { ... default 0; } #  ,     /checkcapcha.php map $http_cookie $allowed_cookie { "~somecookie" 1; default 0; }   GeoIP     map $geoip_country_code $allowed_country { RU 1; default 0; } #   Amazon include vhosts.d/deny-amazon.inc; #      map $remote_addr $valid_addr { include vhosts.d/main_blacklist.map; include vhosts.d/main_whitelist.map; default 2; } # UA - map $http_user_agent $user_agent_search_bot { "~Yandex" "1"; "~Google" "1"; "~*bing" "1"; "~*MSNBot" "1"; default ""; } map $remote_addr $ptr_wl_bl { include vhosts.d/ptr_blacklist.map; include vhosts.d/ptr_whitelist.map; default ""; } map "$user_agent_search_bot:$ptr_wl_bl" $searchbot { "1:1" "1"; "1:0" "0"; default "2"; }
      
      







構成ファイルのリスト


通常の操作の主な構成はvhosts.d / fpm.domain.ru.noddosです。
 include vhosts.d/map.domain.ru.inc; map "$searchbot:$valid_addr:$bad_referer:$bad_query" $root_location_p1 { default @allow_limit; "~^1:" @allow; "~^2:1" @allow_limit; "~^0" @loc_403; "~^2:0" @loc_403; "2:2:1:0" @loc_403; "2:2:1:1" @loc_403; "2:2:0:1" @loc_403; } map "$searchbot:$valid_addr:$bad_post_referer:$bad_query" $root_only_location_p1 { default @allow_limit; "~^1:" @allow; "~^2:1" @allow_limit; "~^0" @loc_403; "~^2:0" @loc_403; "2:2:1:0" @loc_403; "2:2:1:1" @loc_403; "2:2:0:1" @loc_403; } ######################################################## server { listen 80; listen 443 ssl; fastcgi_read_timeout 300s; fastcgi_send_timeout 300s; fastcgi_connect_timeout 300s; server_name domain.ru www.domain.ru m.domain.ru www.m.domain.ru; ssl_certificate ssl/www.domain.ru.crt; ssl_certificate_key ssl/www.domain.ru.key; charset UTF-8; access_log /srv/www/domain/shared/log/domain-acc.log main; error_log /srv/www/domain/shared/log/domain-err.log; root /srv/www/domain/current/public/; error_page 500 502 /highla.html; #  capcha   POST  action="/checkcapcha.php" location = /highla.html { charset UTF-8; root /srv/www/domain/current/public/; allow all; } #       . location = /checkcapcha.php { charset UTF-8; root /srv/www/domain/current/public/; include fastcgi_params; fastcgi_buffers 8 16k; fastcgi_buffer_size 32k; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; fastcgi_param REQUEST_SCHEME $scheme; fastcgi_param HTTPS $https if_not_empty; fastcgi_pass 127.0.0.1:9000; allow all; } #  location       map location @loc_403 { access_log /srv/www/domain/shared/log/loc_403-acc main; return 403; } location @allow { access_log /srv/www/domain/shared/log/allow-acc main; add_header X-debug-message "Allow"; try_files $uri /index.php?$query_string; } location @allow_limit { limit_req zone=newone burst=15; access_log /srv/www/domain/shared/log/allow-acc main; add_header X-debug-message "Allow"; try_files $uri /index.php?$query_string; } location @deny { access_log /srv/www/domain/shared/log/deny-acc main; add_header X-debug-message "Deny"; return 403; } location @restrict { access_log /srv/www/domain/shared/log/resrtict-acc main; add_header X-debug-message "Restrict"; return 502; } location / { try_files /fake-nonexistens-location-forr273 $root_location_p1; } location = / { try_files /fake-nonexistens-location-forr273 $root_only_location_p1; } location ~* \.php { include fastcgi_params; fastcgi_buffers 8 16k; fastcgi_buffer_size 32k; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; fastcgi_param REQUEST_SCHEME $scheme; fastcgi_param HTTPS $https if_not_empty; fastcgi_pass 127.0.0.1:9000; } location ~* \.(jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|doc|xls|exe|pdf|ppt|tar|mid|midi|wav|bmp|rtf|js|swf|flv|avi|djvu|mp3)$ { root /srv/www/domain/current/public; expires 7d; access_log off; log_not_found off; } location ~ /\.git { deny all; } location ~ /\.ht { deny all; } location ~ /\.svn { deny all; } }
      
      







高いLA vhosts.d / fpm.domain.ru.ddosモードの構成:
 include vhosts.d/map.domain.ru.inc; map "$searchbot:$valid_addr:$bad_referer:$bad_query" $root_location { default @main; "~^1:" @allow; "~^2:1" @allow; "~^0" @loc_403; "~^2:0" @loc_403; "2:2:1:0" @loc_403; "2:2:1:1" @loc_403; "2:2:0:1" @loc_403; } map "$searchbot:$valid_addr:$bad_post_referer:$bad_query" $root_only_location { default @main; "~^1:" @allow; "~^2:1" @allow; "~^0" @loc_403; "~^2:0" @loc_403; "2:2:1:0" @loc_403; "2:2:1:1" @loc_403; "2:2:0:1" @loc_403; } map "$allowed_country:$allowed_cookie" $main_location { "1:0" @allow_limit; "1:1" @allow_limit; "0:1" @allow_limit; default @restrict; } ######################################################## server { listen 80; listen 443 ssl; fastcgi_read_timeout 300s; fastcgi_send_timeout 300s; fastcgi_connect_timeout 300s; server_name domain.ru www.domain.ru m.domain.ru www.m.domain.ru; ssl_certificate ssl/www.domain.ru.crt; ssl_certificate_key ssl/www.domain.ru.key; charset UTF-8; access_log /srv/www/domain/shared/log/domain-acc.log main; error_log /srv/www/domain/shared/log/domain-err.log; root /srv/www/domain/current/public/; #  capcha   POST  action="/checkcapcha.php" error_page 500 502 /highla.html; location = /highla.html { charset UTF-8; root /srv/www/domain/current/public/; allow all; } #       . location = /checkcapcha.php { charset UTF-8; root /srv/www/domain/current/public/; include fastcgi_params; fastcgi_buffers 8 16k; fastcgi_buffer_size 32k; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; fastcgi_param REQUEST_SCHEME $scheme; fastcgi_param HTTPS $https if_not_empty; fastcgi_pass 127.0.0.1:9000; allow all; } #  location       map location @loc_403 { access_log /srv/www/domain/shared/log/loc_403-acc main; return 403; } location @allow { access_log /srv/www/domain/shared/log/allow-acc main; add_header X-debug-message "Allow"; try_files $uri /index.php?$query_string; } location @allow_limit { limit_req zone=newone burst=55; access_log /srv/www/domain/shared/log/allow-limit-acc main; add_header X-debug-message "Allow"; try_files $uri /index.php?$query_string; } location @deny { access_log /srv/www/domain/shared/log/deny-acc main; add_header X-debug-message "Deny"; return 403; } location @restrict { access_log /srv/www/domain/shared/log/resrtict-acc main; add_header X-debug-message "Restrict"; return 502; } location @main { add_header X-debug-message "Main"; try_files /fake-nonexistens-location-forr273 $main_location; } location / { try_files /fake-nonexistens-location-forr273 $root_location; } location = / { try_files /fake-nonexistens-location-forr273 $root_only_location; } location ~* \.php { include fastcgi_params; fastcgi_buffers 8 16k; fastcgi_buffer_size 32k; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; fastcgi_param REQUEST_SCHEME $scheme; fastcgi_param HTTPS $https if_not_empty; fastcgi_pass 127.0.0.1:9000; } location ~* \.(jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|doc|xls|exe|pdf|ppt|tar|mid|midi|wav|bmp|rtf|js|swf|flv|avi|djvu|mp3)$ { root /srv/www/domain/current/public; expires 7d; access_log off; log_not_found off; } location ~ /\.git { deny all; } location ~ /\.ht { deny all; } location ~ /\.svn { deny all; } }
      
      







まとめ


このソリューションにより、クライアントが偽のトラフィックからプロジェクトを保護し、サーバーの安定性を向上させるのを支援しました。

投稿者:Marat Rakhimov、トップシステム管理者



All Articles