外网远程访问威联通、群晖等 NAS 的异地容灾方案
Dec 17, 2022
| 2022-12-22
0  |  0 分钟
页面类型
Post
发布状态
Published
发布日期
Dec 17, 2022
文章地址
ddns-nas-proxy
内容摘要
最近没钱续宽带,用了用房东的宽带,谁曾想房东宽带的速度稳定性还很给力,就是没了公网,NAS用户体验直接夭折,官方的中转服务越用越气,应应急还行,所以研究了一下,利用 NewFuture/DDNS 开源软件配合 fatedier/FRP 实现了多地转发、异地容灾的折中方案,出奇稳定,还使用了 Cloudflare Tunnel 实现保底连接,从此 NAS 永不失联。
文章标签
NAS
DDNS
Python
文章分类
技术分享
icon代码
密码
Property
Dec 22, 2022 04:14 AM
最近没钱续宽带,用了用房东的宽带,谁曾想房东宽带的速度稳定性还很给力,就是没了公网,NAS用户体验直接夭折,官方的中转服务越用越气,应应急还行,所以研究了一下,利用 NewFuture/DDNS 开源软件配合 fatedier/FRP 实现了多地转发、异地容灾的折中方案,出奇稳定,还使用了 Cloudflare Tunnel 实现保底连接,从此 NAS 永不失联。
 
💡
文章内容尽量讲透整体的实现思路及原理,后期有空再提供完整服务器端及客户端的 docker compose 模板降低学习成本
 

注意事项

实现的本质是利用中间服务器进行中转,但我们可以利用 Cloudflare Tunnel 实现转发,起码比 NAS 官方中转好使。
1、中转服务器一个或多个(可选);
2、家里或朋友有公网的宽带能给你用(可选);
3、域名一枚并由Cloudflare管理;
4、NAS安装配置 Cloudflare Tunnel;
5、因人而异。

基本思路

用python编写程序使用tcping间歇测试中转服务器与NAS的通讯情况,选择最优的服务器解析到”nas.xxx.com”域名,若配置的服务器均无法访问,解析至 Cloudflare Tunnel 确保基本的连接保障,只要NAS有网既可以访问,NAS 到内部的应用使用了 nginx 进行反代理,为了配置证书及统一接口。
graph LR A[User] -- 访问 --> B{nas.xxx.com}; B --> C(DDNS); C -- tcping-port --> D[Service1<br>Service2<br>more]; D -- 择优 --> E((解析)); E -- Service* IP Address --> B; B -- FRP --> F[Service*] -- FRP NAT --> G[NAS] -- Nginx Proxy --> H[APP]; B -- Cloudflare Tunnel --> F2[Cloudflare Service] -- Tunnel --> G2[NAS] -- Nginx Proxy --> H2[APP];

创建 Cloudflare Tunnel

登录 Cloudflare 的 Zero Trust 控制面板,在左侧导航栏的 access 选择 tunnels,创建一个隧道名称随意,创建后会提供官方安装方案,将隧道程序安装到NAS主机。
notion image
配置好后端地址,此时 Cloudflare 会创建一条解析记录,cname 到 Connector ID。
notion image
安装完成后保留好 Connector ID 以备后用
notion image

配置中转服务器

在中转服务器安装 FRP 服务端,安装方法参考官方文档。
frp/README_zh.md at dev · fatedier/frp
frp 是一个专注于内网穿透的高性能的反向代理应用,支持 TCP、UDP、HTTP、HTTPS 等多种协议。可以将内网服务以安全、便捷的方式通过具有公网 IP 节点的中转暴露到公网。 通过在具有公网 IP 的节点上部署 frp 服务端,可以轻松地将内网服务穿透到公网,同时提供诸多专业的功能特性,这包括: 客户端服务端通信支持 TCP、KCP 以及 Websocket 等多种协议。 采用 TCP 连接流式复用,在单个连接间承载更多请求,节省连接建立时间。 代理组间的负载均衡。 端口复用,多个服务通过同一个服务端端口暴露。 多个原生支持的客户端插件(静态文件查看,HTTP、SOCK5 代理等),便于独立使用 frp 客户端完成某些工作。 高度扩展性的服务端插件系统,方便结合自身需求进行功能扩展。 服务端和客户端 UI 页面。 frp 目前已被很多公司广泛用于测试、生产环境。 master 分支用于发布稳定版本,dev 分支用于开发,您可以尝试下载最新的 release 版本进行测试。 我们正在进行 v2 大版本的开发,将会尝试在各个方面进行重构和升级,且不会与 v1 版本进行兼容,预计会持续一段时间。 现在的 v0 版本将会在合适的时间切换为 v1 版本并且保证兼容性,后续只做 bug 修复和优化,不再进行大的功能性更新。 完整文档已经迁移至 https://gofrp.org 。 frp 是一个免费且开源的项目,我们欢迎任何人为其开发和进步贡献力量。 在使用过程中出现任何问题,可以通过 issues 来反馈。 Bug 的修复可以直接提交 Pull Request 到 dev 分支。 如果是增加新的功能特性,请先创建一个 issue 并做简单描述以及大致的实现方法,提议被采纳后,就可以创建一个实现新特性的 Pull Request。 欢迎对说明文档做出改善,帮助更多的人使用 frp,特别是英文文档。 贡献代码请提交 PR 至 dev 分支,master 分支仅用于发布稳定可用版本。 如果你有任何其他方面的问题或合作,欢迎发送邮件至 fatedier@gmail.com 。 提醒:和项目相关的问题最好在 issues 中反馈,这样方便其他有类似问题的人可以快速查找解决方法,并且也避免了我们重复回答一些问题。 如果您觉得 frp 对你有帮助,欢迎给予我们一定的捐助来维持项目的长期发展。 您可以通过 GitHub Sponsors 赞助我们。 企业赞助者可以将贵公司的 Logo 以及链接放置在项目 README 文件中。 如果您想学习 frp 相关的知识和技术,或者寻求任何帮助及咨询,都可以通过微信扫描下方的二维码付费加入知识星球的官方社群:
frp/README_zh.md at dev · fatedier/frp
配置文件参考:
#Frp作为中间件使用 [common] bind_addr = 0.0.0.0 bind_port = 7000 kcp_bind_port = 7000 token = xxxxxxxxxxxxxxxxxxx #接受未启用TLS的客户端连接 tls_only = false # console or real logFile path like ./frpc.log #log_file = /dev/null # trace, debug, info, warn, error log_level = error log_max_days = 3
💡
高级玩法:实际使用中发现,如果是安装在家宽并单独使用 FRP 进行 NAT 一段时间后运营商会有一定几率封端口,建议使用伪装工具对 FRP 流量进行隐藏保安全。

NAS 安装 Nginx

在 NAS 上使用 Nginx 对内部服务进行反代理,这样的目的是为了统一接口和配置域名证书,具体配置方案网上找找吧,这个都是因人而异,网上也很多关于nginx反代理的教程,这里提供我其中反代 NAS 页面的参考
Tips:Nginx 可不止能反代理 WEB 哦。
需要注意:FRP 客户端若开启了 Proxy Protocol ,nginx 也要开启 Proxy Protocol 协议。
server { listen nginx:2096 ssl proxy_protocol; server_name nas.xxx.com; index index.html; root /etc/nginx/web/default/; access_log /LogFile/log/proxy_myqnap_access.log; error_log /LogFile/log/proxy_myqnap_error.log error; #SSL-START SSL相关配置 ssl_certificate /acme.sh/*.xxx.com//fullchain.cer; ssl_certificate_key /acme.sh/*.xxx.com/*.xxx.com.key; ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE; ssl_prefer_server_ciphers on; ssl_session_cache shared:SSL:10m; ssl_session_timeout 10m; error_page 497 https://$host$request_uri; #SSL-END #ERROR-PAGE-START 错误页配置 #error_page 404 /404.html; #error_page 502 /502.html; #ERROR-PAGE-END #禁止访问的文件或目录 location ^~ /\.env { return 403; break; } location ~ ^/(\.user.ini|\.htaccess|\.git|\.svn|\.conf|\.yml|\.pem|\.key|\.bak|\.types|\.project|LICENSE|README.md) { return 403; break; } #QnapWEB location / { proxy_pass https://qnap:2021; #持久化连接 proxy_connect_timeout 30s; proxy_read_timeout 86400s; proxy_send_timeout 30s; #WebSocket proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; #proxy protocol include proxy_header_proxy_protocol.conf; } # 禁止爬虫访问 if ($http_user_agent ~* "qihoobot|Baiduspider|Googlebot|Googlebot-Mobile|Googlebot-Image|Mediapartners-Google|Adsbot-Google|Feedfetcher-Google|Yahoo! Slurp|Yahoo! Slurp China|YoudaoBot|Sosospider|Sogou spider|Sogou web spider|MSNBot|ia_archiver|Tomato Bot") { return 403; } location =/robots.txt { default_type text/html; return 200 "User-Agent: *\nDisallow: /"; log_not_found off;access_log off; access_log /dev/null;error_log /dev/null; } #favicon不生成日志 location =/favicon.ico { log_not_found off;access_log off; access_log /dev/null;error_log /dev/null; } }

NAS 安装 FRP

NAS 上需要安装 FRP 客户端,配置了多少个服务器就需要安装多少个客户端(推荐使用Docker)。
配置文件参考:
[common] server_addr = 1.1.1.1(服务器地址) server_port = 7000 token = xxxxxxxxxxxxxxxxxxx # KCP protocol = tcp # if tls_enable is true, frpc will connect frps by tls # 启用此功能后除 xtcp 外,可以不用再设置 use_encryption 重复加密 tls_enable = true # console or real logFile path like ./frpc.log #log_file = /etc/frp/log/frpc-rt-home.log # trace, debug, info, warn, error log_level = error log_max_days = 3 #NAS网页管理反代理隧道(Docker) [TCP_NASWEB_HTTPS] type = tcp local_ip = nginx #nginx的NAS内部地址 local_port = 2096 #nginx端口 remote_port = 2096 #服务器端口 use_encryption = false use_compression = false #Proxy Protocol 协议 proxy_protocol_version = v2

NAS 安装 DDNS

程序由 NewFuture/DDNS 的源码二次开发,主要实现的作用是测试中转服务器的可用性,选择延迟最低的更新解析到指定域名,从域名解析层实现故障切换,如果配置的中转服务器均无法使用解析到 Cloudflare Tunnel ,由于 Cloudflare 有端口限制除了固定的端口外,其他端口是无法访问的。这就是为什么要用 Nginx 进行反代理统一接口的原因之一。
配置说明:
{ "dns": "cloudflare", "id": "", "index4": "default", "index6": "default", "ipv4": "nas.xxx.com", #域名 "ipv6": "nas.xxx.com", #域名 "proxy": null, "token": "cloudflare API", #Cloudflare API "ttl": 60, "port": 2096, "pings": 3, "tunnelscname": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.cfargotunnel.com", #Connector ID "backser": "FRP服务器地址或域名", #备用服务器 "addresslis4": [ { "name": "FRP服务器地址或域名1" #常用服务器1 }, { "name": "FRP服务器地址或域名2" #常用服务器2 } ], "addresslis6": [ { "name": "FRP服务器地址或域名1" }, { "name": "FRP服务器地址或域名2" } ] }
具体安装及使用方法可参考官方教程:https://github.com/NewFuture/DDNS/blob/master/README.md
二次开发(本文使用)

实际效果

DDNS 服务解析更新地址的记录
notion image
实际维护了两条中转隧道,家用公网做主用、服务器备用,CloudFlared 保底备用。
notion image

更新计划

提供 Docker 配置模板
兼容本地公网
Docker 按需启动
 
💡
未尽事宜欢迎留言沟通
 
我的博客即将同步至腾讯云开发者社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=5xncd90e99vl
技术分享
  • NAS
  • DDNS
  • Python
  • WP插件CodeColorer兼容PHP7Linux防火墙管理脚本,自动屏蔽网络威胁IP
    Catalog