mod_dosdetector.c(version 0.2)を見ている。
訳有って読み中。mod_dosdetector | Free software downloads at SourceForge.net
検索したら、設定のしかたがわかんないという話があった。多分、以下のdosdetector_cmdsの配列を参照すると良いかもしれない。
(追記:詳しくは、英文だけどApacheのサイトからリンクがあったApache 2 Module Tutorial - Handling a Configuration Directiveを読むといいかもしれない。)
static command_rec dosdetector_cmds[] = { AP_INIT_TAKE1("DoSDetection", set_detection_config, NULL, OR_FILEINFO, "Enable to detect DoS Attack or not"), AP_INIT_TAKE1("DoSThreshold", set_threshold_config, NULL, OR_FILEINFO, "Threshold of detecting DoS Attack"), AP_INIT_TAKE1("DoSHardThreshold", set_hard_threshold_config, NULL, OR_FILEIN FO, "Hard Threshold for DoS Attack"), AP_INIT_TAKE1("DoSPeriod", set_period_config, NULL, OR_FILEINFO, "Period of detecting DoS Attack"), AP_INIT_TAKE1("DoSBanPeriod", set_ban_period_config, NULL, OR_FILEINFO, "Period of banning client"), AP_INIT_TAKE1("DoSShmemName", set_shmem_name_config, NULL, OR_FILEINFO, "The name of shared memory to allocate for keeping track of clients"), AP_INIT_TAKE1("DoSTableSize", set_table_size_config, NULL, OR_FILEINFO, "The size of table for tracking clients"), AP_INIT_ITERATE("DoSIgnoreContentType", set_ignore_contenttype_config, NULL, OR_FILEINFO, "The names of ignoring Content Type"), {NULL}, };
ちなみに、最初にやったのは、yum install httpd-develして、apxsを入手し、makeしたオブジェクトコードからnmでシンボルをとりだし、そのうち、ローカルな関数名(タイプがt)のリストを作った。
(追記:nmを使うのは、Code Reading―オープンソースから学ぶソフトウェア開発技法の影響だ)
$ nm mod_dosdetector.o | awk '$2 == "t"' 00000210 t cleanup_shm 00000a40 t dosdetector_create_dir_config 00000630 t dosdetector_handler 000002b0 t initialize_child 00000360 t initialize_module 00000160 t register_hooks 00000c10 t set_ban_period_config 00000120 t set_detection_config 00000b50 t set_hard_threshold_config 00000020 t set_ignore_contenttype_config 00000bb0 t set_period_config 00000000 t set_shmem_name_config 000000c0 t set_table_size_config 00000af0 t set_threshold_config
で、initializeが付いていれば初期化、configが付いているのは設定内容を反映する部分だし、shmが付いているのは、共有メモリ関連のルーチンだろうから、おそらく、本体は、dosdetector_handlerだと思われる。確かにこの関数はやや長い。
コメントとか、諸々を削るとこんな感じ
dosdetector_handler(request_rec *r) { *cfg = ap_get_module_config(r->per_dir_config, &dosdetector_module); if(cfg->detection) return DECLINED; if (!ap_is_initial_req(r)) return DECLINED; content_type = ap_sub_req_lookup_uri(r->uri, r, NULL)->content_type; if (!content_type) content_type = ap_default_type(r); address = r->connection->remote_ip; **contenttype_regexp = (ap_regex_t **) cfg->contenttype_regexp->elts; for (i = 0; i < cfg->contenttype_regexp->nelts; i++) { if(!ap_regexec(contenttype_regexp[i], content_type, AP_MAX_REG_M ATCH, regmatch, 0)){ return OK; } } addr = r->connection->remote_addr->sa.sin.sin_addr; if(addr.s_addr == 0){ inet_aton(address, &addr); } if (lock) apr_global_mutex_lock(lock); client_t *client = get_client(client_list, addr, cfg->period); if (lock) apr_global_mutex_unlock(lock); last_count = client->count; count_increment(client, cfg->threshold); now = time((time_t *)0); if(client->suspected > 0 && client->suspected + cfg->ban_period > now){ apr_table_setn(r->subprocess_env, "SuspectDoS", "1"); if(client->count > cfg->ban_threshold){ if(client->hard_suspected == 0) TRACELOG("dosdetector: '%s' is suspected as Hard DoS attack! (counter: %d)", address, client->count); client->hard_suspected = now; apr_table_setn(r->subprocess_env, "SuspectHardDoS", "1"); } } else { if(client->suspected > 0){ client->suspected = 0; client->hard_suspected = 0; client->count = 0; } if(client->count > cfg->threshold){ client->suspected = now; apr_table_setn(r->subprocess_env, "SuspectDoS", "1"); } } return DECLINED; }