zerotier 组网+moon+dns服务器
zerotier搭建虚拟局域网
整体可以分成三步:
-
zerotier创建网络,各个客户端加入网络。软件下载:Download - ZeroTier
-
国内公网服务器,搭建moon节点。
-
搭建dns服务器(zeronsd)
⚠但是国内的云服务器默认封禁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服务器,然后加上自定义配置实现。
nas上部署zeronsd
参考文献:
在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 <ZEROTIER_CENTRAL_TOKEN> > /var/lib/zerotier-one/token"
。可以参考搭建dns服务器(zeronsd) -
容器添加环境变量:``
-
ZEROTIER_CENTRAL_TOKEN
: 值是申请的token;这一步可能和将token写入文件重复了。不过我没有验证少了这一步能否成功。
-
-
容器启动命令:
start --domain <域名后缀> -s /var/lib/zerotier-one/authtoken.secret -t /var/lib/zerotier-one/token <network id>
✏ dns服务器默认使用53端口,如果dns服务器无法访问,需要检查对应端口是否打开。(nas上默认好像是开的,我部署完就能直接用)
如此就部署完成了,各个客户端打开allow dns
选项后,就可以通过域名访问自己的服务器了。
- window: 通过GUI界面操作
- linux:
zerotier-cli set <network-id> allowDNS=1
- 安卓:默认启用,如果想加入mood节点必须使用第三方的客户端kaaass/ZerotierFix
window电脑设置dns服务器
通常软件打开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其他服务器
上述服务部署完成后,发现无法在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
如果希望某个docker 容器使用我们的dns 服务器,同时又不希望从头开始配置容器。
可以选择先修改nas的/etc/resolv.conf
,然后将容器重置(确保你的个人数据都已经映射到nas本地,避免数据损失)。
在没有显示指定dns的时候,容器会默认使用主机的dns配置,于是我们就间接完成了对容器的dns配置。
linux设置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
使用smartdns搭建dns服务器代替zeronsd
首先申请api-token:ZeroTier Central
然后设置下面代码中参数:
-
token
:是上面申请的api-token -
networkId
:是你的Network ID -
domainSuffix
:是自定义域名后缀
执行代码生成smartdns需要的配置文件,然后启动smartdns。smartdns的安装请参考官方教程:SmartDNS。
可以实现类似官方zeronsd的效果:<Name>.<domainSuffix>
。
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")
各个客户端分别设置smart服务器
-
window:要在zerotier的网络适配器上手动设置dns为smartdns服务器的IP网址
-
linux:
- 若未启用systemd,修改
/etc/resolv.conf
- 若启用systemd,修改
/etc/systemd/resolved.conf
,然后重启服务systemctl restart systemd-resolved
。
- 若未启用systemd,修改