nodejs HTTPプロキシリバースプロキシサーバ、ファイアウォール、Webフィルタリング、共通の浸透を開発

不慮

最近のWebシステムは、多くの場合、抜け穴の様々なを試し、スキャン、ハッカーの攻撃につながりました。
解析攻撃をログに記録し、いくつかの一般的な攻撃があります。

  • ウェブシェルをアップロード
  • リモートコマンド実行の脆弱性
  • SQLインジェクション
  • XXS攻撃
  • 暫定さまざまなオープンソースフレームワークは、抜け穴をアウトバースト

攻撃情報の特性の解析

それは、ウェブ技術の浸透の使用を意味します。httpリクエストを使用し、ハッカーは、一般的なHTTPヘッダに不正なコマンドを移植する方法、体、および他のいくつかの、不正な文字をされて見つける:EXE、CMD、PowerShellの、ダウンロードを選択し、労働組合、削除しますように。

問題解決のためのアイデア

  • 不正な文字があれば我々は、それが遮断され、サービス拒否を内部情報HTTPリクエストヘッダ、体を分析するためのプロキシサーバーを開発することはできません。
  • ホワイトリストは、要求を許可するように設定され、不正なURLを拒否します。

ネットワークトポロジの不正な要求をインターセプトするためにHTTPプロキシ、サービス拒否。

技術選択

一般的なプロキシサーバはnginxの、Apacheを持って、私は2つのプロキシサーバーは柔軟な設定、フィルタリング、転送することができないことを知らない、理解していません。
だから、nodejs HTTPプロキシを選択してください。

nodejs利点

  • 軽量
  • 迅速な展開
  • 柔軟な開発
  • 高スループット、非同期IO

図ロジックコーディング

絶対に乾燥品、コードシェア

コードは異なり

  • 1.17.0プロキシHTTP
    https://github.com/nodejitsu/node-http-proxyコードアドレス
  • "色": "〜0.6.2"、
var util = require('util'),
    colors = require('colors'),
    http = require('http'),
    httpProxy = require('./node_modules/http-proxy');
    fs = require("fs");

var welcome = [
    '#    # ##### ##### #####        #####  #####   ####  #    # #   #',
    '#    #   #     #   #    #       #    # #    # #    #  #  #   # # ',
    '######   #     #   #    # ##### #    # #    # #    #   ##     #  ',
    '#    #   #     #   #####        #####  #####  #    #   ##     #  ',
    '#    #   #     #   #            #      #   #  #    #  #  #    #  ',
    '#    #   #     #   #            #      #    #  ####  #    #   #   '
].join('\n');

Date.prototype.Format = function(fmt) { //author: meizz
    var o = {
        "M+": this.getMonth() + 1, //月份
        "d+": this.getDate(), //日
        "h+": this.getHours(), //小时
        "m+": this.getMinutes(), //分
        "s+": this.getSeconds(), //秒
        "S": this.getMilliseconds() //毫秒
    };
    if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
    for (var k in o)
        if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
    return fmt;
}


// 非法字符
var re = /php|exe|cmd|shell|select|union|delete|update|insert/;
/** 这里配置转发
 */
var proxyPassConfig = {
    "/hello": "http://www.qingmiaokeji.cn ",
    "/": "http://127.0.0.1/"
}

var logRootPath ="g:/httpproxy/";

console.log(welcome.rainbow.bold);

function getCurrentDayFile(){
    // console.log(logRootPath+"access_"+(new Date()).Format("yyyy-MM-dd")+".log");
    return logRootPath+"access_"+(new Date()).Format("yyyy-MM-dd")+".log";
}




//
// Basic Http Proxy Server
//
var proxy = httpProxy.createProxyServer({});
var server = http.createServer(function (req, res) {
    appendLog(req)

    var postData = "";
    req.addListener('end', function(){
        //数据接收完毕
        console.log(postData);
        if(!isValid(postData)){//post请求非法参数
            invalidHandler(res)
        }
    });
    req.addListener('data', function(postDataStream){
        postData += postDataStream
    });



    var result = isValid(req.url)
    //验证http头部是否非法
    for(key in req.headers){
        result = result&& isValid(req.headers[key])
    }

    if (result) {

        var patternUrl = urlHandler(req.url);
        console.log("patternUrl:" + patternUrl);
        if (patternUrl) {
            proxy.web(req, res, {target: patternUrl});
        } else {
            noPattern(res);
        }

    } else {
        invalidHandler(res)
    }


});

proxy.on('error', function (err, req, res) {
    res.writeHead(500, {
        'Content-Type': 'text/plain'
    });

    res.end('Something went wrong.');
});

/**
 * 验证非法参数
 * @param value
 * @returns {boolean} 非法返回False
 */
function isValid(value) {
    return re.test(value) ? false : true;
}

/**
 * 请求转发
 * @param url
 * @returns {*}
 */
function urlHandler(url) {
    var tempUrl = url.substring(url.lastIndexOf("/"));
    return proxyPassConfig[tempUrl];
}

function invalidHandler(res) {
    res.writeHead(400, {'Content-Type': 'text/plain'});
    res.write('Bad Request ');
    res.end();
}


function noPattern(res) {
    res.writeHead(404, {'Content-Type': 'text/plain'});
    res.write('not found');
    res.end();
}


function getClientIp(req){
    return req.headers['x-forwarded-for'] ||
            req.connection.remoteAddress ||
            req.socket.remoteAddress ||
            req.connection.socket.remoteAddress;
}


function appendLog(req) {
    console.log("request url:" + req.url);
    var logData = (new Date()).Format("yyyy-MM-dd hh:mm:ss")+" "+getClientIp(req)+" "+req.method+ " "+req.url+"\n";
    fs.exists(logRootPath,function(exists){
        if(!exists){
            fs.mkdirSync(logRootPath)
        }
        fs.appendFile(getCurrentDayFile(),logData,'utf8',function(err){
            if(err)
            {
                console.log(err);
            }
        });
    })
}

console.log("listening on port 80".green.bold)
server.listen(80);

アイデアの拡張

  • 不正な文字を傍受した後、管理者に通知する電子メールを送信することができます
  • ログは、ロギングシステムに送信することができる、大規模なデータ解析
  • 頻繁にIP機能を拒否したためにアクセスを増やします。Redisのは、期限切れのキャッシュ実装を使用することができます。

おすすめ

転載: www.cnblogs.com/qingmiaokeji/p/10988901.html