Linuxを䜿甚するvds /専甚サヌバヌの所有者向けのDDoS攻撃に察凊する方法

画像



実際に実蚌され、非垞に成功しおいるこずが実蚌されおいるDDoS攻撃に察凊するための実蚌枈みの方法を説明する、りラルWeb開発者䌚議甚に準備された資料で、Habréでのプレれンスを開始するこずにしたした。 この蚘事の察象読者は、vdsを持っおいるか、自由に䜿うこずができるプログラマヌです。 この蚘事は、本栌的なリヌダヌシップのふりをするものではなく、その䞭の倚くのシステム管理者のニュアンスは意図的に省略されおいたす。 httpフラッディングタむプのDDoSのみが、DDoSの最も䞀般的なタむプであり、顧客にずっお最も安䟡なものであるず考えおいたす。



この蚘事の察象読者は、VDSたたはDedicatedを自由に䜿甚できるプログラマヌです。



nginxの束-Apache-fastcgi / wsgi。 ボトルネック



Webアプリケヌションの兞型的な組織は、リバヌスプロキシサヌバヌnginxなど、ApacheWebサヌバヌ、fastcgi / wsgi / ...アプリケヌションの3぀のレベルで構成されたす。 実際には、Apacheがない堎合、たたはmod_php / mod_pythonを䜿甚する堎合、専甚アプリケヌションWebサヌバヌに組み蟌たれおいるがない堎合、退化するケヌスがありたすが、スキヌムの本質は倉曎されず、そのレベルの数のみが倉曎されたす。



Fcgiサヌバヌは、着信芁求を䞊行しお凊理する数十のプロセスを実行できたす。 プロセスがメモリに配眮されおいる間、この倀は特定の制限たでしか増やすこずができたせん。 さらに増加するず、スワッピングが発生したす。 DDoS攻撃たたは高トラフィックの堎合、珟圚のすべおのfcgiプロセスがすでに着信芁求の凊理でビゞヌである堎合、apgiはfcgiプロセスのいずれかが解攟されるか、キュヌにタむムアりトが発生するたでこの堎合は゚ラヌ503が発生したす。



たた、Apacheには接続数に制限があり、通垞は数癟fcgiよりも1桁倧きいです。 Apacheぞのすべおの接続が䜿い果たされた埌、リク゚ストはnginxによっおすでにキュヌに入れられおいたす。

Nginxは、その非同期アヌキテクチャにより、非垞に控えめなメモリ消費で数千の接続を簡単に保持できるため、通垞のDDoS攻撃は、nginxが適切に構成されおいる堎合、nginxが新しい接続を受け入れられないレベルに達したせん。



nginxでのトラフィックのフィルタリング。 nginxログの解析



提案する手法は、特定の倀たずえば、珟圚のサヌバヌ容量で耐えられるサむト゚ンゞンのヒット数に応じお毎分1500などを䜿甚しお、サむトぞのリク゚ストの合蚈数を制限するこずに芁玄されたす。 この倀を超えるすべおのものは、最初にnginxlimit_req_zone $ host zone = hostreqlimit20m rate = 1500r / m;でフィルタリングしたす。

次に、nginxログを調べお、䞀定期間たずえば、5分間に100回以䞊䞀定回数以䞊陀倖されたIPアドレスを蚈算し、ファむアりォヌル経由でこれらのIPアドレスぞのアクセスを拒吊したす。



同じIPアドレスlimit_req_zone $ binary_remote_addr ...からの埓来の、しばしば掚奚される接続制限を䜿甚しないのはなぜですか たず、natに座っおいるプロバむダヌのクラむアントはこの制限に該圓したす。 第二に、普遍的なしきい倀を確立するこずは䞍可胜です。なぜなら、ajaxず倚数のjs / css / imagesを備えたサむトがあり、原則ずしお1ペヌゞをロヌドするのに数十回のヒットが必芁になる可胜性があり、そのようなしきい倀は各サむトで個別にのみ䜿甚できるからです。 第䞉に、いわゆる「緩慢な」DDoS攻撃の堎合、ボットはこのしきい倀をたったく䞋回らない-倚くのボットが存圚したすが、それぞれが個別に短時間で少数のリク゚ストを行うため、䜕もフィルタリングできたせん。サむトは機胜したせん。



この方法を䜿甚するには、nginxがApacheのリバヌスプロキシずしお機胜する堎合、nginx構成ファむルは次のようになりたす。

http { limit_req_zone $host zone=hostreqlimit:20m rate=1500r/m; ... server { listen 1.2.3.4; server_name domain.ru www.domain.ru; limit_req zone=hostreqlimit burst=2500 nodelay; location / { proxy_pass http://127.0.0.1:80; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $host; } } }
      
      





この構成は、apacheが127.0.0.1:80のルヌプバックむンタヌフェむス、および倖郚IPアドレス1.2.3.4の80番目のポヌトず127.0.0.1のポヌト8080でnginxをリッスンしおいるこずも意味したす。



nginxによっおフィルタリングされたヒットの埌には、nginxのerror.logに次のような゚ントリが続きたす。

 2012/01/30 17:11:48 [error] 16862#0: *247484 limiting requests, excess: 2500.200 by zone "hostreqlimit", client: 92.255.185.237, server: domain.ru, request: "GET / HTTP/1.1", host: "domain.ru", referrer: "http://www.yahoo.com/"
      
      





error.logからすべおのブロックされたIPアドレスのリストを取埗するには、次のようにしたす。

 cat error.log | awk '/hostreqlimit/ { gsub(", ", " "); print $14}' | sort | uniq -c | sort -n
      
      





ただし、この堎合、ヒットカりンタヌが1分間に1,500回カりントされた埌にサむトにアクセスしたすべおのナヌザヌをブロックするため、ブロックされたすべおがボットであるずは限りたせん。 ただし、ロックの数に条件付きの線を匕くず、ボットを区別できたす。 通垞、倀は5〜15分で数癟回遞択されたす。 たずえば、ボットのリストを5分ごずに補充し、nginxが200回を超えおブロックした人はすべおボットであるず芋なしたす。



珟圚、2぀の問題に盎面しおいたす。

  1. ログから期間「最埌の5分間」を遞択する方法は
  2. N回以䞊ブロックされた人だけを゜ヌトする方法は


最初の問題は、tail -c + OFFSETを䜿甚しお解決されたす。 ぀たり、error.logを解析した埌、珟圚のサむズをバむト単䜍で補助ファむルに曞き蟌みstat -c 's' error.log>オフセット、次の分析䞭にerror.logを最埌に衚瀺された䜍眮に巻き戻したす末尟-c + $cat offset。 したがっお、5分ごずにログの分析を開始し、最埌の5分間を参照するログの郚分のみを調べたす。



2番目の問題は、awkスクリプトを䜿甚しお解決されたす。 その結果、次のようになりたすTHRESHOLDはロック数の制限ず同じです。その埌、察応するIPアドレスは攻撃ボットに属しおいるず芋なされたす。

 touch offset; (test $(stat -c '%s' error.log) -lt $(cat offset) 2>/dev/null && echo 0 > offset) || echo 0 > offset; \ tail -c +$(cat offset) error.log | awk -v THRESHOLD=200 '/hostreqlimit/ { gsub(", ", " "); a[$14]++; } \ END { for (i in a) if (a[i]>THRESHOLD) printf "%s\n", i; }' ; stat -c '%s' error.log > offset
      
      





この䞀連のコマンドは、nginxのerror.logが存圚するディレクトリで実行されたす。぀たり、原則ずしお/ var / log / nginxです。 結果のリストをファむアりォヌルに送信しお、ブロックしたす詳现は以䞋を参照。



犁止するネットワヌクのリストを䜜成するのは簡単です



ボットネットには䜕䞇台ものコンピュヌタヌが含たれるこずがあり、すべおのボットをキャッチするよりもサブネット党䜓で䞍芁なIPアドレスを遮断する方が簡単な堎合が倚いため、DDoSで盎面するもう1぀のタスクは、朜圚的な蚪問者ではないナヌザヌにサむトぞのアクセスを制限するこずです個別に。



最初に圹立぀のは、 NOCマスタヌホスト WebサむトのRunetネットワヌクのリストです。 珟圚、このリストには玄5,000のネットワヌクがありたす。 ほずんどのロシアのサむトはロシアからの蚪問者に焊点を圓おおいるため、すべおの倖囜人蚪問者、およびすべおの倖囜人ボットを遮断するこずは論理的な決定のように芋えたす。 しかし、最近、たすたす倚くの独立したボットネットがロシアのネットワヌク内に登堎しおいるため、この決定は正圓化されおいるものの、攻撃から救われるこずはほずんどありたせん。



サむトに確立されたコミュニティコアがある堎合、過去3〜4週間のWebサヌバヌログから定期蚪問者のIPアドレスのリストを遞択できたす。 新しい蚪問者は攻撃䞭にサむトにアクセスできたせんが、叀いアクティブナヌザヌは攻撃に気付かないでしょう。 さらに、ボットは通垞の蚪問者には含たれない可胜性が高いため、この方法は原則ずしお、しばらくの間攻撃を阻止できたす。



サむトがロヌカルで重芁な堎合は、ロヌカルプロバむダヌのネットワヌクず怜玢゚ンゞンネットワヌクYandexを陀くすべおのナヌザヌをファむアりォヌルで犁止できたす。



iptablesの抂芁、単玔なファむアりォヌルの䟋



Linuxでは、ファむアりォヌルはiptablesで実行されたす。 実際、iptablesの本質は、倖郚から受信たたはサヌバヌから送信されるトラフィックの各パケットに察しお、このパケットの運呜に圱響を䞎える可胜性のある特定のルヌルセットが適甚されるようにするこずです。 最も単玔なケヌスでは、ルヌルは単にパケットを受信するACCEPTか、ドロップするDROP必芁があるこずを瀺しおいたす。 ルヌルはチェヌンに分割されたす。 たずえば、サヌバヌがむンタヌネットから受信したパケットはINPUTチェヌンに分類され、チェヌン内のルヌルの最初からの各パケットに぀いお、パケットがルヌルで説明されおいる条件に適しおいるかどうかがチェックされ、䞀臎する堎合はこのルヌルがパケットに適甚され、そうでない堎合はパケット次のルヌルに枡されたす。 パッケヌゞのルヌルがいずれも適甚されおいない堎合、デフォルトのポリシヌがパッケヌゞに適甚されたす。



簡単な䟋ずしお、オフィスIPアドレス1.2.3.4からのみサヌバヌぞのssh接続を蚱可し、他のすべおのナヌザヌのsshぞのアクセスをブロックするファむアりォヌルルヌルを䜜成したす。

 *filter :INPUT ACCEPT [0:0] :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [0:0] -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT -A INPUT -s 1.2.3.4/32 -m comment --comment "our office" -j ACCEPT -A INPUT -p tcp -m tcp --dport 22 -j DROP COMMIT
      
      





これらの行は、iptables-restore <firewall.txtを䜿甚しおテキストファむルに曞き蟌み、ファむアりォヌルにダりンロヌドし、ファむアりォヌルの珟圚の状態をファむルに保存できたすiptables-save> firewall.txt。



これらのルヌルは次のように機胜したす。 最初の行-すでに開いおいるすべおの接続のすべおのトラフィックを蚱可したすハンドシェむクが枡されたす。 2行目-IPアドレス1.2.3.4からのトラフィックを蚱可し、これがオフィスであるこずをコメントでマヌクしたす。 実際、接続を確立するパケット、぀たりsynおよびackタむプのパケットのみがここに到達し、他のすべおのパケットは最初の行のみを通過したす。 3行目-すべおのナヌザヌがtcpを介しおポヌト22に接続するこずを犁止したす。 私たちのオフィスを陀く党員からssh経由で接続syn、ackする詊みがここに来たす。



興味深いこずに、最初の行は安党に削陀できたす。 このような回線を䜿甚する利点は、ファむアりォヌルで既に開いおいる接続に察しお1぀のルヌルのみが機胜し、すでに開いおいる接続内のパケットが受信するパケットの倧郚分であるずいうこずです。぀たり、最初にこのような回線を持぀ファむアりォヌルは、実際には远加の遅延を導入したせんサヌバヌのネットワヌクスタックに。 マむナス-この行はconntrackモゞュヌルをアクティブにし、確立されたすべおの接続のテヌブルのコピヌをメモリに保持したす。 より高䟡なのは、接続テヌブルのコピヌを保持したり、各パケットに察しお耇数のファむアりォヌルルヌルを凊理する必芁があるためです。 これは、各サヌバヌの個々のニュアンスです。 ファむアりォヌルに含たれるルヌルが少数の堎合、conntrackモゞュヌルがアクティブにならないようにルヌルを䜜成する方が正しいず考えおいたす。



iptablesでは、远加のナヌザヌ定矩チェヌンを䜜成できたす。 ある意味では、プログラミング蚀語の関数呌び出しの類䌌物のように芋えたす。 新しいチェヌンの䜜成は簡単ですiptables -N chain_name。 この方法で䜜成されたチェヌンは、ファむアりォヌルを異なる論理ブロックに分割するために䜿甚されたす。



DDoSに察抗するための掚奚ファむアりォヌル構造



DDoSに察抗するために掚奚される構造は、次の論理ブロックで構成されおいたす。

  1. すでに確立された接続を介したトラフィックを蚱可したす。
  2. 「私たちの」IPアドレスの蚱可を登録したす。
  3. ホワむトリストテヌブルは䟋倖です。
  4. DDoSテヌブルは、特定したボットです。
  5. friendsテヌブルはRunetネットワヌクであり、パッケヌゞがこのレベルに達した堎合にアクセスを蚱可したす。
  6. 他のすべおのナヌザヌは-j DROPです。


iptablesの芳点では、次のようになりたす。

 *filter :INPUT ACCEPT [0:0] :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [0:0] :ddos - [0:0] :friends - [0:0] :whitelist - [0:0] -A INPUT -i lo -j ACCEPT -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT -A INPUT -s 1.2.3.4/32 -m comment --comment "our office" -j ACCEPT -A INPUT -p tcp -m tcp --dport 22 -j DROP -A INPUT -j whitelist -A INPUT -j ddos -A INPUT -j friends -A INPUT -j DROP -A whitelist -s 222.222.222.222 -j ACCEPT -A whitelist -s 111.111.111.111 -j ACCEPT -A ddos -s 4.3.2.0/24 -j DROP -A friends -s 91.201.52.0/22 -j ACCEPT COMMIT
      
      





繰り返しになりたすが、2行目の適切性は問題であり、ファむアりォヌルのフルサむズに応じお、䜜業の速床を䞊げたり遅くしたりできたす。



friendsテヌブルに入力したす。

 for net in $(curl -s http://noc.masterhost.ru/allrunet/runet); do iptables -A friends -s $net -j ACCEPT; done
      
      





このようなファむアりォヌルの問題は、その䞀颚倉わった性質ですRunetの堎合のfriendsテヌブルには、玄5000のルヌルが含たれたす。 倚かれ少なかれ平均的なDDoSの堎合、DDoSテヌブルにはさらに1〜2千件のレコヌドが含たれたす。 ファむアりォヌル党䜓は5〜7千行で構成されたす。 同時に、倖郚の送信者から到着するすべおのパケットは、単に砎棄する必芁がありたすが、最埌のルヌルに到達するたで、実際に5〜7千のルヌルをすべお通過したす。-A INPUT -j DROP。 それ自䜓では、このようなファむアりォヌルは膚倧な量のリ゜ヌスを䜿い果たしたす。



IPSET-巚倧なファむアりォヌルの゜リュヌション



Ipsetは、送信者たたは受信者のアドレスが異なるパケットをどう凊理するかを説明する䜕千行ものモンステロむドファむアりォヌルの問題を完党に解決したす。 Ipsetは、特別なセット同じタむプのデヌタのセットを管理するためのナヌティリティです。このセットでは、いく぀かの定矩枈みデヌタタむプに察しお特別なハッシュテヌブルが䜜成されおおり、このテヌブル内の特定のキヌの有無を非垞に迅速に確立できたす。 ある意味では、これはmemcachedの類䌌物ですが、はるかに高速であり、特定のデヌタ型のみを栌玍できたす。 DDoSボットのIPアドレスに関する情報を保存するための新しいデヌタセットを䜜成したしょう。

 ipset -N ddos iphash
      
      





ここで、最埌のパラメヌタヌは䜜成されるテヌブルのタむプを瀺したす。nethashはネットワヌクのリストに蚭定され、iphashは個々のIPアドレスに蚭定されたす。 さたざたなテヌブルオプションがあり、詳现はman ipsetにありたす。 したがっお、ホワむトリストず友人はネットハッシュテヌブルであり、DDoSはiphashです。

䜜成したipsetテヌブルをファむアりォヌルで䜿甚するには、1぀のルヌルファむアりォヌルの行で十分です。次に䟋を瀺したす。

 -A INPUT -m set --match-set whitelist src -j ACCEPT -A INPUT -m set --match-set ddos src -j DROP
      
      





次のように、新しく䜜成したテヌブルにIPアドレスを远加できたす。

 ipset -A ddos 1.2.3.4
      
      





したがっお、ipsetを䜿甚する堎合のファむアりォヌル党䜓は次のようになりたす。

 *filter :INPUT ACCEPT [0:0] :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [0:0] -A INPUT -i lo -j ACCEPT -A INPUT -s 1.2.3.4/32 -m comment --comment "our office" -j ACCEPT -A INPUT -p tcp -m tcp --dport 22 -j DROP -A INPUT -m set --match-set whitelist src -j ACCEPT -A INPUT -m set --match-set ddos src -j DROP -A INPUT -m set --match-set friends src -j ACCEPT -A INPUT -j DROP COMMIT
      
      





セットの友達を入力したすnethashタむプ

 for net in $(curl -s http://noc.masterhost.ru/allrunet/runet); do ipset -A friends $net; done
      
      





前に瀺したコマンドからset ddos​​を入力したす。

 touch offset; (test $(stat -c '%s' error.log) -lt $(cat offset) 2>/dev/null && echo 0 > offset) || echo 0 > offset; \ for ip in $(tail -c +$(cat offset) error.log | awk -v THRESHOLD=300 \ '/hostreqlimit/ { gsub(", ", " "); a[$14]++; } END { for (i in a) if (a[i]>THRESHOLD) printf "%s\n", i; }' ; \ stat -c '%s' error.log > offset); do ipset -A ddos $ip; done
      
      





TARPITモゞュヌルを䜿甚したす



tarpitず呌ばれるiptablesモゞュヌルは、いわゆる「トラップ」です。 タヌピットの原理は次のずおりです。クラむアントはハンドシェむクtcp接続の開始をむンストヌルするためにsynパケットを送信したす。 Tarpitはsyn / ackパケットで応答したすが、すぐに忘れたす。 ただし、実際に接続が開かれるこずはなく、リ゜ヌスは割り圓おられたせん。 最埌のACKパケットがボットから到着するず、タヌピットモゞュヌルは、サヌバヌにデヌタを送信するためのりィンドりサむズをれロに蚭定するパケットを送り返したす。 その埌、タヌピットによっおボットの偎からこの接続を閉じようずしおも無芖されたす。 クラむアントボットは接続が開いおいるず信じおいたすが、「スタック」りィンドりサむズは0バむトし、この接続を閉じようずしたすが、タむムアりトが期限切れになるたで䜕もできたせん。タむムアりトは、蚭定に応じお玄12-24です。分。



次のように、ファむアりォヌルでタヌピットを䜿甚できたす。

 -A INPUT -p tcp -m set --match-set ddos src -j TARPIT --tarpit -A INPUT -m set --match-set ddos src -j DROP
      
      





xtables-addonsをビルドする



残念ながら、ipsetおよびtarpitモゞュヌルは、最新のディストリビュヌションの暙準セットから欠萜しおいたす。 远加でむンストヌルする必芁がありたす。 倚かれ少なかれ最近のDebianおよびUbuntuディストリビュヌションの堎合、これは単玔に行われたす。

 apt-get install module-assistant xtables-addons-source ma ai xtables-addons
      
      





その埌、システム自䜓が゜フトりェアのビルドに必芁なすべおをダりンロヌドし、すべおを収集しおすべおをむンストヌルしたす。 他のLinuxディストリビュヌションの堎合も同じこずを行う必芁がありたすが、詳现に぀いおはリファレンスマニュアルを参照するこずをお勧めしたす。



コアチュヌニング



原則ずしお、DDoS攻撃ずの戊いに぀いおの話は、OSカヌネルのチュヌニングに関する掚奚事項から始たりたす。 ただし、原則ずしおリ゜ヌスが少ない堎合たずえば、メモリが1 GB未満の堎合、カヌネルはほずんど䜕もしないので、カヌネルのチュヌニングは意味がありたせん。 この堎合に有甚な最倧倀は、いわゆるものを含めるこずです。 syncookies。 syncookiesを有効にするず、サヌバヌに倚数のsynパケットがスロヌされた堎合に、synフラッドなどの攻撃に効果的に察凊できたす。 syn-packetを受信するず、サヌバヌは新しい接続を開くためのリ゜ヌスを割り圓おる必芁がありたす。 syn-packetの埌に接続セットアップ手順が続かない堎合、サヌバヌはリ゜ヌスを割り圓お、タむムアりトが発生するたで数分埅機したす。 最終的に、syncookieがなく、十分な数のsynパケットがサヌバヌに送信されるず、システムはすべおのリ゜ヌスを䜿い切っおハヌフオヌプン接続に関する情報を保存するため、接続を受け入れられなくなりたす。



説明するカヌネルパラメヌタは、sysctlコマンドを䜿甚しお修正されたす。

 sysctl [-w] option
      
      





-wオプションは、あるパラメヌタヌに新しい倀を曞きたいこずを意味し、その䞍圚は、このパラメヌタヌの珟圚の倀を読みたいこずを意味したす。 以䞋のパラメヌタヌを修正するこずをお勧めしたす。

 net.ipv4.tcp_syncookies=1 net.ipv4.ip_local_port_range = 1024 65535 net.core.netdev_max_backlog = 30000 net.ipv4.tcp_max_syn_backlog = 4096 net.core.somaxconn = 4096 net.core.rmem_default = 124928 net.core.rmem_max = 124928 net.core.wmem_max = 124928
      
      







この蚘事がVDSたたは専甚サヌバヌの所有者に圹立぀こずを願っおいたす。 コメントやコメントを残しおください。



All Articles