整体可以分成三步:
zerotier创建网络,各个客户端加入网络。软件下载:Download - ZeroTier
国内公网服务器,搭建moon节点。
教程:打洞不成功?来试试 ZeroTier 自建 Moon 中转吧~ | Lufs's Blog
搭建dns服务器(zeronsd)
教程:ZeroTier组网:使用zeronsd作为其私有网段DNS_软件应用_什么值得买
教程:ZeroTier的私有DNS服务器ZeroNSD搭建引导 - Halcyon Zone
⚠但是国内的云服务器默认封禁53端口,即使你在防火墙中打开53端口也不行。所以zeronsd不能安装在云服务器上。
⚠moon服务器需要各个客户端都能访问到才行,所有moon节点必须搭建在具有公网ip的服务器上。
⚠zeronsd需要部署在zerotier的节点服务器上,因为这样才能通过zerotier的网络访问dns服务器。
综上所述推荐在云服务器上部署moon节点,在自己的nas上部署zeronsd服务器。
经过一段时间的使用,发现官方的zeronsd并不好用。首先截止到1.14.1版本,zeronsd并没有实现linux和mac上dns服务器的开箱即用。
官方文档上也说明了这点:DNS | ZeroTier Documentation。部署zeronsd,在客户端上打开
allowDNS=1
后,还需要自己额外设置dns服务器地址。window上通过NRPT实现了开箱即用。但即使这样操作后,官方的zetonsd不支持递归dns解析,在部分linux系统中会遇到报错(如DEEPIN 23系统)。
所以不建议部署官方的zeronsd实现dns解析,推荐使用第三方工具搭建dns服务器,然后加上自定义配置实现。
参考文献:
- zerotier/zeronsd: A DNS server for ZeroTier users
- How to set up in docker compose? · Issue #230 · zerotier/zeronsd
- 群晖异地组网-ZeroTier搭建使用指南(全平台异地组网)_NAS存储_什么值得买
在nas上首选通过docker部署,这样管理和更新起来都很方便。但是网上关于docker安装zeronsd的教程很少,我参考一些文章,经过一番摸索部署成功。
☛前提1:已经在docker上部署了zerotier节点,可以参考教程:群晖异地组网-ZeroTier搭建使用指南(全平台异地组网)_NAS存储_什么值得买
官方提供了用于docker部署的镜像和命令行:
docker run --net host -it \
-v /var/lib/zerotier-one/authtoken.secret:/authtoken.secret \
-v <token file>:/token.txt \
zeronsd:alpine start -s /authtoken.secret -t /token.txt \
<network id>
官方提供的镜像关键字zeronsd可以搜到,但直接照抄命令行,是无法部署成功的。我采用GUI界面的方式部署,主要注意下面几点:
文件夹映射,在nas上将部署zerotier-one容器时用到的文件夹映射到容器的/var/lib/zerotier-one
目录,目的是让两个容器的/var/lib/zerotier-one
目录内容相同。
申请api token,并将token写入容器的目录echo
。可以参考搭建dns服务器(zeronsd)
容器添加环境变量:``
ZEROTIER_CENTRAL_TOKEN
: 值是申请的token;这一步可能和将token写入文件重复了。不过我没有验证少了这一步能否成功。容器启动命令:start --domain <域名后缀> -s /var/lib/zerotier-one/authtoken.secret -t /var/lib/zerotier-one/token
✏ dns服务器默认使用53端口,如果dns服务器无法访问,需要检查对应端口是否打开。(nas上默认好像是开的,我部署完就能直接用)
如此就部署完成了,各个客户端打开allow dns
选项后,就可以通过域名访问自己的服务器了。
zerotier-cli set allowDNS=1
通常软件打开allow DNS
选项后,即可通过Windows nrtp(Name Resolution Policy Table 域名解析策略表)正常工作。
window可以通过Get-DnsClientNrptPolicy -Effective
(需要管理员权限)命令查看dns的信息。如果输出空白就说明dns没有生效。正确的输出如下:
Namespace : .fbh
QueryPolicy : QueryIPv6Only
SecureNameQueryFallback : FallbackPrivate
DirectAccessIPsecCARestriction :
DirectAccessProxyName :
DirectAccessDnsServers :
DirectAccessEnabled : False
DirectAccessProxyType :
DirectAccessQueryIPsecEncryption :
DirectAccessQueryIPsecRequired :
NameServers : 192.168.193.7
DnsSecIPsecCARestriction :
DnsSecQueryIPsecEncryption :
DnsSecQueryIPsecRequired :
DnsSecValidationRequired :
NameEncoding :
上述服务部署完成后,发现无法在nas上ping 其他服务器的域名,但是ping ip可以。这是因为zeronsd在linux上做不到开箱即用,还需要手动配置dns服务器。
查看nas的/etc/resolv.conf
,发现只有默认的dns服务器只有路由器192.168.3.1
。
ash-4.4# cat /etc/resolv.conf
nameserver 192.168.3.1
nameserver 192.168.3.1
修改一下,将nas的zerotier的地址添加上去
ash-4.4# cat /etc/resolv.conf
nameserver 192.168.193.7
nameserver 192.168.3.1
这样就会首先通过zerotier服务器解析域名,同时又不影响其他域名的解析。
✎这里如果将nas的地址192.168.193.7
放在第二行,是无效的, 必须放在第一行。
ash-4.4# nslookup gs.fbh
Server: 192.168.193.7
Address: 192.168.193.7#53
Name: gs.fbh
Address: 192.168.193.101
如果希望某个docker 容器使用我们的dns 服务器,同时又不希望从头开始配置容器。
可以选择先修改nas的/etc/resolv.conf
,然后将容器重置(确保你的个人数据都已经映射到nas本地,避免数据损失)。
在没有显示指定dns的时候,容器会默认使用主机的dns配置,于是我们就间接完成了对容器的dns配置。
ubuntu22.04使用systemd管理dns,不能直接修改/etc/resolv.conf
。
这个文件是个软链接,被systemd管理,修改后也会自动更新。
修改dns配置: vim /etc/systemd/resolved.conf
[Resolve]
DNS=192.168.193.7
重启服务
systemctl restart systemd-resolved
查看dns服务已经生效
cat /run/systemd/resolve/resolv.conf
首先申请api-token:ZeroTier Central
然后设置下面代码中参数:
token
:是上面申请的api-tokennetworkId
:是你的Network IDdomainSuffix
:是自定义域名后缀执行代码生成smartdns需要的配置文件,然后启动smartdns。smartdns的安装请参考官方教程:SmartDNS。
可以实现类似官方zeronsd的效果:
。
import requests
import json
token = 'xxxx'
networkId = 'xxxx'
domainSuffix = 'xxxx'
headers={
'Authorization': f"token {token}"
}
url=f"https://api.zerotier.com/api/v1/network/{networkId}/member"
param = {}
response = requests.get(url=url,params=param,headers=headers) #三个参数
memberData = json.loads(response.text)
with open("smartdns.conf", '+w') as f:
f.write(f"bind [::]:53\n")
# 谷歌
f.write(f"server 8.8.8.8\n")
f.write(f"server 8.8.4.4\n")
# cloudflare
f.write(f"server 1.1.1.1\n")
f.write(f"server 1.0.0.1\n")
# 114
f.write(f"server 114.114.114.114\n")
# baidu
f.write(f"server 180.76.76.76\n")
# 腾讯
f.write(f"server 119.29.29.29\n")
f.write(f"server 119.28.28.28\n")
# 阿里
f.write(f"server 223.5.5.5\n")
f.write(f"server 223.6.6.6\n")
# 字节
f.write(f"server 180.184.1.1\n")
f.write(f"server 180.184.2.2\n")
for i in memberData:
config=i['config']
print(f"id: {config['id']};\tname: {i['name']};\tdescription: {i['description']};\tip: {config['ipAssignments']}")
f.write(f"address /{i['name']}.{domainSuffix}/{','.join(config['ipAssignments'])}\n")
window:要在zerotier的网络适配器上手动设置dns为smartdns服务器的IP网址
linux:
/etc/resolv.conf
/etc/systemd/resolved.conf
,然后重启服务systemctl restart systemd-resolved
。