『瀚思彼岸』» 智能家居技术论坛

 找回密码
 立即注册
查看: 42580|回复: 15

[进阶教程] 使用 ZeroTier 实现内网穿透,外网访问 HA

[复制链接]

8

主题

47

帖子

757

积分

论坛技术达人

积分
757
金钱
705
HASS币
20
发表于 2018-4-6 18:55:33 | 显示全部楼层 |阅读模式
本帖最后由 tomczhen 于 2018-4-6 19:09 编辑

前言

关于外网访问需求,个人认为外网访问外网公开访问是有差别的,公开不应该是外网访问的前提条件。
外网访问常用的方案分为三种:

  • DDNS 动态域名
  • 代理中转
  • 内网穿透

DDNS 需要有公网 IP,ISP 不提供公网 IP 已经成为趋势,虽然可以通过找客服解决,但是公网 IP 变成一项增值服务应该是必然结果。至于 IPv6 普及,个人观点是由于牵扯到利益分配(现有 IPv4 公网 IP 的利益),即便普及短期内也未必可以对外公开访问。

代理中转需要有公网服务器,最常使用的是 frp 与 Ngrok,本质上花生壳也算是一种代理中转,这种模式带宽和流量受中转服务器限制。

另外,公开外网访问还有一些安全问题,对于大多数普通人来说,并没有能力和精力去配置、关注安全措施,而网络上大量的自动脚本会批量的扫描尝试漏洞。
需要注意的是,免费服务,就请别对可靠性要求太高。至于家用网络搭建外网公开访问服务的需求,当前相对最可靠的方案还是使用公网服务器自建 frp 做代理。

ZeroTier 的优缺点

ZeroTier 并不提供外网公开访问解决方案,需要使用类似 VPN 的客户端才能访问。

优点

  • 无需中国特色的实名认证
  • 客户端免费开源
  • 全平台支持,甚至包括Synology、QNAP、WD MyCloud 等平台。
  • 无需公网 IP 或服务器
  • 基于 P2P 网络,速度完全取决与带宽限制

缺点

  • 握手服务器是中心化

  • 管理后台中心化,免费服务有 100 设备限制

  • 穿透失败后依靠官方服务器中转,而官方服务器走在国外,基本不可用

注:可以通过自建中转服务器来解决打洞失败后速度慢的问题 ,不过考虑到技术难度以及最终效果,不如直接自建 frp 。

ZeroTier Central

ZeroTier 需要通过 ZeroTier Central 对虚拟网络进行管理,控制客户端使用权限。

注册 ZeroTier 帐号

  1. 打开 ZeroTier 的官网 https://www.zerotier.com/
  2. 点击右上角的 Login(登录)
  3. 点击 Create An Account(创建帐号)
  4. 输入E-mail Address(邮箱)以及Password(密码),Re-Enter Password(确认密码)

如果打开速度慢请耐心等待或刷新重试,可以肯定,至少截至本文发布为止,网站没有被伟大的墙阻挡。登录后打开的付费页面无视即可,内容是提醒用户帐号的服务为免费级别,直接点击右上的 Networks 进入管理页面。

注:由于 ZeroTier 属于国外服务,如果邮箱无法收到激活邮件,建议更换邮箱服务商重新尝试。

创建 Network

  1. 登录后默认的页面是调整帐号服务等级页面,新注册帐号默认 Free 服务,有 100 个设备的限制
  2. 点击右上的 Networks 按钮进入 Networks 管理页面
  3. Create 按钮创建新的 Networks,名称由系统自动生成
  4. 点击新创建的 Network 进入 Network Setting(设置)页面

配置 Network

  1. Network ID 由系统自动生成,无法修改,同一个 Networkd ID 下的客户端就是处于一个虚拟局域网中
  2. Network Name 可以根据需要修改,或者添加 Description (说明)
  3. Access Control 可以调整 Network 是私有还是公共网络,建议 Private Network (私有)
  4. Managed Routes 可以控制客户端的路由表
  5. IPv4 Auto-Assign 控制客户端 IP 自动分配,勾选 Auto-Assign from Range 并选择网段

注:自动分配的 IP 不能与客户端本地 IP 冲突,最好保证自动分配的网段与客户端本地网段不同。

Members 管理

  1. 设备上通过zerotier-cli join 命令加入后,需要勾选已经加入的客户端 Auth 选择框,授权客户端使用虚拟网络
  2. Managed IPs 列可以为客户端添加固定 IP,确保客户端每次都分配到同样的虚拟网络 IP

注: Private Network(私有网络)需要在 ZeroTier Central 中授权才能使用虚拟网络

安装 ZeroTier One

ZeroTier One 是 ZeroTier 的客户端名称,可以在官网下载对应平台的安装包。

https://www.zerotier.com/download.shtml
注:群晖有对应的安装包可下载安装

Raspbian

使用官方提供的一键安装脚本安装:

curl -s https://install.zerotier.com/ | sudo bash

Hass.io

安装 Zerotier One 插件

https://github.com/TomCzHen/hassio-addons-repository
注:只支持 amd64 与 armhf。

配置 ZeroTier One

ZeroTier One 启动后会提供一个 API 接口,可以利用 RESTful Sensor 监听 ZeroTier One 的状态。

Raspbian

加入到 ZeroTier Network:

$ zerotier-cli join younetworkid

获取 authtoken

$ sudo cat /var/lib/zerotier-one/authtoken.secret

获取 api port

$ cat /var/lib/zerotier-one/zerotier-one.port

如果不需要使用 RESTful Sensor 监控状态,那么直接使用下面的命令获取设备 address

$ sudo zerotier-cli info

Hass.io

Hass.io 需要在插件中配置network_id port auth_token

{
  "network_id":"yournetworkid",
  "port": 9993,
  "auth_token": "yourauthtoken",
  "log_level": "info"
}

如果对 docker 熟悉或者有使用 portainer,也可以直接进入插件容器控制台中执行命令来获取设备 ZeroTier address 并加入 network 。

补充说明

zerotier-one 的配置默认保存在 /var/lib/zerotier-one/,Hass.io 插件则保存在插件 data 目录下。

如果配置文件删除,zerotier-one 会产生新的设备 address,如果卸载插件或删除对应的文件夹,那么需要重新设置 ZeroTier 网络。

配置 RESTful Sensor

对于 Hass.io 来说,如果不知道如何进入插件对应容器的终端,那么这一步是必须的。

添加 RESTful Sensor

将下面 resource 中的端口,headersX-ZT1-Auth 的值替换成你的配置即可,关于 RESTful Sensor 更多使用请查看官方文档:

https://www.home-assistant.io/components/sensor.rest/

  - platform: rest
    name: ZeroTier One Status
    json_attributes:
      - address
      - version
    resource: http://127.0.0.1:9993/status
    value_template: '{{ value_json.online }}'
    method: GET
    headers:
      X-ZT1-Auth: yourauthtoken
  - platform: rest
    name: ZeroTier One Network
    json_attributes:
      - id
      - type
    resource: http://127.0.0.1:9993/network/yournetworkid
    value_template: '{{ value_json.status }}'
    method: GET
    headers:
      X-ZT1-Auth: yourauthtoken

ZeroTier One API 简单说明

详细的 API 文档请参阅官方手册:

https://www.zerotier.com/manual.shtml#4

主要关注的是 /status/network 这两个接口,返回的数据格式是 JSON 格式。

/status

只支持 GET 访问,返回当前设备的 ZeroTier  状态。

  • address
    设备的 ZeroTier 地址

  • online
    设备的联网状态

/network

只支持 GET 访问,返回当前设备相关的 network 列表。

/network/################

支持 GET、POST、DELETE 访问,操作指定 id 的 network。

POST 访问将会请求加入指定 id 的 network,DELETE 则是离开指定 id 的 network,出于监控状态的目的,只能使用 GET 方式

  • status
    当前设备指定 id 的 network 状态,对于私有 ZeroTier 网络,需要管理者允许才能加入。
    状态包括OK NOT_FOUND ACCESS_DENIED PORT_ERROR

管理 ZeroTier 网络

在 ZeroTier Central 中的 Members 部分对对应的 address 设备授权,对于需要访问 HomeAssistant 或 Hass.io 的设备,安装好 ZeroTier One 后主动 Join 或者同样的方式添加到同一个 network 即可,使用 ZeroTier Network 分配的 IP 访问对应设备。

Managed Routes

假设你的本地局域网网段为 192.168.99.0/24,HA 的 IP 为 192.168.99.100,HA 在 ZeroTier 网络中分配的 IP 为 192.168.196.100

Managed Routes 中添加一条新路由记录。network/bits 中输入 192.168.99.0/24,后面一栏输入 192.168.196.100,这样在本地网络时直接访问 192.168.99.100,在外网时,需要开启 Route Via ZeroTier 选项 ,然后也可以通过 192.168.99.100 来访问 HA。

警告:路由表会改变设备网络访问路径,如果配置不当,会影响到设备网络。当同一内网中有多个设备安装 ZeroTier One 后以上配置会让设备本地内网 IP 互访不可达。

其他

如果路由器支持安装 ZeroTier One 的话,可以仅在路由器安装,不需要为内网所有设备安装 ZeroTier One,这个就属于玩路由器的范畴了,不在本文范围之内,请使用搜索引擎来获取更多信息。

脑洞

ZeroTier 是基于 Layer 2 的实现,假如网络配置正确的话,应该可以将异地设备也加入到 HomeAssistant 中进行管理。

FAQ

  • 官网速度慢/打不开
    中国特色互联网,不爽请移民或者换个科学的姿势。
  • 安装配置后外网访问慢
    解决不了,打洞能否成功看脸,根据网上收集的信息看,成功率还是比较高的,但是我用的联通 4G 网络就没打洞成功过。
  • 英文看不懂
    1. 开翻译软件
    2. 学英语
  • 不会安装/安装失败
    一键安装脚本请到官方网站反馈问题,请记得用英语。


如果觉得内容能帮助到你,愿意的话可以通过赞赏码对我赞赏:

                               
登录/注册后可看大图


评分

参与人数 1金钱 +7 收起 理由
jyz_0501 + 7 这排版和通俗易懂的描述简直是天人!!!.

查看全部评分

回复

使用道具 举报

12

主题

545

帖子

2037

积分

金牌会员

Rank: 6Rank: 6

积分
2037
金钱
1492
HASS币
0
发表于 2018-4-6 19:22:49 来自手机 | 显示全部楼层
这个比用内网穿透复杂太多拉 而且还要客户端好像
回复

使用道具 举报

2

主题

47

帖子

350

积分

论坛技术达人

积分
350
金钱
303
HASS币
0
发表于 2018-4-6 20:24:03 | 显示全部楼层
联通4g是Symmetric NAT,无法内网穿透。这玩意感觉配置好了玩局域网游戏挺好用的。
回复

使用道具 举报

75

主题

1976

帖子

8183

积分

元老级技术达人

积分
8183
金钱
6157
HASS币
430

活跃会员教程狂人

发表于 2018-4-6 20:36:35 | 显示全部楼层
我的 铁通网络,本来是外网动态IP,路由器是梅林,DDNS是阿里的,长宽和移动手机都可以回家,就是联通不行,无奈弄了个花生壳内网穿透,勉强用着,不知道有啥好办法。
所有过往,皆为序章。
回复

使用道具 举报

123

主题

4661

帖子

1万

积分

管理员

囧死

Rank: 9Rank: 9Rank: 9

积分
16412
金钱
11666
HASS币
45
发表于 2018-4-6 21:21:03 | 显示全部楼层
不能外网访问,还是不太爽
回复

使用道具 举报

6

主题

386

帖子

2045

积分

金牌会员

Rank: 6Rank: 6

积分
2045
金钱
1657
HASS币
0
发表于 2018-4-7 11:39:11 | 显示全部楼层
马克一下。
回复

使用道具 举报

6

主题

60

帖子

353

积分

论坛积极会员

积分
353
金钱
293
HASS币
0
发表于 2018-4-27 13:59:15 | 显示全部楼层
感谢分享
回复

使用道具 举报

2

主题

227

帖子

1980

积分

金牌会员

Rank: 6Rank: 6

积分
1980
金钱
1753
HASS币
0
发表于 2018-6-2 08:11:15 | 显示全部楼层
Mark 一下
回复

使用道具 举报

15

主题

212

帖子

1268

积分

金牌会员

Rank: 6Rank: 6

积分
1268
金钱
1056
HASS币
0
发表于 2018-6-10 15:26:31 | 显示全部楼层
666666666666666
回复

使用道具 举报

175

主题

2967

帖子

7606

积分

超级版主

我就是六神

Rank: 8Rank: 8

积分
7606
金钱
4614
HASS币
398

活跃会员教程狂人灌水之王

QQ
发表于 2018-9-7 00:57:41 | 显示全部楼层

9月 07 00:55:10 raspberrypi hassio-supervisor[1386]: 18-09-06 16:55:10 INFO (MainThread) [hassio.addons.git] Clone addon https://git.coding.net/tomczhen/hassio-addons.git repository
9月 07 00:55:10 raspberrypi hassio-supervisor[1386]: 18-09-06 16:55:10 ERROR (MainThread) [aiohttp.server] Error handling request
9月 07 00:55:10 raspberrypi hassio-supervisor[1386]: Traceback (most recent call last):
9月 07 00:55:10 raspberrypi hassio-supervisor[1386]:   File "/usr/local/lib/python3.7/site-packages/aiohttp/web_protocol.py", line 390, in start
9月 07 00:55:10 raspberrypi hassio-supervisor[1386]:     resp = await self._request_handler(request)
9月 07 00:55:10 raspberrypi hassio-supervisor[1386]:   File "/usr/local/lib/python3.7/site-packages/aiohttp/web_app.py", line 352, in _handle
9月 07 00:55:10 raspberrypi hassio-supervisor[1386]:     resp = await handler(request)
9月 07 00:55:10 raspberrypi hassio-supervisor[1386]:   File "/usr/local/lib/python3.7/site-packages/aiohttp/web_middlewares.py", line 106, in impl
9月 07 00:55:10 raspberrypi hassio-supervisor[1386]:     return await handler(request)
9月 07 00:55:10 raspberrypi hassio-supervisor[1386]:   File "/usr/local/lib/python3.7/site-packages/hassio/api/security.py", line 36, in token_validation
9月 07 00:55:10 raspberrypi hassio-supervisor[1386]:     return await handler(request)
9月 07 00:55:10 raspberrypi hassio-supervisor[1386]:   File "/usr/local/lib/python3.7/site-packages/hassio/api/proxy.py", line 231, in websocket
9月 07 00:55:10 raspberrypi hassio-supervisor[1386]:     await server.send_str(client_read.result())
9月 07 00:55:10 raspberrypi hassio-supervisor[1386]:   File "/usr/local/lib/python3.7/site-packages/aiohttp/client_ws.py", line 252, in receive_str
9月 07 00:55:10 raspberrypi hassio-supervisor[1386]:     msg.data))
9月 07 00:55:10 raspberrypi hassio-supervisor[1386]: TypeError: Received message 257:None is not str
9月 07 00:55:10 raspberrypi hassio-supervisor[1386]: 18-09-06 16:55:10 ERROR (MainThread) [aiohttp.server] Unhandled exception
9月 07 00:55:10 raspberrypi hassio-supervisor[1386]: Traceback (most recent call last):
9月 07 00:55:10 raspberrypi hassio-supervisor[1386]:   File "/usr/local/lib/python3.7/site-packages/aiohttp/web_protocol.py", line 410, in start
9月 07 00:55:10 raspberrypi hassio-supervisor[1386]:     await resp.prepare(request)
9月 07 00:55:10 raspberrypi hassio-supervisor[1386]:   File "/usr/local/lib/python3.7/site-packages/aiohttp/web_response.py", line 300, in prepare
9月 07 00:55:10 raspberrypi hassio-supervisor[1386]:     return await self._start(request)
9月 07 00:55:10 raspberrypi hassio-supervisor[1386]:   File "/usr/local/lib/python3.7/site-packages/aiohttp/web_response.py", line 608, in _start
9月 07 00:55:10 raspberrypi hassio-supervisor[1386]:     return await super()._start(request)
9月 07 00:55:10 raspberrypi hassio-supervisor[1386]:   File "/usr/local/lib/python3.7/site-packages/aiohttp/web_response.py", line 367, in _start
9月 07 00:55:10 raspberrypi hassio-supervisor[1386]:     await writer.write_headers(status_line, headers)
9月 07 00:55:10 raspberrypi hassio-supervisor[1386]:   File "/usr/local/lib/python3.7/site-packages/aiohttp/http_writer.py", line 110, in write_headers
9月 07 00:55:10 raspberrypi hassio-supervisor[1386]:     self._write(buf)
9月 07 00:55:10 raspberrypi hassio-supervisor[1386]:   File "/usr/local/lib/python3.7/site-packages/aiohttp/http_writer.py", line 67, in _write
9月 07 00:55:10 raspberrypi hassio-supervisor[1386]:     raise ConnectionResetError('Cannot write to closing transport')
9月 07 00:55:10 raspberrypi hassio-supervisor[1386]: ConnectionResetError: Cannot write to closing transport
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|Hassbian

GMT+8, 2024-11-27 04:14 , Processed in 0.157094 second(s), 35 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表