nas 上有多个服务对应着多个端口. 本文将介绍三种方法来隐藏端口.
环境
- 广东电信
- 群晖 7.0
- cloudflare
方案1: 群晖自动的反向代理
这个方法最简单, 先按需注册不同二级域名[1]
然后通过群晖自带的 ngnix 配置反向代理即可, 如下图所示.
但该方案缺点很明显且致命: 除非备案, 不然 443 端口和 80 端口默认是封的. 即, 依然需要在域名后加端口来访问 nas.
方案2: 使用 cloudflare workers 代理
该方案是在方案1基础上改装的. 没有 443 端口, 就得想办法怎么把非标准端口转为 443 端口, 经过一番搜索后找到了这个解决方案
sequenceDiagram Client->Cloudflare: 443 request Cloudflare->nas: 6443 request nas-->Cloudflare: 6443 response Cloudflare-->Client: 443 response
如上图所示, nas 暴露出来一个端口, cloudflare 负责把用户的请求发往这个端口, 再把这个端口返回的内容原封不动发回给用户. 所以 nas 上基本不用做什么, 仅需配置好 worker
按下图新建 worker
到这里把下面的代码粘贴上去并点击 Save and Deploy, 至此就配置完成了, 可以在右边的测试窗里输入域名测试.(注意这代码是我根据原代码[2]改的, 使用前请参考原 readme 及 原文
1 | let Svr = { |
这个方案理论上可以完美运行的, 但不知道为什么我这边在局域网内就正常, 但到了广域网就连不上. 而在广域网通过 workers 的编辑界面可以测通. 也不知道是哪里配错或少配了, 请大佬们不吝赐教.
方案3: 使用 cloudflare tunnel 做内网穿透
以上两种方案都无法完美实现, 最终在 clarkzjw 大佬的推荐下使用了 cloudflare tunnel 做穿透, 这是一个优缺点都很明显的方案.
查看 cloudflare tunnel 官方文档 可以发现他的实现方式和 frp 很相似, 都是通过一个公网服务来实现内网穿透. 硬要说不同的话应该是两者属于不同的层级. tunnel 原理图如下(来自官网)
以下内容参考视频[3] 实现. 会省略部分操作, 如果有疑问请参考原视频, 里面演示了完整的一套操作.
- 创建文件夹 ~/docker/cloudflare
从 docker 下载 cloudflare 映像
映射存储空间
docker/cloudflare /home/nonroot/.cloudflared 勾选 使用与 Docker Host 相同的网络
命令填写 tunnel login
运行, 进入 容器 -> 详情 查看日志
复制链接到浏览器中打开完成登录, 再次查看日志可以看到下图则说明登录成功
且可发现 ~/docker/cloudflare 中多了一个 cert.pem 文件
导出上面的容器到 ~/docker/cloudflare 文件夹中, 并重命名为 xxx_create, 如下图
编辑文档内 cmd 属性, 要记住你的 tunnel 名, 后面还要用到
导入该配置文件到 docker 中, 并运行. (这里就不截日志的图了). 运行后可以发现 ~/docker/cloudflare 文件夹中多了一个 json 文件, 里面包含了调用 tunnel 所需凭证
创建 dns 记录, 这里你可以参考视频里的步骤, 也可以直接用上一步获得的 json 文件的文件名去创建 CNAME 记录, 按需创建. 比如我用了 foto 和 blog-pics 等, 都指向 tunnel 地址.
Type Name Target Proxy Status CNAME foto (json文件名).cfargotunnel.com 勾选 创建 tunnel 配置文件 config.yml, 其中 tunnel 填写第三步获取的 json 文件文件名, credentials-file 填写第三步获取到的 json 文件在 docker 中的路径 (即 /home/nonroot/.cloudflared/文件名.json)
1
2
3
4
5
6
7
8tunnel: 文件名
credentials-file: /home/nonroot/.cloudflared/文件名.json
ingress:
- hostname: foto.fm7077.it
service: http://localhost:端口 # 注意, 这里一定要用 http, 而不是 https 不然会因为证书不符导致 502 错误
# ~~~~ 其他你要暴露的服务
- service: http_status:404复制第三步导出的 json 文件并重命名为 xxx_run.
导入 docker 中, 设置 启用自动重新启动, 运行, 顺利的话就能看到如下图日志.
至此配置完成, 试着从外网通过域名访问 nas.
从上面的步骤可以看到, 使用该方案不需要公网 ip, 也不需要把服务器完整地暴露在公网上, 而且在没有 443 端口的情况下能隐藏服务器端口, 可以说非常完美了.
但缺点也很明显:
1. 在国内访问会比较慢.
2. 如果 docker 挂了, 而人又不在家就 gg 了. (这点可以通过直接暴露 nas 的方案<sup id="fnref:1"><a href="#fn:1" rel="footnote"><span class="hint--top hint--error hint--medium hint--rounded hint--bounce" aria-label="[给 nas 配置多个域名并配置 ssl | 一颗牛肉丸 (fm7077.it)](https://blog.fm7077.it/2022/05/05/set-ssl-for-multi-domain-names/)
“>[1]解决)
1. 不是缺点的缺点: 依赖免费的 tunnel.
总结
三个方案各有优缺点, 实现难度依次递增, 除了第二个没能完整验证外, 其他两个都能在特定环境下实现.
方案 | 优点 | 缺点 |
---|---|---|
方案一 | 操作简单 | 需要公网 ip 的443 端口没被封 |
方案二 | 不需要公网 443 端口 | 因不明原因无法在公网上正常使用 |
方案三 | 不需要暴露服务器到公网上 | 部署相对复杂. 在国内访问会比较慢, 如果 docker 挂了, 而人又不在家就 gg 了. (这点可以通过直接暴露 nas 的方案<span class=”hint–top hint–error hint–medium hint–rounded hint–bounce” aria-label=”[给 nas 配置多个域名并配置 ssl |
“>[1]解决) 不是缺点的缺点: 依赖免费的 tunnel |
希望这篇文章能帮到你.
参考链接
- 1.给 nas 配置多个域名并配置 ssl | 一颗牛肉丸 (fm7077.it) ↩
- 2.使用 cloudflare workers 作代理. ↩
- 2.KawaiiZapic/HidePortWorker ↩
- 3.CLOUDFLARE tunnel on SYNOLOGY - lu4t Tech ↩