如何无需开放端口/修改防火墙,安全实现Web服务器向本地传数据?
可行方案:反向SSH隧道(无需开放本地端口/修改防火墙)
核心原理
反向SSH隧道的本质是本地机器主动发起出站SSH连接到Web服务器,把本地Flask的服务端口映射到Web服务器的一个内部端口上。因为连接是从本地向外发起的,防火墙默认允许出站流量,完全不需要在本地开放入站端口或修改防火墙规则;同时Web服务器上的映射端口可以只允许本地访问,不会暴露到公网,安全性有保障。
实操步骤
在本地机器建立反向SSH隧道
执行以下命令(替换成你的Web服务器信息):ssh -R 8000:localhost:5000 your-server-user@your-server-ip参数说明:
-R:表示创建反向隧道8000:Web服务器上用于接收请求的端口(可自定义,只要服务器上没被占用)localhost:5000:本地Flask应用的地址和端口your-server-user@your-server-ip:Web服务器的SSH登录账号和IP
配置Web服务器的SSH服务(允许外部访问映射端口)
默认情况下,SSH反向隧道的映射端口只能被Web服务器本地访问,需要修改SSH配置让它能被服务器上的应用调用:- 编辑
/etc/ssh/sshd_config,找到并设置:GatewayPorts yes - 重启SSH服务使配置生效:
sudo systemctl restart sshd
- 编辑
启动本地Flask应用(带HTTPS)
确保Flask监听本地端口,同时开启HTTPS(临时测试可用自签名证书,生产环境建议用正规CA证书):from flask import Flask, request app = Flask(__name__) @app.route('/', methods=['POST']) def receive_data(): content = request.form.get('input_text') print(content) return 'Received', 200 if __name__ == '__main__': # adhoc参数生成临时自签名证书,用于HTTPS app.run(host='localhost', port=5000, ssl_context='adhoc')Web服务器端发起请求
把网页提交的POST请求目标改为https://localhost:8000(Web服务器上的映射端口),这个请求会通过SSH隧道自动转发到本地的Flask应用。
稳定性优化
如果需要长期保持隧道连接,建议用autossh工具自动重连断开的SSH连接:
autossh -M 20000 -R 8000:localhost:5000 your-server-user@your-server-ip
-M 20000指定一个用于监控连接状态的端口,当SSH断开时autossh会自动重新建立连接。
替代方案(可选)
- WebSocket反向代理:本地Flask主动连接Web服务器的WebSocket服务建立长连接,Web服务器通过这个连接转发POST请求。原理和SSH隧道类似,但配置复杂度更高,适合需要自定义协议的场景。
- 内网穿透工具:比如一些第三方中继服务,适合临时测试,但长期使用不如SSH隧道可控和安全,因为依赖第三方服务器。
内容的提问来源于stack exchange,提问作者dani
相关产品推荐
相关产品推荐

