apache2.4.6にmod_evasiveをインストール

DoS対策をせよとのお達し。むかしdosdetectorを入れて失敗してから絶えてチャレンジしてなかったなぁ。
で、apache dosとかって検索するとmod_evasiveってのがいいらしい。早速インストールしてみる。

ダウンロード

物はここにあります。

インストール

READMEによると展開してapxsでライブラリを作成するようです。
まずダウンロードしたファイルを展開する。

# tar -zxvf mod_evasive_1.10.1.tar.gz

展開したディレクトリへ移動してapxsでライブラリを作成。

# cd mod_evasive
# /usr/local/apache2/bin/apxs -i -a -c mod_evasive20.c
usr/local/apache2/build/libtool --silent --mode=compile gcc -std=gnu99 -prefer-pic   -DLINUX=2 -D_REENTRANT -D_GNU_SOURCE -g -O2 -pthread -I/usr/local/apache2/include  -I/usr/local/apache2/include   -I/usr/local/apache2/include   -c -o mod_evasive20.lo mod_evasive20.c && touch mod_evasive20.slo
mod_evasive20.c: In function ‘access_checker’:
mod_evasive20.c:142: error: ‘conn_rec’ has no member named ‘remote_ip’
mod_evasive20.c:146: error: ‘conn_rec’ has no member named ‘remote_ip’
mod_evasive20.c:158: error: ‘conn_rec’ has no member named ‘remote_ip’
mod_evasive20.c:165: error: ‘conn_rec’ has no member named ‘remote_ip’
mod_evasive20.c:180: error: ‘conn_rec’ has no member named ‘remote_ip’
mod_evasive20.c:187: error: ‘conn_rec’ has no member named ‘remote_ip’
mod_evasive20.c:208: error: ‘conn_rec’ has no member named ‘remote_ip’
mod_evasive20.c:212: 警告: implicit declaration of function ‘getpid’
mod_evasive20.c:215: error: ‘conn_rec’ has no member named ‘remote_ip’
mod_evasive20.c:221: error: ‘conn_rec’ has no member named ‘remote_ip’
mod_evasive20.c:222: error: ‘conn_rec’ has no member named ‘remote_ip’
mod_evasive20.c:228: error: ‘conn_rec’ has no member named ‘remote_ip’
apxs:Error: Command failed with rc=65536

なにやら一杯エラーがでました。
なになに、conn_rec構造体にはremote_ipなんてメンバがいないとな。

デバッグ

先ほどのmod_evasiveのページにはApache2.2かApache1.3に対応ということだった。conn_rec構造体のメンバ名がApache2.2からApache2.4で変更されたっぽいですね。
Apache2.2.25(2.2の最新)をダウンロード展開して、Apache2.4.6と比較してみます。
対象となる構造体conn_recは include/httpd.h に定義があります。
まず、Apache2.4.6だとこう。

struct conn_rec {
    /** Pool associated with this connection */
    apr_pool_t *pool;
    /** Physical vhost this conn came in on */
    server_rec *base_server;
    /** used by http_vhost.c */
    void *vhost_lookup_data;

    /* Information about the connection itself */
    /** local address */
    apr_sockaddr_t *local_addr;
    /** remote address; this is the end-point of the next hop, for the address
     *  of the request creator, see useragent_addr in request_rec
     */
    apr_sockaddr_t *client_addr;

    /** Client's IP address; this is the end-point of the next hop, for the
     *  IP of the request creator, see useragent_ip in request_rec
     */
    char *client_ip;
    /** Client's DNS name, if known.  NULL if DNS hasn't been checked,
     *  "" if it has and no address was found.  N.B. Only access this though
     * get_remote_host() */
    char *remote_host;
    /** Only ever set if doing rfc1413 lookups.  N.B. Only access this through
     *  get_remote_logname() */
    char *remote_logname;

(以下略)

そしてApache2.2.25だとこうです。

struct conn_rec {
    /** Pool associated with this connection */
    apr_pool_t *pool;
    /** Physical vhost this conn came in on */
    server_rec *base_server;
    /** used by http_vhost.c */
    void *vhost_lookup_data;

    /* Information about the connection itself */
    /** local address */
    apr_sockaddr_t *local_addr;
    /** remote address */
    apr_sockaddr_t *remote_addr;

    /** Client's IP address */
    char *remote_ip;
    /** Client's DNS name, if known.  NULL if DNS hasn't been checked,
     *  "" if it has and no address was found.  N.B. Only access this though
     * get_remote_host() */
(以下略)

わかりやすいようにコメントも引用しています。どうやら Apache2.2で remote_ip だった構造体メンバ名は Apache2.4では client_ip に変更されたようです。

ということで

ということでmod_evasive20.cを改修。

%s/remote_ip/client_ip/g

はい、これで無事コンパイルできました。