You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

为非安全WebSocket服务器搭建安全WebSocket代理方案咨询

嘿,这个需求我刚好帮不少开发者落地过——核心就是把内网不安全的ws://流量转换成对外的wss://,同时确保内网的非安全WebSocket完全不暴露到外网。下面是几个最靠谱的实现方案,你可以根据自己的技术栈和需求选:

方案1:Nginx反向代理(生产环境首选)

Nginx是目前最成熟的反向代理工具,配置简单、性能稳定,完全能满足你的需求。步骤如下:

  1. 申请SSL证书
    用Let's Encrypt的免费证书就行,推荐用certbot工具一键申请:

    sudo certbot certonly --standalone -d your-proxy-domain.com
    

    执行后证书会存在/etc/letsencrypt/live/your-proxy-domain.com/目录下。

  2. 配置Nginx的WebSocket代理
    编辑你的Nginx站点配置文件(比如/etc/nginx/sites-available/wss-proxy.conf),添加以下内容:

    server {
        listen 443 ssl;
        server_name your-proxy-domain.com;
    
        # 加载SSL证书
        ssl_certificate /etc/letsencrypt/live/your-proxy-domain.com/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/your-proxy-domain.com/privkey.pem;
    
        # 处理WebSocket请求的转发规则
        location /ws {
            # 替换成你的内网服务器IP和WebSocket端口
            proxy_pass http://192.168.1.100:8080;
            # 必须设置这两个头,才能正确升级为WebSocket连接
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
            # 传递真实客户端IP给内网服务器(可选)
            proxy_set_header X-Real-IP $remote_addr;
        }
    }
    
    # 可选:把80端口的HTTP请求重定向到HTTPS
    server {
        listen 80;
        server_name your-proxy-domain.com;
        return 301 https://$host$request_uri;
    }
    
  3. 重启Nginx生效

    sudo nginx -t && sudo systemctl restart nginx
    

之后外网用户就可以通过wss://your-proxy-domain.com/ws访问,所有流量都会被Nginx加密后转发到内网的ws://192.168.1.100:8080,内网的非安全流量完全不会流出。

方案2:Node.js自定义代理(适合需要定制逻辑的场景)

如果你需要在代理层加一些自定义处理(比如用户鉴权、请求日志、流量过滤),用Node.js写个轻量代理是个不错的选择:

  1. 初始化项目并安装依赖

    npm init -y
    npm install ws http-proxy https fs
    
  2. 编写代理代码
    创建wss-proxy.js文件:

    const https = require('https');
    const httpProxy = require('http-proxy');
    const fs = require('fs');
    
    // 加载SSL证书(替换成你的证书路径)
    const sslOptions = {
      key: fs.readFileSync('/path/to/privkey.pem'),
      cert: fs.readFileSync('/path/to/fullchain.pem')
    };
    
    // 创建代理实例
    const proxy = httpProxy.createProxyServer({});
    
    // 创建HTTPS服务器处理wss请求
    const server = https.createServer(sslOptions, (req, res) => {
      // 这里可以加自定义逻辑,比如验证请求头里的token
      if (!req.headers.authorization) {
        res.writeHead(401);
        res.end('Unauthorized');
        return;
      }
      // 转发到内网服务器
      proxy.web(req, res, {
        target: 'http://192.168.1.100:8080',
        ws: true
      });
    });
    
    // 处理WebSocket连接的升级请求
    server.on('upgrade', (req, socket, head) => {
      proxy.ws(req, socket, head, {
        target: 'http://192.168.1.100:8080'
      });
    });
    
    // 启动服务器
    server.listen(443, () => {
      console.log('Secure WebSocket proxy running on wss://your-proxy-domain.com');
    });
    
  3. 启动代理

    node wss-proxy.js
    

    建议用pm2之类的进程管理器托管,避免终端关闭后进程终止。

方案3:Caddy(零配置快速上手)

如果你不想折腾配置,Caddy是最佳选择——它会自动申请和续期SSL证书,配置极简:

  1. 安装Caddy
    按照官方指引安装后,创建Caddyfile

    your-proxy-domain.com {
      reverse_proxy /ws http://192.168.1.100:8080 {
        header_up Upgrade $http_upgrade
        header_up Connection "upgrade"
      }
    }
    
  2. 启动Caddy

    caddy run
    

    启动后Caddy会自动完成证书申请、HTTPS配置和WebSocket转发,全程不用手动干预。


几个关键注意事项

  • 确保代理服务器能通过内网IP访问到目标服务器,且目标服务器的防火墙允许代理服务器的IP访问其WebSocket端口
  • 代理服务器要开放443端口给外网,同时关闭不必要的端口,降低安全风险
  • 用Let's Encrypt证书的话,记得开启自动续期(Nginx和Caddy默认都支持)
  • 测试连接可以用wscat工具:wscat -c wss://your-proxy-domain.com/ws,看是否能正常和内网服务器通信

内容的提问来源于stack exchange,提问作者James Baker

火山引擎 最新活动