2010年8月22日日曜日

Ubiquity で不正な IP を調べる

以下のサイトでは、不正な IP がデータベース化されている。

DroneBL

DroneBL is a realtime monitor of abusable IPs, which has the goal of stopping abuse of infected machines.

EFnet RBL

The EFnet IRC Network RBL is comprised of a collection of data from several sources with the purpose of providing a "one stop shop" for IRC admins to block a multitude of undesirable clients.

Ubiquity でこれらのデータベースに IP アドレスを問い合わせ、何れかに登録されているかどうか調べたい。

インストールはこちらから。

使い方 : IP アドレスをブラウザ上で選択してから checkIP コマンドを実行。いづれかのデータベースに登録されている場合は true、そうでなければ false がプレビューに表示される。

 

ソースコードについて

上記二つのデータベースの問い合わせでは、単純にサイトの URL と IP を組み合わせてアクセスすると結果が HTML で返される。その中に含まれる文字列をチェックすることにより登録状態をチェック。

新たにデータベースを増やしたい場合は、問い合わせ先の URL と、問い合わせの結果が返されたら IP が存在することをチェックする述語 existp を記述して、dbSet に追加する。

CmdUtils.CreateCommand({
    names: ["checkIP"],
    preview: function preview(pblock, args){
        // プレビューをクリア
        pblock.innerHTML = "";
        
        /**
        * DB は IP を検索するサイト。
        *
        * {spec.url サイトの URL,
        * spec.existp サイトでの検索結果から、対象がサイトに存在するか判定する述語}
        *
        * @param {Object} spec
        */
        var db = function(spec){
            var that = {};
            
            // public --------------------------------------------
            
            /**
            * 与えられた IP が存在することを確認し、その結果に対して関数 f を適用する。
            * @param {Object} ip IP アドレス
            * @param {Function} f コールバック関数
            */
            var exists = function(ip, f){
                jq(ip, function(page){
                    f(spec.existp(page));
                });
            };
            that.exists = exists;
            
            /**
            * 与えられた IP に対する存否の結果ページを取得し、その結果に対して関数 f を適用する。
            * @param {Object} ip IP アドレス
            * @param {Function} f コールバック関数
            */
            var getHTML = function(ip, f){
                jq(ip, function(page){
                    f(page);
                });
            };
            that.getHTML = getHTML;
            
            // private --------------------------------------------
            
            /**
            * jQuery.get をラップした関数
            * @param {Object} ip
            * @param {Function} f
            */
            var jq = function(ip, f){
                jQuery.get(spec.url + ip, null, function(page){
                    f(page);
                });
            };
            
            return that;
        };
        
        /**
        * DB SET は検索対象の DB を集約。
        *
        * {spec.dbs db の配列}
        *
        * @param {Object} spec
        */
        var dbSet = function(spec){
            var that = {};
            
            /**
            * DB における IP アドレスの存否の結果を HTML で取得し、それに関数 f を適用する。
            * @param {Object} ip
            * @param {Function} f
            */
            var getHTML = function(ip, f){
                each(function(db){
                    db.getHTML(ip, function(page){
                        f(page);
                    });
                });
            };
            that.getHTML = getHTML;
            
            /**
            * いずれかの DB に与えられた IP が存在するか確認し、その結果に対して関数 f を適用する。
            *
            * @param {Object} ip
            * @param {Function} f
            */
            var exists = function(ip, f){
                var result = [];

                var allChecked = function(){
                    var b = false;
                    if (result.length === spec.dbs.length) {
                        for (var i = 0; i < spec.dbs.length; i++) {
                            b = b || result[i];
                        }
                        f(b);
                    }
                };
                
                each(function(db){
                    db.exists(ip, function(exists){
                        var idx = result.length;
                        exists ? result[idx] = true : result[idx] = false;
                        allChecked();
                    });
                });
            };
            that.exists = exists;
            
            // private ----------------------------------------------
            
            /**
            * 各 DB に対して関数 f を適用する
            * @param {Function} f
            */
            var each = function(f){
                for (var i = 0; i < spec.dbs.length; i++) {
                    f(spec.dbs[i]);
                }
            };
            
            return that;
        };
        
        // 各 DB の設定
        var dronebl = db({
            url: "http://dronebl.org/lookup_branded.do?ip=",
            existp: function(page){
                var msg = /This means that your IP is not listed in DroneBL/;
                return page.match(msg) ? false : true;
            }
        });
        
        var efnetrbl = db({
            url: "http://rbl.efnetrbl.org/?i=",
            existp: function(page){
                var msg = /was found in the database/;
                return page.match(msg) ? true : false;
            }
        });
        
        // ブラウザで選択された IP アドレス
        var ip = CmdUtils.getSelection("").match(/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/);
               
        // DB を集約
        dbSet({
            dbs: [dronebl, efnetrbl],
        }).exists(ip, function(b){
            pblock.innerHTML += b;
        });
    },
});

 

関連記事