摘 要:现代智能家居设备可通过手机APP被远程控制,这些控制信息流通常会通过云服务器VPS中转,存在安全隐患。当中转VPS接受大量请求时,可能会产生网络阻塞而延时。该文设计了一种价格低廉而又可靠的远程控制方案,以MQTT协议传输信息,家居控制端采用NodeMCU控制模块(ESP8266带Wi-Fi),网络架构以一种VPN技术,在手机APP和家庭路由器(OpenWrt系统)之间进行P2P内网穿透的直连通信,既保证了安全性,又提高了控制响应速度。
关键词:内网穿透;ZeroTier;OpenWrt;MQTT;NodeMCU;ESP8266
中图分类号:TP319 文献标识码:A 文章编号:2096-4706(2020)18-0169-03
Abstract:Modern smart home devices can be remotely controlled through mobile APP. These control information streams are usually transferred through the cloud server VPS,which has security risks. When the transit VPS accepts a large number of requests,it may cause network congestion and delay. This paper designs a low-cost and reliable remote control scheme,which uses MQTT protocol to transmit information and the home controlled terminals use NodeMCU modules(ESP8266 with Wi-Fi). The network architecture uses a VPN technology to carry out P2P intranet penetration direct communication between mobile APP and home(OpenWrt)router,which not only ensures the security,but also improves the control response speed.
Keywords:intranet penetration;ZeroTier;OpenWrt;MQTT;NodeMCU;ESP8266
0 引 言
当下智能家居设备在家庭中逐渐普及,给生活带来了便利。有时我们不在家中,却想要查询或控制家中的电器设备,这时就要求我们能对其进行远程控制。目前常见的远程家居设备控制方案通常采用云服务器中转传输信息,存在两个缺点,一是信息可被截获,存在安全隐患,二是当中转VPS接受大量请求时,可能会产生网络阻塞而延时。本文采用内网穿透技术,使得控制端与家庭路由器之间不经过VPS中转消息,以P2P直连,再结合MQTT协议和NodeMCU控制模块,与手机端APP软件以及开源OpenWrt路由系统一起构建了一个廉价可靠而又灵敏的物联网家居远程控制系统。
1 内网穿透技术介绍
通常每个家庭的智能家居设备会以家庭智能路由器为中心构建一个小型局域网,在该局域网中以有线或Wi-Fi方式连接PC、手机、平板等各种智能联网设备。當我们人在家中,手中的手机通常直连入家庭局域网,这时手机上的APP软件可容易地控制家中联网设备。而当人处于住所以外的地方,这时手中手机连接的网络要么是4G/5G通信网络,要么是另一个Wi-Fi局域网,这种情况下想要连接上自己的家庭局域网并控制联网设备,则需要内网穿透技术才能达到目的。
内网穿透的目的是从外网(Internet)访问局域网内部某一个联网的设备,涉及NAT/NAPT和P2P等技术。
1.1 NAT和NAPT
NAT中文含义是网络地址转换,NAT不仅能解决IP地址不足的问题,还能有效地避免来自网络外部的攻击,隐藏并保护网络内部的计算机[1]。NAPT中文含义是网络地址端口转换,能完成<内部地址+内部端口>和<外部地址+外部端口>之间的转换,被称为“多对一”的NAT,目前大多数中等及大型局域网中路由设备主要都采用NAPT。
1.2 P2P技术
P2P点对点技术又称对等互联网络技术,可以使得不同局域网的内网设备实现直连。它的重要能力就是内网穿透,档案分享类软件如电骡等就使用了P2P技术。P2P传输的方法主要有中继、逆向连接、打洞(UDP或TCP方式)等技术。需要注意,针对双方都是对称NAT网络进行UDP打洞则不可行,而目前国内几个主要4G网络提供商的局域网大都是对称NAT类型,使用常见内网穿透方式通常会失败。
1.3 实用内网穿透方案
商用内网穿透方案主要有花生壳、NAT123、蒲公英等。开源方案有frp、NPS、ngrok、ZeroTier、n2n、Tinc等。ZeroTier是一款适用于全球互联网的智能以太网软交换技术。它是建立在加密安全的全球点对点对等网络(P2P)之上的分布式网络管理程序。它提供了先进的网络虚拟化和管理功能,与企业SDN交换机不相上下,能同时跨局域网和广域网,几乎可以连接任何类型的应用程序或设备。[2]
ZeroTier协议是原始的,在OSI模型意义上,它有两个概念上独立但紧密耦合的层:VL1和VL2。VL1是底层的点对点传输层,即“虚拟线”,而VL2是一个模拟的以太网层,它为操作系统和应用程序提供友好常见的通信介质。[2]
P2P连接过程为[2]:(1)A想发送一个包到B,但由于它没有直接路径,所以它将包发送到上级R(根节点);(2)如果R有一个直接链接到B,R会将包转发到B那里。否则,R会继续向上级根节点发送数据包,直到到达行星根节点群为止。行星根节点群知道所有的节点,所以如果B在线,包最终会到达B;(3)R还向A发送一个路由消息,其中包含关于R如何到达B的提示。同时,转发包到B的根节点R也发送路由消息,通知B根节点R如何到达A;(4)A和B获取它们的路由会合消息,并尝试向彼此发送测试消息,可能会完成对任何阻挡的NAT或有状态防火墙的穿孔。如果建立起了直接的链接,则包不再走先前的转发路线。
2 系统架构设计
手机通过4G/5G或局域网连接入公网Internet,家庭局域网路由器(OpenWrt系统)通过光猫接入公网。手机和路由器中均安装有ZeroTier客户端,前期通过ZeroTier的根服务器完成打洞,之后手机和路由器之间可建立起直连通道。路由器的OpenWrt系统上安装有MQTT服务器(SSL版)[3],转发MQTT消息给局域网中的所有NodeMCU控制模块。本文采用了有较强内网穿透能力的ZeroTier技术,设计的系统架构如图1所示。
3 系统架构搭建及网络连通测试
按照图1架构方式,首先使用ZeroTier搭建内网穿透环境,分为五个步骤:(1)在ZeroTier官网先注册账号;(2)再根据使用的场景下载不同版本的ZeroTier客户端软件(有Linux,Windows,Android,OpenWRT环境);(3)网页登录个人账号工作面板,创建网络ID;(4)在使用环境中运行ZeroTierOne软件,加入创建好的网络ID;(5)在工作面板上授权各客户端的连接,分配虚拟局域网IP,如图2的192.168.191.39和192.168.191.16所示,其中39为手机IPv4地址,16为路由器(OpenWrt系统)分得地址。网络连通测试只需由路由器向手机IPv4地址发送PING包,若建立起了P2P通道,则可PING通。
4 手机APP与NodeMCU控制模块通信设计及编码实现
本文采用的物联网通信协议是MQTT,该协议适合智能家居设备,有各种语言版本的实现。MQTT服务器采用开源Mosquitto(支持MQTT V3.1.1协议)[4],支持WebSocket通信方式。在手机APP中采用了开源mqtt.js[5],以网页WebSocket进行通信。NodeMCU控制模块的SDK[6]实现了MQTT的通信模块,编程时只需调用编程接口即可。
Web页关键代码为:
varmaster = mqtt.connect("ws://192.168.191.16:9001");
master.subscribe("mqtt/d");
master.on("message", function (topic, payload){
console.log(topic+":"+payload);});
function sendMsg(){
master.publish("mqtt/d", "off"); }
btnClose.onclick = function(){sendMsg();}
手機APP调用Web页,其中IP为由ZeroTier技术分配的虚拟局域网IP地址。
NodeMCU控制模块进行MQTT通信关键Lua代码为(其中IP为路由器IP地址):
function go()
m = mqtt.Client("NodeMCU", 120)
m:on("message", function(client, topic, data)
print(topic .. ":" )
if data ~= nil then
print(data) --根据mqtt消息进行设备控制,如关灯
end
end)
m:connect("192.168.2.1",
function(m)print("已连接")
m:subscribe("mqtt/d", 0, function(client) print("订阅成功") end)
m:publish("mqtt/d", " NodeMCU", 0, 0, function(client) print("发送") end)
end,
function(client, reason) print("失败原因" .. reason) end
)
end
当系统网络连通后,从手机APP发布的MQTT消息内网穿透后,直接以P2P方式传到家庭路由器(OpenWrt系统)上,该路由器上MQTT服务器收到这个消息后,转发给NodeMCU控制模块从而控制家居设备,比如开关空调、调节空调等。我院计算机科学系多个实验室机房采用这种方案实现了对机房内空调和灯的远程控制,完成的空调控制端模块和手机端APP界面如图3和图4所示。实际运用的网络环境为移动4G通信网络(对称NAT)和电信宽带网络(端口限制NAT),通信过程表明采用ZeroTier技术和这种架构,网络响应迅速,是一种实际可用且可靠的方案。
5 结 论
本文构建了一种可内网穿透家庭局域网进行网络直连,进而控制智能家居设备的方案。该方案硬件方面由手机/平板,广域网(4G/5G通信网络),VPS(ZeroTier根服务器),家庭光猫,路由器(OpenWrt系统),多个NodeMCU控制模块和多台受控设备(灯、电视、空调等)构成;软件方面有手机/平板APP(ZeroTier客户端、远程家居设备控制程序),路由器OpenWrt系统运行的ZeroTier客户端、MQTT服务器(Mosquitto)软件,NodeMCU控制模块程序,结合MQTT协议进行信息交互。采用了ZeroTier的P2P技术能在除两方局域网都是对称NAT网关设备之外的多种情景下进行内网穿透。实际场景应用表明这是一种稳定可靠且快速的远程控制家居设备的方案。
参考文献:
[1] FALL K R,STEVENS W R.TCP/IP详解 卷1:协议:第2版 [M].吴英,张玉,许昱玮,译.北京:机械工业出版社,2016:212.
[2] ZeroTier.MANUAL [EB/OL].[2020-05-20].https://zerotier.com/manual/.
[3] OpenWRT. package:mosquitto-ssl [DB/OL].[2020-05-20].https://openwrt.org/packages/pkgdata/mosquitto-ssl.
[4] Eclipse. An open source MQTT broker [EB/OL].[2020-05-20].http://mosquitto.org/.
[5] MQTT.js.The MQTT client for Node.js and the browser [EB/OL].[2020-05-19]https://github.com/mqttjs/MQTT.js
[6] ROBINSON S,TUAN PM.MQTT Module [EB/OL].(2015-01-23).https://nodemcu.readthedocs.io/en/release/modules/mqtt/.
作者简介:钱立(1978—),男,汉族,四川遂宁人,硕士,副教授,研究方向:软件专业Java/Web開发前端技术、物联网嵌入式软件技术等。