歲月留聲

群晖 NAS 公网 IP 使用 DDNS 自定义域名 HTTPS 外网访问

群晖 DSM 6.2.3-25426 Update 2 默认并支持 20+ DDNS 服务,比如 DNSPod.cn、DNSPod.com 和花生壳等 DDNS 服务,群晖 NAS 使用 DNSPod.cn DDNS 即可实现自定义域名外网 HTTPS 访问群晖 NAS 外网访问。

「群晖 NAS 公网 IP 使用 DDNS 自定义域名 HTTPS 外网访问:https://0xo.net/87」

群晖 NAS 公网 IP 使用 DDNS 自定义域名 HTTPS 外网访问 - 第1张图片

前言 - 为什么不直接使用 QuickConnect?

博主 2020 年 7 月底,蜗牛星际 D 款安装了群晖 DS3617xs DSM 6.2.3-25426 Update 2,一直使用 Cloud Sync 套件备份 OneDrive 的 Google Photos 数据,后来还使用 Hyper Backup 实现本地文件夹间增量复制文件备份。

黑裙,以前淘宝花点小钱洗白即可直接使用 QuickConnect(QC),后来中国区需要绑定手机才可以使用,现在可能更不容易折腾了吧?再者,如果宽带能拿到公网 IP,使用 DDNS 访问速度会好很多,基本上能跑满宽带上行。

「群晖 NAS 公网 IP 使用 DDNS 自定义域名 HTTPS 外网访问:https://0xo.net/87」

山旮旯地方,目前电信宽带还能报障申请到公网 IP。博主是 2021 年申请到的,过程挺顺利,报障申请到拿到公网 IP 也就半个小时左右。

宽带拿到公网 IP 有什么用处?——群晖脱离 QuickConnect 实现外网访问;Windows 远程桌面连接(RDP);外网访问家里监控;建站……(当然,这些服务没有公网 IP 也可以使用 frp 等工具实现,不过有公网 IP 速度会更好)

题外话,这个升级款矿渣蜗牛星际稳定性也还行,安装群晖后稳定运行 2 年多,除了折腾或者断电重启,一直 24 小时运行,不过没跑什么任务,主要就 Cloud Sync 备份相片数据。

「群晖 NAS 公网 IP 使用 DDNS 自定义域名 HTTPS 外网访问:https://0xo.net/87」

群晖(Synology)NAS 启用 DNSPod DDNS

群晖 6.2.3 默认并支持 20+ DDNS 服务:

群晖 NAS 公网 IP 使用 DDNS 自定义域名 HTTPS 外网访问 - 第2张图片

前提:得有一个域名,因为这里使用 DNSPod,直接在 DNSPod 购买域名更方便,不过得实名认证

「群晖 NAS 公网 IP 使用 DDNS 自定义域名 HTTPS 外网访问:https://0xo.net/87」

参考资料:DNSPod DDNS 官方文档

在拥有公网 IP 地址的情况下,群晖(Synology)NAS 使用 DNSPod 启用 DDNS(动态域名服务)后,就可以在外使用购买的自定义域名访问家中的群晖(Synology)NAS。域名需要付费购买,启用 DDNS 服务免费

前提条件

启用 DDNS - DNSPod 域名解析、创建密钥

在「我的域名」管理页面,单击用作连接群晖的域名,进入【记录管理】页面。

【添加记录】,添加一条主机记录为 www 或者 @,记录值为 0.0.0.0 的 A 记录,如下图:

群晖 NAS 公网 IP 使用 DDNS 自定义域名 HTTPS 外网访问 - 第3张图片

进入「密钥管理」页面,单击【创建密钥】,输入自定义的密钥名称后并单击【确定】。如下图:

群晖 NAS 公网 IP 使用 DDNS 自定义域名 HTTPS 外网访问 - 第4张图片

请妥善保管对话框中的 ID 与 Token。

启用 DDNS - 群晖 NAS 外部访问配置

需要使用管理员权限账号登录群晖(Synology)NAS,菜单:【控制面板】>【外部访问】>【DDNS】>【新增】,在弹出的对话框中,【服务供应商】下拉选择【DNSPod.cn】,并填写相关信息。如下图:

主机名称:填写前面购买、配置好的域名。
用户名/电子邮箱:填写前面生成密钥获取到的 DNSPod ID。
密码/密钥:填写前面获取到的密钥。

群晖 NAS 公网 IP 使用 DDNS 自定义域名 HTTPS 外网访问 - 第5张图片

单击【确定】,【立即更新】,确认状态栏显示正常,并且获取到正确公网 IP 即可:

群晖 NAS 公网 IP 使用 DDNS 自定义域名 HTTPS 外网访问 - 第6张图片

如无意外,这时候返回「我的域名」管理页面,域名解析记录已变更为公网 IP 地址。如未变更,按前面配置步骤检查一遍。

群晖 NAS 公网 IP 使用 DDNS 自定义域名 HTTPS 外网访问 - 第7张图片

群晖 自定义 域名+免费证书 实现 HTTPS 访问

主要操作:申请免费证书、导入证书、配置证书、端口配置和映射……

申请免费证书

DSM 6.2.3-25426 Update 2 内置 Let’s Encrypt,不过试了很多次都没有申请成功,可以到腾讯云申请一个免费一年证书,到期后再申请更新即可。

群晖导入免费证书

群晖,「控制面板」-「安全性」-「证书」-「添加新证书」

群晖 NAS 公网 IP 使用 DDNS 自定义域名 HTTPS 外网访问 - 第8张图片

创建证书 - 选择动作

描述随便填,选择「导入证书」,勾选「设为默认证书」

群晖 NAS 公网 IP 使用 DDNS 自定义域名 HTTPS 外网访问 - 第9张图片

导入证书文件

腾讯云申请到免费 SSL 证书,下载会得到一个 zip 压缩包,解压,取 Apache 文件夹里面三个文件使用。其中 1_root_bundle.crt 为中间证书;2_域名.crt 为证书;3_域名.key 为私钥。

群晖 NAS 公网 IP 使用 DDNS 自定义域名 HTTPS 外网访问 - 第10张图片

选择使用新证书

群晖服务可能还是在使用旧的默认证书,选中刚才添加的新证书,点击配置,群晖服务按需要选择启用新证书即可。

群晖 NAS 公网 IP 使用 DDNS 自定义域名 HTTPS 外网访问 - 第11张图片

群晖 DSM 端口配置

「控制面板」-「网络」-「DSM 设置」,不要使用默认端口可能会更安全,可以勾上 HTTP 自动重定向到 HTTPS,HTTP/2 也启用吧。

群晖 NAS 公网 IP 使用 DDNS 自定义域名 HTTPS 外网访问 - 第12张图片

还有一个地方可以配置端口,「控制面板」-「外部访问」-「高级设置」:

群晖 NAS 公网 IP 使用 DDNS 自定义域名 HTTPS 外网访问 - 第13张图片

一般填上域名即可,如果前面网络端口没有修改,也可以直接在这里修改。

路由器端口映射

不同路由器这个功能叫法可能有点不同,虚拟服务、虚拟主机、端口映射……下面是参考配置:

群晖 NAS 公网 IP 使用 DDNS 自定义域名 HTTPS 外网访问 - 第14张图片

如无意外,配置到这里,已经可以使用 https://域名: 端口号(比如:https://nas.com:1028)访问群晖 NAS 了。如不行,按照前面配置步骤检查。

另外,如果使用旁路由,可能也需要配置转发:

群晖 NAS 公网 IP 使用 DDNS 自定义域名 HTTPS 外网访问 - 第15张图片

群晖自定义域名如何实现自动切换内外网?

QuickConnect 除了可以让群晖 NAS 无需公网 IP 也能够在外网访问外,还有一个很实用的功能:自定识别内外网——也就是使用同一个地址,既可外网访问群晖 NAS,也可以内网访问群晖 NAS 资源时无需绕外网一圈再回来。

群晖自定义域名访问也可以实现自动切换内外网,稍稍配置一下路由器即可,原理是:DNS 劫持

网上找到一个方法是:群晖使用 DNS Server 套件,架设一个 DNS Server 服务器,路由器首选群晖架设这个 DNS Server,DNS 劫持自定义网址到群晖内网地址,完整资料在此下载

博主在用 N1 旁路由,主要设备都使用 N1 作网关和 DNS,N1 旁路由为 OpenWRT 系统,自带「自定义挟持域名」功能,「网络」-「DHCP/DNS」-「自定义挟持域名」添加配置即可,参考配置如下:

群晖 NAS 公网 IP 使用 DDNS 自定义域名 HTTPS 外网访问 - 第16张图片

按理,若主路由是 OpenWRT 系统也可以按此方法配置。

后记:换用 Cloudflare DDNS 服务

后记:轻度使用,没什么问题,只是偶尔连接不上,以为是网络抽风。后来换用 Cloudflare DDNS 服务,就算 TTL 设置成一分钟也没用,才发现是 DNS 缓存问题,DDNS 可以及时更新公网 IP,但是 DNS 生效就难保证了,无解

记录一下群晖 NAS 添加 Cloudflare DDNS 动态域名解析服务配置方法。

shell 脚本版:https://github.com/joshuaavalon/SynologyCloudflareDDNS

php 版本:https://github.com/mrikirill/SynologyDDNSCloudflareMultidomain

参考教程:群晖 NAS 网络服务 - 原生 DDNS 部署配置 Cloudflare DDNS 动态域名解析(shell 脚本版)

脚本备份下载:SynologyCloudflareDDNS-20220813

博主目前在用 shell 脚本版,下面简单记录一下使用方法。

Cloudflare 获取域名区域 ID 以及 API 令牌

登录 Cloudflare,点击需要用作 DDNS 的域名,「概述」API 信息记录该域名「区域 ID」备用:

群晖 NAS 公网 IP 使用 DDNS 自定义域名 HTTPS 外网访问 - 第17张图片

接着点击「区域 ID」下下方「获取您的 API 令牌」,进入「API 令牌」页面,「创建令牌」或者编辑现有令牌:

群晖 NAS 公网 IP 使用 DDNS 自定义域名 HTTPS 外网访问 - 第18张图片

「创建令牌」可以选用「编辑区域 DNS」模板,然后修改即可,下面是令牌权限参考:

群晖 NAS 公网 IP 使用 DDNS 自定义域名 HTTPS 外网访问 - 第19张图片

一般开放用作 DDNS 的域名区域编辑 DNS 权限即可。编辑完成点击确认「创建令牌」即可:

群晖 NAS 公网 IP 使用 DDNS 自定义域名 HTTPS 外网访问 - 第20张图片

记得复制令牌保存备用。

配置群晖原生 DDNS 添加 Cloudflare 支持

群晖原生 DDNS 支持 20+ 服务商,但是并不支持 Cloudflare,通过 joshuaavalon/SynologyCloudflareDDNS 项目提供的脚本和方案, 可以将 Cloudflare 添加到原生 DDNS 列表中。

1、ssh 登陆群晖 NAS 终端「控制面板 - 终端机和 SNMP - 勾选启用 SSH 功能」,登录成功执行 sudo -i 切换为 root 帐户。

2、下载并修改 Cloudflare DDNS 脚本:将 proxy="true" 修改为 proxy="false" 避免被 Cloudflare CDN 代理;还可以增加指定 ttl 选项,详细介绍见 Cloudflare API 官方文档

群晖 NAS 公网 IP 使用 DDNS 自定义域名 HTTPS 外网访问 - 第21张图片

ttl 最小可以指定为 60(1 分钟),下面是博主在用 cloudflareddns.sh 代码,可以参考一下:

#!/bin/bash
set -e;

ipv4Regex="((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])"

proxy="false"
ttl="60"

# DSM Config
username="$1"
password="$2"
hostname="$3"
ipAddr="$4"

if [[ $ipAddr =~ $ipv4Regex ]]; then
recordType="A";
else
recordType="AAAA";
fi

listDnsApi="https://api.cloudflare.com/client/v4/zones/${username}/dns_records?type=${recordType}&name=${hostname}"
createDnsApi="https://api.cloudflare.com/client/v4/zones/${username}/dns_records"

res=$(curl -s -X GET "$listDnsApi" -H "Authorization: Bearer $password" -H "Content-Type:application/json")
resSuccess=$(echo "$res" | jq -r ".success")

if [[ $resSuccess != "true" ]]; then
echo "badauth";
exit 1;
fi

recordId=$(echo "$res" | jq -r ".result[0].id")
recordIp=$(echo "$res" | jq -r ".result[0].content")

if [[ $recordIp = "$ipAddr" ]]; then
echo "nochg";
exit 0;
fi

if [[ $recordId = "null" ]]; then
# Record not exists
res=$(curl -s -X POST "$createDnsApi" -H "Authorization: Bearer $password" -H "Content-Type:application/json" --data "{\"type\":\"$recordType\",\"name\":\"$hostname\",\"content\":\"$ipAddr\",\"proxied\":$proxy,\"ttl\":$ttl}")
else
# Record exists
updateDnsApi="https://api.cloudflare.com/client/v4/zones/${username}/dns_records/${recordId}";
res=$(curl -s -X PUT "$updateDnsApi" -H "Authorization: Bearer $password" -H "Content-Type:application/json" --data "{\"type\":\"$recordType\",\"name\":\"$hostname\",\"content\":\"$ipAddr\",\"proxied\":$proxy,\"ttl\":$ttl}")
fi

resSuccess=$(echo "$res" | jq -r ".success")

if [[ $resSuccess = "true" ]]; then
echo "good";
else
echo "badauth";
fi

修改好 cloudflareddns.sh 脚本,上传至 /sbin/ 目录下,并执行下面命令赋予执行权限:

chmod +x /sbin/cloudflareddns.sh

接着复制粘贴以下命令并执行:

cat >> /etc.defaults/ddns_provider.conf << EOF
[Cloudflare]
modulepath=/sbin/cloudflareddns.sh
queryurl=https://www.cloudflare.com
website=https://www.cloudflare.com
EOF

登录群晖使用 Cloudflare 开启 DDNS 服务

登陆群晖 DSM - 控制面板 - 外部访问 - DDNS - 新增或者编辑。

服务供应商 - 选择 Cloudflare
主机名称 - 填写 DDNS 域名
用户名 - 填写域名区域 ID
密码 - 填写前面生成的 API 令牌

群晖 NAS 公网 IP 使用 DDNS 自定义域名 HTTPS 外网访问 - 第22张图片

填写好相关配置,点击「测试联机」,状态正常即可。还可以点击「立即更新」即可更新 IP 变动。

至此,群晖已经可以正常使用 Cloudflare DDNS 服务。

DDNS 服务 DNS 生效慢如何解决?

前面提到,群晖 + Cloudflare DDNS 服务几乎可以实现更新本地网络公网 IP 变动到域名解析,但是 DNS 解析生效时间确无法控制。

删除/修改记录解析多久可以生效?

理论答案:解析生效时间取决于本地 DNS 缓存解析记录 TTL 到期时间,一般默认为 10 分钟。例如解析记录设置的 TTL 值为 10 分钟,则理论上全球解析生效时间需要 10 分钟;解析记录设置的 TTL 值为 60 秒,则理论上全球解析生效时间需要 60 秒。

但是实测 Cloudflare 将 TTL 设置为 60 秒,生效时间也不可控,本地清缓存,刷新再刷新,浏览器清缓存,可能还是无法刷出新解析记录。

那么 DNS 生效慢有办法解决吗?

网上说 DDNS 动态域名生效慢可以使用 TXT 域名解决,不过,一般人可能用不上。还有人说搞一台 VPS 接收路由器发送 ip 变化,然后 nginx 反代……

前几天试着套一个 cname,解析好像基本上可以实时生效了。

具体方法举例:DDNS 服务更新 ip 到 ddns.test.com 子域名,ttl:一分钟;群晖使用 dsm.test.com 子域名,dsm.test.com CNAME 解析到 ddns.test.com,ttl:一分钟。

有需要不妨试试。

退出移动版