This page looks plain and unstyled because you're using a non-standard compliant browser. To see it in its best form, please visit upgrade to a browser that supports web standards. It's free and painless.

Fillano's Learning Notes 會員登入 會員註冊

« 上一篇 | 下一篇 »

最近在思考如何控管httpd伺服器,來減少spam機器人灌水的效率,結果找到了一個叫做mod_limitipconn的模組。這個模組支援apache httpd-2.0以及httpd-2.2,透過修改一下httpd的原始碼,還可以讓他偵測X-Forwarded-For檔頭中的ip資訊,以分辨透過同一個ip當作proxy過來的不同連線。

套件的網址:http://dominia.org/djao/limitipconn2.html,裡面有簡單的說明、與下載的連結等,也有預先編譯好的win32模組。

透過他內建的diff檔案來patch過httpd以後重新編譯,很順利。接著只要依照mod_limitipconn中的說明,編譯安裝,修改httpd.conf設定,就可以使用。

根據說明,mod_limitipconn支援幾個設定:

  1. MaxConnPerIP這是每個ip最大可同時連接的數量
  2. NoIPLimit指定要排除限制的內容種類(mime type)
  3. OnlyIPLimit指定只要限制的內容種類(mime type)

要注意的是,他只能以per location的方式做設定,所以至少要有:

<Location />
     MaxConnPerIP 1
</Location>

類似的設定才會發生作用。

寫了一個小程式測試一下:

<html>
<body>
<script>
var errlink=0;
var successlink=0;
var starttime = 0;
function test() {
	try {
		errlink=0;
		successlink=0;
		var count = document.getElementById('testn').value;
		starttime = (new Date()).getTime();
		for (var i=0; i<count; i++) {
			(new ajax('test.php')).run();
		}
	}catch(e){alert(e);}
}
function xmlhttp() {
	try{return new XMLHttpRequest();} catch(e){}
	try{return new ActiveXObject("Msxml2.XMLHTTP");} catch(e){}
	try{return new ActiveXObject("Microsoft.XMLHTTP");} catch(e){}
	alert("XMLHttpRequest Object not existed!!");
	return null;
}
function ajax (url) {
	this.url = url;
	this.xmlhttp = xmlhttp();
	var ajaxinst = this;
	this.xmlhttp.onreadystatechange = function () {
		try {
			if (ajaxinst.xmlhttp.readyState == 4) {
				if (ajaxinst.xmlhttp.status == 200) {
					successlink += 1;
				} else {
					errlink += 1;
				}
			}
			var obj = document.getElementById("panel");
			obj.innerHTML = "successlink: " + successlink + "
errlink: " + errlink + "
time: " + ((new Date()).getTime() - starttime)/1000; }catch(e){alert(e);} }; this.run = function () { this.xmlhttp.open("POST",this.url,true); this.xmlhttp.send(""); } } </script> <input type="text" id="testn" name="testn"><input type="button" value="linking" onclick="test();"> <div id="panel"></div> </body> </html>

果然,在沒啟用mod_limitipconn模組前,都可以順利連線,但是開啟限制後,就會有錯誤出現。(ie7為了提昇速度,如果用GET方法,預設會直接取cache的資料,所以測不出結果。後來改成POST就可以看到效果了。Firefox沒有這個問題。另外,ie7也支援了原生的XMLHttpRequest,不再依賴msxml了。)

考慮到一般的spam comment,應該會用post的方式把資料送到伺服器(伺服器的php應該也會這樣設計),所以接著想在mod_limitipconn加上只攔阻POST而不攔阻GET的功能試試看。

在mod_limitipconn.c的程式原始碼裡面,有用到很多request_rec這個資料結構,找了一下httpd的原始碼,在include/httpd.h裡面找到了定義。在這個資料結構裡面,有一個叫做method_number的成員(型別為int)。嗯嗯,就拿來用用看。

接著在mod_limitipconn.c裡面找到

static int limitipconn_handler(request_rec *r)
這個函數,在裡面找到
    if (cfg->limit == 0) {
	return OK;
    }
在這下面加幾行判斷:
    if (r->method_number == M_GET) {
        return OK;
    }
(其實對於這些原始碼還不熟悉啦,但是這些資訊剛好夠用。嘿嘿)

重新編譯模組後,再用剛剛的程式測試一下。果然可以:)。用GET方法就不會發生錯誤。如果用POST方法,他依舊會限制連線數。不過說限制,也只是減緩他的速度,並不是把他的spam comment真的擋掉:(

mod_limitipconn這個模組有一個問題,就是只能偵測位於proxy(而且必須帶有X-Forwarded-For檔頭)之後的機器,在NAT之後的機器沒辦法,都會被當成同一個ip擋下來。也許透過mod_usertrack模組,利用cookie的方式可以做限制?有機會再來試試。

  1. Re: 用mod_limitipconn模組控管http連線 [回覆]

    用金银工艺礼品铜、铁、锡等金属材料,或以网易企业邮箱金属材料为主辅以其他滤布材料,加工搜索引擎优化制作而成的seo工艺品。具有挂历厚重、雄浑、电脑包华贵、高档礼品典雅、精细的风格。

    fefe 回應於 08 元月, 2010 13:22

發表回應

 暱稱 (必填)

 標題

 個人網頁

 電子郵件

authimage 
 認證碼 (必填)