前言

我自身对于NAS的要求只不过是一个临时存储罢了,一两个T就够用,挂一些番剧的下载任务,emby媒体库自动刮削,看完扔到我80T的RaidZ3冷备份服务器里就行了,基本没有外网访问家里文件的需求。如果有,我也会借助OneDrive的同步,完全不需要人工值守。不过最近有个朋友要润到艾美莉卡了,他还是想把文件存在家里,我也是最近刷到了Cloudflare Tunnel的视频,于是本着生命不息、折腾不止的想法,稍微玩了一下这玩意。先说结论,国内能用,但是你最好在客户端挂一层代理。做个简单的内网穿透足够,做SMB在国内不开代理的速度在2-3MB/s浮动,也看时间段,开了代理能提升不少。

Cloudflare配置Tunnel

Cloudflare Dashboard左侧点击Zero Trust,按要求设置支付方式,进去后找到网络->Tunnels

我的域名是在Cloudflare上买的,早就绑好卡了。没有支付方式可参考没有公网IP? 免费域名搭建cloudflare内网穿透,不限流量,不用绑卡支付跳过绑卡。

创建隧道,并选择Cloudflared,命名,然后下一步选择环境,选哪个无所谓,重点是把TOKEN保存出来。至于安装,常规方法按照提示安装就行,但我总是要玩点不一样的嘛,这个暂且放到后面。

接着下一步,配置域名和服务类型,按自己需求来就行,本文用的是SMB。注意服务的URL写的是内网地址。安装在服务本机就127.0.0.1,其他正常写内网地址就行。

创建好之后回到Tunnels主页,你可以查看到已创建隧道的UUID,复制备用。

安装并运行连接器

既然都说了要玩点不一样的,那常规安装我就不介绍了。这次要玩的是要与之前搭建好的一套系统进行结合,我将分别介绍连接器immortalwrtTrueNAS上的使用方法。

immortalwrt

在软件包中安装luci-app-cloudflared,安装好后在顶部VPN一栏选择进入。

先将上面保存出来的TOKEN粘贴进去。

config.yml的编写参考官方文档File structure for public hostnames,以下是用于immortalwrt的示例。

1
2
3
4
5
6
7
tunnel: 6ff42ae2-765d-4adf-8112-31c55c1551ef
credentials-file: /etc/cloudflared/6ff42ae2-765d-4adf-8112-31c55c1551ef.json

ingress:
- hostname: your.host.name
service: smb://192.168.2.33:445
- service: http_status:404

tunnel填写你创建隧道的UUID,在Tunnels主页查看,上面说过复制备用了。

credentials-file的路径是luci-app-cloudflaredimmortalwrt上的安装路径,这个文件是软件运行时生成的,这里只是规范路径和命名。

cert.pemhttps://dash.cloudflare.com/argotunnel获取,参考官方文档origincert

下载下来后上传至目标位置,你可以直接在luci-app-cloudflared配置页面上传。

我习惯用scp了,使用前记得去软件包安装一下sftp server

1
scp "C:\Users\Administrator\Desktop\cert.pem" root@192.168.2.1:/etc/cloudflared/cert.pem

地区不用选择,直接启用就行了,启动后记得看一下日志,出现Registered tunnel connection字样就是链接成功了,此时可以去Tunnels主页看看状态,显示正常就没问题了。

注意,如果你在immortalwrt上使用了代理,可能导致隧道连接不上。关闭你的代理,让隧道建立连接后再开回来。已建立的隧道连接会长时间维持,不会切换至代理连接。

TrueNAS

注意TrueNAS版本不能太低,低版本的App使用的是Kubernetes而不是docker

选择Custom App,名字自己取,Repositorycloudflare/cloudflaredTag默认latest不动。

下面是重点,Command的填写方法。

官方运行docker的完整命令类似于

1
docker run cloudflare/cloudflared:latest tunnel --no-autoupdate run --token yourtoken

对于后面的参数,Command要一个一个ADD,所以你要添加五条Command,依次填写tunnel--no-autoupdaterun--tokenyourtoken

勾选上Host Network,否则cloudflared无法访问你的内网ip

启动应用即可。返回Tunnels主页,状态正常就好了。

Windows挂载

首先Windows客户端也要安装cloudflared

1
winget install --id Cloudflare.cloudflared

然后先把Cloudflare Tunnel映射到本地。注意不要写localhost,后面会说。

1
cloudflared access tcp --hostname smb.example.com --url 127.0.0.1:8445

接着是Windows挂载非标SMB端口。大多数人是把监听在本机445Server服务禁用掉,然后把非标端口转发到本机445,但这么做就不能开启本机的SMB了,只能挂载SMB,而且也只能挂载一个,非常受限。我这台主力电脑有的时候也要向其他设备分享文件,也是要用到Server服务的,不能禁用,所以要另寻他路。

首先在PowerShell 中安装LoopbackAdapter模块,并创建一个虚拟网卡。需要在当前会话中临时放宽执行策略。

1
2
3
Set-ExecutionPolicy Bypass -Scope Process
Install-Module -Name LoopbackAdapter
New-LoopbackAdapter -Name "SMBProxy"

当然你可以手动添加
设备管理器 → 操作 → 添加过时硬件 → 手动安装 → 网络适配器 → Microsoft → Microsoft KM-TEST 环回适配器

然后给网卡配置ip,子网掩码随便,网关不用写。我这里以10.0.0.2为示例。

然后把Cloudflare Tunnel映射到本地的127.0.0.1:8445再监听到10.0.0.2:445上。这也是为什么上面不要写localhost的原因。

1
netsh interface portproxy add v4tov4 listenaddress=10.0.0.2 listenport=445 connectaddress=127.0.0.1 connectport=8445

使用netsh interface portproxy show v4tov4查看是否配置正确。

至此,你就能用\\10.0.0.2\path愉快的链接你的SMB了。

消除cloudflared运行窗口并开机自启

正常使用的情况下你也不希望cloudflared的命令行窗口出现在你眼前吧,而且SMB一般我们也都设置了开机时自动连接。我们要让cloudflared也在开机的时候运行在后台。

新建一个Start-Cloudflared.ps1文件,找个合适的地方放。

1
Start-Process "cloudflared.exe" -ArgumentList 'access tcp --hostname smb.example.com --url 127.0.0.1:8445' -WindowStyle Hidden

然后写一个Run-Cloudflared-ps1.vbs放在Windows启动目录。win+rshell:startup

1
2
Set objShell = CreateObject("Wscript.Shell")
objShell.Run "powershell.exe -NoProfile -ExecutionPolicy Bypass -File ""C:\Start-Cloudflared.ps1""", 0