【nodejs代理服务器一】nodejs http-proxy 开发反向代理服务器,防火墙,过滤常见的web渗透
事出有因
最近web系统引来了黑客的攻击,经常被扫描,各种漏洞尝试。
分析攻击日志,有几种常见的攻击手段:
- 上传webshell
- 远程执行命令漏洞
- sql注入
- xxs 攻击
- 试探各种开源框架爆出来的漏洞
分析攻击信息的特点
说白了就是采用web渗透技术,利用http请求,黑客想尽办法,在http header ,body,等部分植入非法的命令,非法字符常见的有:exe,cmd,powershell,download,select,union,delete等等。
解决问题思路
- 我们能不能开发个代理服务器,来分析http请求header,body里面的信息,如果有非法字符,就截断,拒绝服务。
- 配置允许请求的白名单,拒绝非法Url.
网络拓扑

http proxy 拦截非法请求,拒绝服务。
技术选型
常见的代理服务器有nginx,apache,不知道这2个代理服务器能不能灵活的配置,过滤,转发,没有深入了解。
因此选用nodejs http-proxy。
nodejs优点
- 轻量级
- 快速部署
- 灵活开发
- 高吞吐,异步io
编码实现逻辑图

绝对干货,分享代码
代码依赖
- http-proxy 1.17.0
https://github.com/nodejitsu/node-http-proxy 代码地址 - "colors": "~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 过期缓存实现。
【nodejs代理服务器一】nodejs http-proxy 开发反向代理服务器,防火墙,过滤常见的web渗透的更多相关文章
- 用PHP实现反向代理服务器
什么是反向代理: 百度百科有云: 反向代理(Reverse Proxy)方式是指以代理服务器来接受internet上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给int ...
- Windows下使用nginx搭建反向代理服务器
反向代理(Reverse Proxy)方式是指以代理服务器来接受internet上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给internet上请求连接的客户端,此时 ...
- Nginx 一个高性能的HTTP和反向代理服务器
本文只针对Nginx在不加载第三方模块的情况能处理哪些事情,由于第三方模块太多所以也介绍不完,当然本文本身也可能介绍的不完整,毕竟只是我个人使用过和了解过,欢迎留言交流. Nginx能做什么 ——反向 ...
- 高并发解决方案--负载均衡(HTTP,DNS,反向代理服务器)(解决大流量,高并发)
高并发解决方案--负载均衡(HTTP,DNS,反向代理服务器)(解决大流量,高并发) 一.总结 1.什么是负载均衡:当一台服务器的性能达到极限时,我们可以使用服务器集群来提高网站的整体性能.那么,在服 ...
- 如何搭建web服务器 使用Nginx搭建反向代理服务器 .
引言:最近公司有台服务器遭受DDOS攻击,流量在70M以上,由于服务器硬件配置较高所以不需要DDOS硬件防火墙.但我们要知道,IDC机房是肯定不允许这种流量一直处于这么高的,因为没法具体知道后面陆续攻 ...
- apache代理服务器为nodejs服务设置域名
本机以apache为主,其中 在httpd.conf中先设置 <VirtualHost *:80> ServerName nodejs.cc ServerAlias www.nodejs. ...
- nodeJS学习(4)--- webstorm/...开发 NodeJS 项目-节1
前提: 已安装好 IDE ,eg:webstorm/IDEA 2016.3 & 2017.1 nodeJS(含 npm 及 相应的模板等) 要用 webstorm 开发 NodeJS项目(we ...
- 【APT】NodeJS 应用仓库钓鱼,大规模入侵开发人员电脑,批量渗透各大公司内网
APT][社工]NodeJS 应用仓库钓鱼,大规模入侵开发人员电脑,批量渗透各大公司内网 前言 城堡总是从内部攻破的.再强大的系统,也得通过人来控制.如果将入侵直接从人这个环节发起,那么再坚固的防线, ...
- 反向代理服务器(Reverse Proxy)
反向代理服务器(Reverse Proxy) 普通代理服务器是帮助内部网络的计算机访问外部网络.通常,代理服务器同时连接内网和外网.首先内网的计算机需要设置代理服务器地址和端口,然后将HTTP请求 ...
随机推荐
- (一)UML概览
类图
- sqlserver如何创建链接服务器
遇到下列问题: 线上服务器A,中转服务器B,本地服务器C 数据在A上面,想在B上面操作类似 select * from [A].[database].table这样的SQL,不用去链接服务器,直接把处 ...
- CentOS 7中安装和配置Promethues
Prometheus 是什么? Prometheus是一套开源的监控&报警&时间序列数据库的组合,起始是由SoundCloud公司开发的.随着发展,越来越多公司和组织接受采用Prome ...
- 【C#设计模式1】单例模式
一.引言 最近在设计模式的一些内容,主要的参考书籍是<Head First 设计模式>,同时在学习过程中也查看了很多博客园中关于设计模式的一些文章的,在这里记录下我的一些学习笔记,一是为了 ...
- 【Aizu - 0189】Convenient Location (最短路 Floyd算法)
Convenient Location 直接翻译了 Descriptions 明年毕业的A为就业而搬家.就职的公司在若干城市都有办公室,不同天出勤的办公室也不同.所以A在考虑住在哪去各个办公室的时长最 ...
- css实现可伸缩的搜索框
效果图: 代码: <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" ...
- 判断scrollView的滑动方向(二)
在上一篇文章<判断scrollView的滑动方向>中谈到的第二种方法是根据滑动速率来判断的. 今天将通过滑动过程中的坐标差来判断 - (void)scrollViewDidScroll:( ...
- UiPath工具当中写入代码
在UIPath的工具中选择下面的控件 点击[Edit Code]之后出现写代码的地方,入力VB.net代码 点击[Edit Arguments]之后是这个方法的传入和传出的值. 下面自己做的一个小例子 ...
- 日常工作问题解决:使用vmvare克隆centos6虚拟机造成无eth0的解决办法
目录 一.问题描述 样本虚拟机配置有两张网卡,eth0.eth1,使用vmvare克隆虚拟机后,复制的虚拟机,没有网卡eth0,eth1,而是有eth2.eth3,如下所示: 二.原因分析 复制系统中 ...
- 获取Android手机日志
方式一:使用USB连接 1.在手机上启用USB调试2.在终端输入adb devices 3.获取日志 只连接一个设备:1)清除已缓存日志:adb logcat -c2)获取日志并保存到本地:adb l ...