node 后端代理服务器

分析攻击日志,有几种常见的攻击手段:

上传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
编码实现逻辑图

在这里插入图片描述

以下有代码分享
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);
### 部署 Node.js 后端与连接的数据库至云服务器的最佳实践 #### 准备工作 在开始之前,确保已经完成本地开发环境中的所有功能验证。这包括确认 Node.js 应用可以正常启动,并且能够成功连接到 MySQL 数据库并执行查询[^1]。 #### 选择合适的云平台 常见的云服务平台如 AWS、Google Cloud Platform (GCP) 和 Microsoft Azure 提供了丰富的资源和服务支持。这些平台通常提供虚拟机实例以及托管数据库服务(例如 Amazon RDS 或 Google Cloud SQL),便于快速部署和管理应用及数据库。 #### 创建云服务器实例 登录所选云服务商控制台,创建一个新的虚拟机实例作为运行 Node.js 的主机。配置过程中需注意以下几点: - **操作系统**: 推荐使用轻量级 Linux 发行版(如 Ubuntu Server)。 - **安全组/防火墙设置**: 打开必要的端口(比如 HTTP 的 80, HTTPS 的 443 及自定义 API 端口,默认可能是 3000)。同时关闭不必要的外部访问权限以提高安全性。 #### 安装依赖软件 通过 SSH 连接到新创建的云服务器,在终端上依次安装所需的软件包: ```bash sudo apt update && sudo apt upgrade -y sudo apt install nodejs npm mysql-client nginx -y ``` #### 配置 Nginx 代理反向代理 为了提升性能和保护应用程序直面公网的风险,建议利用 Web 服务器如 Nginx 设置反向代理指向内部监听的服务地址 `http://localhost:3000` 。编辑站点可用配置文件 `/etc/nginx/sites-available/default` ,添加如下内容: ```nginx location / { proxy_pass http://localhost:3000; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection 'upgrade'; proxy_set_header Host $host; proxy_cache_bypass $http_upgrade; } ``` 重启 Nginx 生效更改: ```bash sudo systemctl restart nginx ``` #### 上载项目代码 可以通过 Git 或 SCP 将本地项目的源码上传至远程服务器指定目录下。如果采用版本控制系统,则先初始化仓库再推送分支;若是直接复制则命令类似于这样: ```bash scp -r ./my-node-app user@your-server-ip:/home/user/ cd ~/my-node-app npm install --production NODE_ENV=production PORT=3000 node server.js & ``` #### 数据库迁移 对于生产环境中使用的数据库,推荐选用云端提供的关系型数据库解决方案而非自行搭建MySQL实例。这是因为它们自带备份策略、自动扩展等功能简化运维负担。假设选择了Amazon RDS上的MySQL引擎,那么只需修改原有的 connection string 替换成新的RDS endpoint即可[^2]: ```javascript const dbConfig = { host : 'aws-rds-endpoint.amazonaws.com', user : 'db_user', password : 'password', database : 'test_db' }; ``` #### 测试接口连通性 最后一步就是检验整个系统的运作状况。打开浏览器输入公有IP加上路径 `/api/data`, 或者借助 Postman 工具发起请求查看返回的数据结构是否符合预期[^3]。 #### 考虑适用场景优化架构设计 考虑到Node.js擅长处理大量短时间内的读写操作特性[^4], 如果目标系统预计会有较高的并发需求,可能还需要引入负载均衡器分摊流量压力,甚至考虑微服务拆解等方式进一步增强可维护性和弹性伸缩能力。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值