PEAK XOOPS - mod_access_rbl in englishin japanese

Archive | RSS |
Site News
Site News : mod_access_rbl
Poster : GIJOE on 2007-02-09 09:33:00 (11350 reads)

in englishin japanese
最近のSPAMの量は半端じゃありません。ほとんどDDoSレベルです。
こんなのをまともに処理してたら、CPU帯域がいくらあっても足りないので、Apacheレベルで拒否できるmod_access_rblを導入してみました。

参考記事 http://www.rbl.jp/bbstbspam.html

とりあえず、このサイトに仕掛けてみました。ProtectorのログとApacheのerrorログを付き合わせることで、どれくらい有効かがわかると思います。

そのmod_access_rblのオリジナルはここです。(Apache1.3用のパッチ)
http://www.blars.org/mod_access_rbl.html
…が、なぜか記事が消えてます。

私はあえてApache1.3を利用しているのですが、ネットを探しても見つかるのはこれをベースに、Apache2.0用に書き換えたものばかりです。
仕方がないので、そのApache2バージョンを元に、再度1.3用に書き換えてみました。
移植の再移植なので、質が落ちている可能性は大です。特に私自身、Cのプログラムを書くのが本当に久しぶりで、変数の頭に$をつけたり、文字列を代入しちゃったりで、コンパイルエラーでまくりでした
もしオリジナルのdiffが見つかったらそちらを利用するべきでしょう。

#Apache用のmodって実はけっこうコード量が少ないんですね。mod_xoops.c なんかも簡単に書けるのかもしれません。


*** mod_access.c.orig	Thu Mar 14 06:05:33 2002
--- mod_access.c	Fri Feb  9 06:29:57 2007
***************
*** 61,66 ****
--- 61,67 ----
   * 
   * Module derived from code originally written by Rob McCool
   * 
+  * 'via' mods to handle RBL style dns lookup by blarson@blars.org
   */
  
  #include "httpd.h"
***************
*** 74,79 ****
--- 75,81 ----
      T_ALL,
      T_IP,
      T_HOST,
+     T_VIA,
      T_FAIL
  };
  
***************
*** 150,157 ****
      allowdeny *a;
      char *s;
  
!     if (strcasecmp(from, "from"))
! 	return "allow and deny must be followed by 'from'";
  
      a = (allowdeny *) ap_push_array(cmd->info ? d->allows : d->denys);
      a->x.from = where;
--- 152,168 ----
      allowdeny *a;
      char *s;
  
!     if (!strcasecmp(from, "via")) {
!         if (strlen(where) > 80)
! 	    return "'via' location limited to 80 characters";
! 	a = (allowdeny *) ap_push_array(cmd->info ? d->allows : d->denys);
!         a->limited = cmd->limited;
! 	a->type = T_VIA;
! 	a->x.from = where;
! 	return NULL;
!     }
!     else if (strcasecmp(from, "from"))
! 	return "allow and deny must be followed by 'from' or 'via'";
  
      a = (allowdeny *) ap_push_array(cmd->info ? d->allows : d->denys);
      a->x.from = where;
***************
*** 292,297 ****
--- 303,350 ----
  	return 0;
  }
  
+ static int check_via(request_rec *r, const char *via_list)
+ {
+     char hb[100];
+     char *ha, *s, *sb, *sc;
+     int ret = OK;
+ 
+ /* take the network address, convert to ascii, reverse the order of
+  * the numbers, tack on the rbl-style list to search, add a period
+  * at the end if there isn't one already, and see if it's listed */
+ /* perhaps caching results would be a good idea */
+ 
+     ha = r->connection->remote_ip;
+     s = ha + strlen(ha);
+     sb = hb;
+     while (--s != ha) {
+         if (*s == '.') {
+ 	    sc = s;
+ 	    while (*++sc != '.' && *sc) *sb++ = *sc;
+ 	    *sb++ = '.';
+ 	}
+     }
+     sc = s;
+     while (*sc != '.' && *sc) *sb++ = *sc++;
+     *sb++ = '.';
+     sc = (char *)via_list;
+     while (*sb++ = *sc++) ;
+     if (sb[-2] != '.') {
+ 	sb[-1] = '.';
+ 	*sb = '\0';
+     }
+     if (gethostbyname(hb) != NULL)
+ 	    ret = FORBIDDEN;
+ 	else
+ 	    ret = OK;
+ 
+     if (ret == FORBIDDEN){
+     ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r,
+ 		  "looking up %s\n", hb);
+ 	}
+     return ret;
+ }
+ 
  static int find_allowdeny(request_rec *r, array_header *a, int method)
  {
      allowdeny *ap = (allowdeny *) a->elts;
***************
*** 337,342 ****
--- 390,400 ----
  		return 1;
  	    break;
  
+ 	case T_VIA:
+ 	    if (check_via(r, ap[i].x.from))
+ 		return 1;
+ 	    break;
+ 
  	case T_FAIL:
  	    /* do nothing? */
  	    break;

0 comments

Related articles
Printer friendly page Send this story to a friend

Comments list

Login
Username or e-mail:

Password:

Remember Me

Lost Password?

Register now!