(网络) 利用 ZeroTier 将既有私网改造成 SDN(SD-WAN) 的实践

作者: iEdon 分类: 文章列表 发布时间: 2019-12-03 15:00

背景

笔者经常在闲时研究网络交换技术。在一年的研究和学习后,笔者自己建立了一个私有网络架构。这个网络将家,学校,公司进行互联,网络上部署了 LDAP,简易 Web Portal 认证,统一 DHCP 服务器,网内 DNS 服务,以及笔者一些小程序微服务等等,更与 DN×× 实验网络爱好者进行对接,笔者在任意地区只要接入网络都能访问网内的任意服务,就好像在现场一样,非常方便。

  1. 目前核心网络使用的技术是 OpenV×N,AES-128 加密,SHA256 密钥交换,网络在 DDNS 的情况下使用良好。
  2. “核心路由”为家里服务器上面的 OpenWRT 虚拟机,直通 3 块物理网卡(一网卡接电信宽带,一网卡接移动宽带,一网卡接家里局域网),核心路由上还有3个虚拟接口,另外还有一个 V×N 传入接口,接收外网传入的 V×N 连接。
  3. 笔者在 DN×× 上申请了实验 AS 号以及实验用 IPv4(一个 /25,一个 /26) 及 IPv6 网段(一个 /48)。
  4. 核心路由在 3 个虚拟接口接口及传入接口上运行 OSPF,OSPFv6,BGP 这些路由协议,用以交换私有路由表及整个 DN×× 路由表。

笔者私有网络在 DN×× 全网上的 BGP 互联情况:(欢迎联系我 peer!)

现有网段分配示意图:

支持多节点的 Web 认证服务(由于笔者的实验网络在学校有多个接入节点,并且与一些朋友进行了共享,因此研究了一下简易的 Portal 认证系统。具体可以参考笔者 2017 年发布的文章):

遇到了什么问题

  1. (现有方案其实并不是不能用,目前方案能用而且还相对稳定。)
  2. 现有的 OpenV×N 方案是传统网络架构,服务端不能动态调整客户端所获得的 IP 地址,也不能(或者说没有成熟的,简单易行的方法)在服务端动态增删改路由表的推送。
  3. 现有方案对客户端验证较为麻烦,使用的是证书机制。在笔者进行网络大规模(多节点)部署的情况下,在很多路由器设备使用同一证书,反而大大降低了安全性。任何人只要得到笔者的配置文件,就能接入网络,访问网内资源。因此这是一颗悬在笔者头上的达摩克里斯之剑。ZeroTier 提供可视化的授权服务
  4. 现有方案依赖公网地址,依赖内网穿透(如果你没有公网地址的话),部署不灵活,而且会遇到 DDNS 更新 IP 的瞬时闪断,体验不是最佳。
  5. 现有方案不便于分享,ZeroTier 网络只需要像 TeamViewer 一样,共享一个网络ID,就能接入网络
  6. OpenV×N 的本质是 V×N,所有客户端的数据需要服务器转发,容易出现单点故障,且服务端带宽需要足够高。在公有云上部署(国内带宽非常高),需要非常高的成本。ZeroTier 提供 STUN UDP 打洞服务,点对点的连接优先,如果无法建立连接,才会退化成服务端转发。因此 ZeroTier 的设计能提升性能,降低服务端带宽负载(需要自建 Moon 服务器)。
  7. ZeroTier 提供了默认安全实践,你要做的唯一一件事请就是输入网络ID,只要网络通畅,就能建立安全的连接。无需关心任何底层细节
  8. SDN(软件定义网络) 好高大上啊!嗯!

ZeroTier 服务端部署

ZeroTier 依靠星球系统来完成网络发现,穿透和转发。

在现阶段(1.x),ZeroTier 网络架构分为:官方建立的公共根服务器(行星 PLANET),用户自己建的根(卫星 MOON),用户客户端(叶子节点 LEAF),网络控制器(Controller)

在这样一个架构中,我们的网络由控制器定义和管理,由 MOON / PLANET 负责服务发现,打洞或转发。ZeroTier 官方定义了一个免费的公共控制器,免费的行星,但因为是公共的,而且服务在国外,严重影响国内使用,所以推荐自建控制器与卫星,在极端情况下(你想自己隔离整套系统),你甚至可以修改 ZeroTier 源代码,将自己的卫星定义为行星,自成体系(这样你的网络ID不能被其他 ZeroTier 客户端访问到)。

部署一个卫星(笔者系统为 OpenWRT + Entware):

opkg update
opkg install zerotier

# /opt 为安装好 Entware 后定义的目录
# 非 Entware 的 OpenWRT 系统要注意:原生 OWRT 系统中的 /var 挂载在 /tmp 上,是临时文件系统
# 重启后配置有丢失的风险,所以需要自己重新写脚本进行持久化挂载

cd /opt/var/lib/zerotier-one
zerotier-idtool initmoon identity.public >> moon.json
vi moon.json

# 修改 “stableEndpoints”: [ “你的公网IPx1/端口”,”你的公网IPxN/端口” ]
zerotier-idtool genmoon moon.json

# 由此 MOON 已经配置文成,将 /opt/var/lib/zerotier-one/moons.d/ 下面的 000000MOON网络ID.moon 交付给客户端
# 以便客户端能使用自建的卫星节点
# 客户端也要使用下面这个命令激活选用 MOON
zerotier-cli orbit MOON网络ID MOON网络ID

部署一个控制器:

ZeroTier 官方开源了自己的控制器代码,控制器暴露的操作接口是一个 RESTful API,目前全网仅有 ztncui 这个项目是第三方制作的控制器可视化 UI。

git clone https://github.com/key-networks/ztncui.git
cd ztncui-master/src
npm install
vi .env

# 修改一些必要的参数
ZT_TOKEN=从刚才的MOON中 auth token 中获取
ZT_ADDR=刚才MOON服务器的内网IP:端口
# 允许在所有端口上启用不安全的 HTTP
HTTP_ALL_INTERFACES=yes
# HTTP 监听端口
HTTP_PORT=xxx
# 注意,刚才 MOON 服务器监听的端口,只有 127.0.0.1 上允许使用控制器 API
# 所以需要在刚才的 MOON 服务配置文件下修改或新建一个 local.conf
# 如果 ztncui 与 MOON 在同一服务器上无需此操作,上一步直接填入 127.0.0.1 即可
vi local.conf

{
“settings”: {
“primaryPort”: 9993,
“allowManagementFrom”: [ “127.0.0.1/8”, “允许使用API管理的网段” ]
}
}

npm start

使用自建的控制器进行网络创建/管理:

接下来,只要在客户端输入刚创建的网络的网络ID,客户端就会自动建立连接。地址分配,路由表推送,是否授权访问等等都可以通过控制器进行管理。

因为笔者使用了 OSPF 等协议进行路由表的交换,所以要还需要注意开放组广播权限。

4条评论
  • 何先生

    2019年12月4日 上午10:41

    ZeroTier不用在路由将公网ip解析成域名,然后通过域名访问吗,我家宽带公网ip72小时自己变一次。

    1. iEdon

      2019年12月4日 下午4:12

      目前根据 GitHub 上的 Issue,ZeroTier 不支持也没有计划支持 DDNS。
      所以我的做法是,ZeroTier 套一层腾讯云,ZeroTier 部署在家里,然后借助 FRP / V×N 穿透到公网,这样既能保证网络在自己手里管理,又能保证公网稳定直达。
      因为 ZeroTier 是打洞传输优先,所以穿透的这层消耗还是比较小的。江苏与上海的延迟平均在 10ms +,所以完全可以接受。而且,套了腾讯云的BGP线路,反而对移动更加友好哈哈哈哈。
      推荐你选一个离你家最近的公有云机房的机器,然后将局域网内的 ZeroTier 暴露到公有云上去。

  • 何先生

    2019年12月4日 上午10:43

    不知道速度如何,穿透的东西我试过frp速度还不错。

    1. iEdon

      2019年12月4日 下午4:13

      我目前使用带有 FEC 算法的 V×N 进行穿透,虽然 ping 增加了 10ms,但是实际访问的时候发现 HTTPS 延迟反而比原来降低了。

发表评论

电子邮件地址不会被公开。 必填项已用*标注