使用SSH建立内网穿透,能够访问内网的web服务器
搞了一个晚上,终于建立了一个内网穿透。和AI配合,还是得自己思考,AI配合才能搞定,不思考只依赖AI也不行。内网服务器只是简单地使用了python -m http.server 8899,但是对于Gradio建立的服务器好像不行,会出问题。
问题背景
需求
- 将内网的 Web 服务器(
http://localhost:8899
)通过 SSH 隧道映射到外网服务器,使外网可以通过外网服务器的8080
端口访问内网服务。
环境
- 内网服务器:
- Web 服务运行在
localhost:8899
。 - 可以访问外网服务器,但外网服务器无法直接访问内网服务器(由于防火墙限制)。
- Web 服务运行在
- 外网服务器:
- 外网 IP:
47.238.40.212
。 - 需要将
8080
端口的流量通过 SSH 隧道转发到内网的8899
端口。
- 外网 IP:
问题分析
-
SSH 隧道未正确建立:
- 外网服务器的
8080
端口被sshd
监听,但流量未正确转发到内网的8899
端口。 - 错误日志显示
upstream prematurely closed connection
,表明连接被提前关闭。
- 外网服务器的
-
Nginx 配置问题:
- Nginx 配置正确,将请求转发到
127.0.0.1:8080
,但 SSH 隧道未正常工作。
- Nginx 配置正确,将请求转发到
-
客户端服务问题:
- 内网的 Web 服务(
http://localhost:8899
)正常运行,但未通过 SSH 隧道暴露到外网。
- 内网的 Web 服务(
解决方案
1. 配置 SSH 隧道
在内网服务器上执行以下命令:
ssh -R 8080:localhost:8899 user@47.238.40.212
- 参数说明:
-R 8080:localhost:8899
:将外网服务器的8080
端口转发到内网的8899
端口。user@47.238.40.212
:外网服务器的用户名和 IP 地址。
验证 SSH 隧道:
- 在外网服务器上检查
8080
端口是否被sshd
监听:
输出示例:netstat -tuln | grep 8080
tcp 0 0 127.0.0.1:8080 0.0.0.0:* LISTEN 12345/sshd: user tcp6 0 0 ::1:8080 :::* LISTEN 12345/sshd: user
2. 配置外网服务器的 SSH 服务
编辑 /etc/ssh/sshd_config
:
- 确保以下配置项已启用:
AllowTcpForwarding yes GatewayPorts yes
- 重启 SSH 服务以应用更改:
sudo systemctl restart sshd
检查防火墙:
- 确保外网服务器的防火墙允许
8080
端口的流量:sudo firewall-cmd --permanent --add-port=8080/tcp sudo firewall-cmd --reload
3. 配置 Nginx
编辑 Nginx 配置文件:
- 在外网服务器上编辑
/etc/nginx/nginx.conf
或/etc/nginx/conf.d/default.conf
,添加以下内容:server { listen 80; server_name xinnian.wang; location / { proxy_pass http://127.0.0.1:8080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_connect_timeout 300s; proxy_read_timeout 300s; proxy_send_timeout 300s; } }
测试 Nginx 配置:
- 检查配置文件语法:
sudo nginx -t
- 重新加载 Nginx 配置:
sudo systemctl reload nginx
4. 启动内网 Web 服务
在内网服务器上启动 Web 服务:
- 使用 Python 的
http.server
模块启动 Web 服务:python -m http.server 8899
- 确保服务正常运行,并可以通过
http://localhost:8899
访问。
5. 测试 SSH 隧道
在外网服务器上测试:
- 使用
curl
测试8080
端口:
如果 SSH 隧道正常工作,应该返回内网 Web 服务的内容。curl http://127.0.0.1:8080
通过外网访问:
- 在外网浏览器中访问
http://47.238.40.212:8080
,确认可以访问内网 Web 服务。
最终结果
- SSH 隧道成功建立:
- 外网服务器的
8080
端口通过 SSH 隧道转发到内网的8899
端口。
- 外网服务器的
- Nginx 配置正确:
- Nginx 将外网请求转发到
127.0.0.1:8080
,并通过 SSH 隧道传递到内网。
- Nginx 将外网请求转发到
- 测试成功:
- 通过
curl http://127.0.0.1:8080
和浏览器访问http://47.238.40.212:8080
,成功访问内网 Web 服务。
- 通过
后续建议
-
保持 SSH 隧道稳定:
- 使用
autossh
或tmux
保持 SSH 隧道的稳定性。 - 示例:
autossh -M 0 -o "ServerAliveInterval 60" -o "ServerAliveCountMax 3" -R 8080:localhost:8899 user@47.238.40.212
- 使用
-
安全性:
- 使用 SSH 密钥认证代替密码认证。
- 限制允许访问的 IP 地址。
-
日志监控:
- 定期检查 Nginx 和 SSH 的日志,确保没有异常访问或错误。
🚀
- 定期检查 Nginx 和 SSH 的日志,确保没有异常访问或错误。