如何使用 Docker 快速搭建反向隧道实现内网穿透?

来源:CDN教程作者:新加坡程序员头衔:程序员
导读:本期聚焦于新加坡程序员创作的《如何使用 Docker 快速搭建反向隧道实现内网穿透?》,敬请观看详情。内网服务器没有公网IP,怎么从外网访问它?反向隧道是解决这个问题的经典方案。本文介绍如何借助 Docker 容器在公网机器上部署服务端,在内网机器上运行客户端,通过 SSH 反向隧道或 frp 两种方式打通内外网通信。文章详细讲解端口映射、容器网络模式选择、自动重连配置以及常见踩坑点,比如连接超时、GatewayPorts 设置和容器重启策略。整套方案无需在宿主机安装多余软件,迁移和销毁都很方便,适合需要远程运维、在家自建服务对外暴露场景的开发者阅读参考。

把服务部署在家里的机器或者公司内网服务器上之后,最头疼的问题往往不是服务本身,而是外面的人根本访问不到它。运营商不给公网 IP,路由器后面又是层层 NAT,这时候反向隧道就派上用场了。反向隧道的思路很简单:内网机器主动去连接一台有公网 IP 的服务器,把这条连接“占住”,公网服务器再把外部请求通过这条连接转发回内网。而用 Docker 来搭建整个链路,可以做到环境隔离、配置即代码、随时销毁重建,比直接在系统里装软件省心得多。

如何使用 Docker 快速搭建反向隧道实现内网穿透?

反向隧道的核心原理

要理解反向隧道,得先明白为什么正向连接行不通。内网机器访问公网没有任何障碍,因为 NAT 会自动维护一张映射表;但反过来,公网机器主动连内网时,NAT 上没有对应的映射记录,数据包根本不知道该转发给谁。所以解决方向不是想办法穿透 NAT,而是让内网机器主动发起连接,把这条已经建立的 TCP 连接当成一条“管道”,公网侧的流量顺着管道流回去。

SSH 的 -R 参数就是最经典的反向隧道实现。内网机器执行 ssh -R 8080:localhost:80 user@公网服务器 后,公网服务器的 8080 端口收到的所有请求,都会通过这条 SSH 连接转发给内网机器的 80 端口。整个过程不需要在公网服务器上做任何额外配置,只要它能跑 SSH 服务就行。这个特性让 SSH 反向隧道成为最轻量的方案,缺点是连接稳定性依赖 SSH 客户端的重连能力,断线后需要机制自动恢复。

如果需要转发多个端口、区分多台内网机器,或者想要图形化面板管理,frp 这类专用工具就更合适了。frp 分为 frps(服务端,跑在公网机器)和 frpc(客户端,跑在内网机器)两个角色,配置文件声明式地定义端口映射关系,功能比 SSH 隧道丰富得多,支持 TCP、UDP、HTTP、HTTPS 等多种协议。两种方案各有适用场景,下面分别演示 Docker 部署方式。

方案一:用 Docker 跑 SSH 反向隧道

传统做法是在内网机器上装 autossh 做持久化反向连接,其实用 Docker 完全可以替代,而且更干净。核心思路是构建一个只包含 ssh 客户端的镜像,把密钥和启动脚本挂载进去,配合 restart 策略实现断线自动拉起。下面是一个可用的 Dockerfile:

# 基于轻量 Alpine 镜像
FROM alpine:3.19

# 安装 ssh 客户端和 autossh
RUN apk add --no-cache openssh-client autossh

# 自动重连脚本
COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh

ENTRYPOINT ["/entrypoint.sh"]

entrypoint.sh 的内容很简短,autossh 会监控 SSH 连接状态,一旦断开就自动重试:

#!/bin/sh
autossh -M 0 \
  -o "ServerAliveInterval=30" \
  -o "ServerAliveCountMax=3" \
  -o "StrictHostKeyChecking=no" \
  -N -R 8080:localhost:80 \
  -p 22 user@your-public-server.com

这里有几个细节值得注意。-M 0 表示关闭 autossh 自带的监控端口,改用 SSH 协议自身的 KeepAlive 机制,这是目前更推荐的做法;ServerAliveInterval=30 让客户端每 30 秒发一次心跳,连续 3 次没响应就判定断线并重连。运行容器时记得把私钥通过 volume 挂载进去,并加上 --restart=always,这样宿主机重启后隧道也能自动恢复。

还有一个非常容易踩的坑:默认情况下,公网服务器上的 sshd 只允许反向端口绑定在 127.0.0.1 上,也就是说只有公网服务器本机能访问这个端口,外部依然访问不到。解决办法是编辑公网服务器的 /etc/ssh/sshd_config,把 GatewayPorts 改成 clientspecified 或者 yes,然后在 -R 参数里显式指定绑定地址,例如 -R 0.0.0.0:8080:localhost:80,改完记得重启 sshd 服务。

方案二:用 Docker 部署 frp 实现内网穿透

当需求复杂起来,比如要同时暴露 Web 服务、远程桌面、数据库等多个端口,frp 的声明式配置就体现出优势了。服务端用一行 Docker 命令即可启动:

docker run -d --name frps --restart=always \
  -p 7000:7000 -p 7500:7500 -p 8080:8080 \
  -v /opt/frp/frps.toml:/etc/frp/frps.toml \
  snowdreamtech/frps

其中 7000 是 frps 与 frpc 之间的通信端口,7500 是监控面板端口,8080 是预留给内网服务对外暴露的端口。frps.toml 配置也很简单:

bindPort = 7000
# 监控面板
webServer.port = 7500
webServer.user = "admin"
webServer.password = "你的密码"
# 开启 token 认证,防止被陌生人白嫖
auth.token = "一串足够长的随机字符串"

内网机器这边的 frpc 容器对应配置如下,假设要把内网一台机器上的 Web 服务暴露出去:

serverAddr = "your-public-server.com"
serverPort = 7000
auth.token = "与服务端一致的token"

[[proxies]]
name = "my-web"
type = "tcp"
localIP = "192.168.31.100"
localPort = 80
remotePort = 8080

启动 frpc 容器时有个网络模式的选择问题。如果内网服务就跑在同一台机器上,用默认的 bridge 模式、把 localIP 写成 host.docker.internal 或宿主机内网 IP 即可;但如果 frpc 需要访问局域网里其他设备的服务,建议直接用 --network=host 模式,让容器共享宿主机网络栈,省去容器内 DNS 解析和路由的麻烦。frpc 自带断线重连机制,配合 --restart=always 基本可以做到无人值守长期运行。

安全加固与常见问题排查

隧道打通等于给内网开了一扇门,安全措施必须跟上。首先是认证层面,SSH 方案务必禁用密码登录、只允许密钥认证;frp 方案则一定要设置 auth.token,网上大量被扫穿的 frp 服务就是因为用了默认配置。其次是暴露面控制,能在 frps 前面套一层 Nginx 反向代理并加 HTTPS 就尽量加,监控面板端口不要随意对全网开放,可以用防火墙限制来源 IP。

排查问题时可以按链路顺序逐段检查:先确认 frpc 日志里显示 login 成功,说明内外网之间的控制通道是通的;再从公网服务器本机执行 curl 127.0.0.1:8080 验证端口转发是否生效;最后从外部设备访问公网 IP 测试。如果本机通而外部不通,大概率是云服务器安全组没放行对应端口,这在阿里云、腾讯云上是高频踩坑点,很多人查了半天配置,最后发现是安全组规则漏了。

还有一个细节是容器时区。frp 的日志时间戳默认是 UTC,排查问题时容易产生“日志时间对不上”的困惑,可以在 docker run 时加上 -e TZ=Asia/Shanghai 解决。整体来说,Docker 化的反向隧道方案把整条链路拆成了几个可独立管理的容器单元,出问题时可以单独重启某一环,配置文件也能纳入 Git 管理,比传统的裸机部署方式可维护性高出不少。无论是临时调试还是长期运行,这套方案都值得作为标准实践沉淀下来。

Docker反向隧道内网穿透frp修改时间:2026-09-04 13:18:38

免责声明:已尽一切努力确保本网站所含信息的准确性。网站作品多为原创整理与精心创作,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们进行处理Email:chomcom@qq.com。
引用或转载本作品时,请注明当前出处:https://www.ipipp.com/html/20260904/50257.html,基于非商业用途的前提下,欢迎转载或二创本作品。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。