使用Cloudflared穿透内网Docker服务
前些日子发现之前在美国买的swift3已经胜任不了国内的办公软件压力了。恰好之前又了解到开源的飞牛os,于是想着与其浪费这个电脑放在角落吃灰,不如刷个玩玩。swift3的配置虽说在国内个个都塞虚幻引擎的软件下有点吃力但是作为nas还是没有什么压力的。1135G7的cpu比绿联3000价位的成片nas还高。8G的RAM对于nas来说也是完全够用。
我一直想能在外网访问内网服务,例如某个端口上的视频下载器,或者是搭建个api服务。无奈我的房子简陋至极,不仅没有ipv4,连公网ipv6都没有,无奈开不了ddns;由于是租的房子,也没法开通什么。这时候就想到了老朋友cloudflare,果然cloudflare是提供免费的内网穿透的。虽然飞牛os自带一个,但是是他给的域名,而且还要手机号注册,就一直没注册。恰好飞牛os又带了docker管理,那就直接开整。
P.S. 值得一提的是,cloudflare tunnel既没有上下行带宽限制,还没有用量限制!想充钱都找不到入口!这样的服务我用起来良心都有点过不去。
在安装前,受限于网络环境,需要在fnOS的镜像仓库-设置-加速源设置中添加加速源,推荐毫秒:docker.1ms.run
,之后就可以愉快的开始下载了,镜像都会从这个源来pull。
考虑到便捷性,以下方式为cloudflare web控制台方法,也可以在本地ssh后用cli设定,但是更为复杂。
登录cloudflare后,在侧边找到zero trust→网络→tunnel,新建tunnel,然后填写自定义名称,就可以拿到各个平台的安装代码了。选择docker可以复制如下代码:
docker run cloudflare/cloudflared:latest tunnel --no-autoupdate run --token <你的token>
--token
后就是你的token,可以先记下。由于cloudflared不提供webui,要在一开始docker run的时候就制定好token,在fnOS里的docker里的 compose 选项卡中新建如下docker-compose.yaml
:
version: '3.8'
services:
cloudflared:
image: cloudflare/cloudflared:latest
container_name: cloudflared
restart: always
network_mode: host
command: tunnel --no-autoupdate run --token <替换为刚才显示的token>
启动之后就可以看到cloudflare控制台显示已有一个连接器连接成功了。点击下一步,就可以接着配置要转发到的域名了。由于fnOS默认是http,需选择http类型,然后代理内容填上你要访问的域名就可以了。例如
nas.mydomain.com
→ http://localhost:5666
就可以把fnOS的后台管理页面反代到nas.mydomain.com
上。在外网访问nas.mydomain.com
就等同于在内网访问http://localhost:5666
了。
Cloudflare除了其他几个固定的协议,仅仅支持80/443端口的转发,也就是说你无法设定域名的端口号,例如
nas.mydomain.com:1234
。
你还可以选择穿透更多服务,只需要单独再开一个cloudflared容器就可以了(注意确保项目和docker-compose配置文件里的容器名不一样),当然你也可以选择cli修改本地的config文件。但是反正我找了好久都没找到。
踩的坑
1.
我其实一开始连接日志都没错但是访问域名console里就是显示404,以及websocket无法连接:
index-CQTteHea.js:141 WebSocket connection to 'wss://nas.zly.vg/websocket?type=main' failed:
我感觉很莫名其妙,尤其是在看完youtuber的教程之后,我发现过程一模一样。在跟chatgpt多轮分析之后,我突然意识到,之前为了让我的cloudflare r2能只用文件名不用.html
扩展名访问网页,我开启了如下规则
来让让所有mydomain.com/xxx 自动重定向到 mydomain.com/xxx.html。所以导致所有的连接最后都带上了.html
,404和websocket地址有误的问题也瞬间迎刃而解了。
不过我感觉应该不会再有人跟我有一样的问题了... 大部人正常人都如果是我这种需求都不会选择r2而是page...
2.
如果你也像我一样使用了类似typecho等CMS,无比确保你把“站点基本信息”中的网址填对,应该填你想要穿透出去的域名,而不是内网ip+端口号。不然fnOS默认http但是cloudflared穿透服务之后默认挂SSL证书变成https就和内网中走的http不符了,你的一些内部资源请求就会失效,console里报错:Failed to load resource: net::ERR_SSL_PROTOCOL_ERROR
穿透速度
如下是我通过fnOS分享的,本来仅支持内网分享链接的文件下载速度,实测最快能跑道2.4Mb/s。还是非常可观的
存在的问题
有时候,会莫名其妙连接不到cloudflare,日志中报错
2025-08-23T12:32:58Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=...
2025-08-23T12:32:58Z INF Retrying connection in up to 1m4s connIndex=3 event=0 ip=...
2025-08-23T12:32:58Z ERR Connection terminated error="failed to dial to edge with quic: timeout: no recent network activity" connIndex=3
failed to accept QUIC stream: timeout: no recent network activity" connIndex=2 event=0 ip=...
针对这个问题,大概率是ISP/路由器/防火墙对 UDP/7844 不友好。可以尝试使用以下代码不用auto的默认quic优先,而是强制http2::
--protocol http2 --edge-ip-version 4 --ha-connections 1
- 本文标题:使用Cloudflared穿透内网Docker服务
- 本文作者:uygnil
- 本文链接:https://blog.zhoulingyu.net/index.php/archives/9/
- 版权声明:本文采用 CC BY 4.0 协议进行许可
标签:无