阿里云 IoT 模组安全 SDK 集成范例

简介: 本文档介绍如何使用资源极低的 ESP32/8266 WiFi 模组进行前期开发联调与 BSP 无关的业务功能。方便开发人员快速上手。在基本业务功能端到端调试完毕之后再将标准的 C 语言程序移植到 cat1 或者 NBIoT 无线模组开发环境进行后续 BSP 的开发或者适配。

概述

本文档介绍如何使用资源极低的 ESP32/8266 WiFi 模组进行前期开发联调与 BSP 无关的业务功能。方便开发人员快速上手。在基本业务功能端到端调试完毕之后再将标准的 C 语言程序移植到 cat1 或者 NBIoT 无线模组开发环境进行后续 BSP 的开发或者适配。

硬件选型

ESP 有多种型号可选,这里我们选用 ESP01(1m RAM)以及 M5Stack C Plus 进行开发,这是 ESP 系列当中配置最低的模组,在资源有限的环境中增加业务逻辑,是确保在不同配置模组之间移植的较好选择。

  • ESP01

另外需要一个 CH340 下载器进行下载。

购买链接:

EPS01链接:https://item.jd.com/10023423910094.html

下载器链接:https://item.jd.com/10033537688506.html

  • M5Stack C Plus

购买链接:https://ic-item.jd.com/10034666963148.html

开发环境搭建

注明:下面的开发环境均以 ESP01 为模板编写,M5Stack 的开发环境和 ESP01 略有不同,在每一段的注释中标记。

推荐开发和构建环境为 VSCode 和 PlatformIO 插件,在各种平台上均可以开发和利用 UART 烧录固件。

  1. 安装 VSCode,并且在插件栏目中搜索 PlatformIO。

  1. 装好之后可以在 VSCode 侧边栏里看到 PlatformIO 的图标以及首页。这时如果导入带有 platformio.ini 配置的工程文件夹,即可直接被 PlatformIO 捕获,并且可以直接编辑配置和进行构建。

  1. 如果是初次安装 PlatformIO 环境,则需要在上述面板的 Platforms 当中搜索 ESP8266 基础支持库,并且进行安装。

M5Stack:下载 ESP32 基础库,Libraries 当中在 example 工程的基础上添加 M5StickCPlus 即可。

4. 装好之后,导入你的 C/C++ 功能即可进行开发和构建了,下面三个蓝色框分别对应:构建、烧录、打印调试日志。

  1. 在工程的 platformio.ini 文件中可以对构建全局变量进行编辑,例如指定额外的源码目录、头文件目录、库等。详情可参考:https://docs.platformio.org/en/latest/projectconf/index.html
  2. ESP 是一个开放的,生态丰富的社区,有许多开发者为这款开源硬件贡献自己开发的稳定的功能库,例如 MQTTPubSub,WifiManager,AliotSDK 等,可以直接在 PlatformIO 的 Libraries 栏目中搜索并下载。下载好的库均是以源码形式和项目进行混合编译,库目录位于 ${USER}/.platformio/packages/framework-arduinoespressif8266/cores/esp8266/ 目录下面。
  3. 项目当中的内容分为两部分:模组逻辑部分和模组安全 SDK 集成。在开发体验过程中,我们可以同时扮演模组开发者以及安全SDK开发者。

模组安全 SDK 代码结构

模组安全 SDK 代码树结构的简单说明如下:

das2 +

    +--board  // 模组硬件相关的 BPS 侧差异化代码,通常是一些接口

    +--example + // 可以用于测试和运行的示例,例如 ESP32 的示例就在其中

               +--esp8266 // ESP8266 WiFi 模组适配样例

               +--linux // GNULinux 通用适配样例

               +--m5720 // M5720 cat1 模组适配样例

               +--m5stack // 基于 ESP32 模组的 M5 CPLUS 1 设备适配样例(含设备 GUI 部分)

    +--src   // 主体代码

    +--test  // 单元测试代码

   


其中 src 目录下包括了所有模组安全检测和防御机能的通用能力,所有 example 均是可完整编译的工程,这些工程可以通过 symbolic link 的方式链接到 SDK 暴露出来的客户侧代码,方法如下:

Windows:

cd exmpale/esp8266

make_link.bat

M5Stack

cd example/m5stack

make_link.bat

Linux/Mac:

cd example/esp8266

./make_link.sh

M5Stack

cd example/m5stack

./make_link.sh

ESP 联网向导

在  ESP8266 example 当中,可以通过调整三元组定义,连接到阿里云物联网平台公共实例(内置一个免费三元组供体验)。方法如下:

  1. 在安装了 PlatformIO 插件的 VSCode 当中以文件夹方式打开 example/esp8266 目录,工程会自动导入和部署。
  2. 找到源码:example/esp8266/platform.ini,在其中可编辑 build.flag 的一个宏开关,来指定日常、预发和线上,其中指定:
  • -DENV_RELEASE=1 表示线上环境


  1. 找到源码:src/alink.cpp,根据上面选择的不同的宏开关,填入在物联网平台上申请的 PK,DN,DS 然后进行固件编译。
  2. 对于需要切换 WiFi 热点的模组,需要先利用 ESP8266 Downloader 对 flash 进行擦除,然后再烧写固件,具体步骤见下面 “构建、烧录和调试”章节。
  3. EPS8266 上电之后,会首先切换为 STA 模式,并向周围发布一个名为 ESPXXXX 的 WiFi 热点。开发者准备一台自己的手机,寻找到这个热点之后进行连接。
  4. 连接上之后会弹出一个 WifiManager 的配置页面,点击配置,即可扫描获得周围的 AP,选择一个公开的 AP,例如 IoT 实验室 AP(亦或者自己的手机做 AP),输入密码进行配置。如果配置正确,ESP32 会自动重启进入 Client 模式,连接到指定的 AP,随后自动建立 MQTT 连接到阿里云 IoT 平台和安全中心,开始工作。


M5Stack:PlatformIO 的仓库里的 WiFiManager 版本由于年久失修,不能直接用了,需要从 github 下载手动集成最新的 WifiManager(example 里已经带了):https://github.com/tzapu/WiFiManager

*此外 ESP32 的 LITTLEFS 和 ESP8266 的也略有不同,并且 PlatformIO 仓库里的 LITTLEFS 和 vfs api 有兼容性 bug,exist 函数的 create 布尔参数要自己改一下。

功能调试

模组侧 HOOK

在 ESP8266 的开源生态中,我们可以直接接触到 WiFi FWK 的所有源码,其中几个比较重要的部分,从协议栈接口向上依次为:

  1. Wifi-TCP 客户端 :它包含了一个用于实现对接层2协议栈的多态 C++ 实现和接口,对上接入 lwip 的 TCP 协议栈。在这个客户端上下文当中,可以自主添加代码,实现网络流量审计、保存、挂接(hook)网络访问事件。源码位置在:

ARDUINO_FRAMEWORK = ${USER}/.platformio/packages/framework-arduinoespressif8266

${ARDUINO_FRAMEWORK}/libraries/ESP8266WiFi/src/include/ClientContext.h

  • TCP 协议链接 STUB 可挂接在 tcp_connect 函数入口,捕获 ip4_addr 以及 port 参数。
  • 通过 Wifi-TCP Client 上行流量审计挂接在 write 函数入口,每次增加 dl 字节,保存。
  • 通过 Wifi-TCP Client 下行流量审计挂接在 _consume 函数的 tcp_receved 之后,每次增加 size 字节,保存。
  1. Wifi-UDP 客户端:它包含了一个用于实现对接层2协议栈的多态 C++ 实现和接口,对上接入 lwip 的 UDP 协议栈。在这个客户端上下文当中,可以自主添加代码,实现网络流量审计、保存、挂接(hook)网络访问事件。源码位置在:

${ARDUINO_FRAMEWORK}/libraries/ESP8266WiFi/src/include/UDPContext.h

  • UDP 协议链接 STUB 可挂接在 connect 函数入口,捕获 UDP 连接的 addr 和 port 信息。
  • 通过 Wifi-UDP Client 上行流量审计挂接在 trySend 函数 udp_sendto 调用成功之后,每次增加 data_size 字节,保存。
  • 通过 Wifi-UDP Client 下行流量审计挂接在 _consume 函数的末尾,每次增加 size 字节,保存。
  1. Wifi 模组作服务端,则会调用 WifiServer.cpp 当中的接口实现 listen 和 accept 等操作,暂时不做挂接,待将来有捕获网络连入事件时再进行入口捕获。

附件中为基于 ESP8266 模组已经配置好模组框架层挂接点的源代码,可以直接替换上述文件位置,随同模组固件一起编译,即可在模组层面向安全 SDK 提供相应的事件报告。

  1. 网络事件挂钩,这一组挂钩包括模组对外连接 IP:port 以及域名解析的挂钩模拟,以 TCP 为例:
  • IP:port 类型访问挂钩在:

${ARDUINO_FRAMEWORK}/libraries/ESP8266WiFi/src/include/ClientContext.h

int connect(ip_addr_t* addr, uint16_t port) 的 tcp_connect 调用之前。挂钩函数原型:

void lsocClientReportIPAccessEvent(ip_addr_t*addr, uint16_tport, intipVer, constchar*protocol);

  • host 域名访问挂钩在

${ARDUINO_FRAMEWORK}/libraries/ESP8266WiFi/src/WifiClient.cpp

int WiFiClient::connect(const char* host, uint16_t port) 开头的位置。挂钩函数原型:

void lsocClientReportHostAccessEvent(const char* hostname, uint16_t port);

这两个挂钩函数当中既需要调用 access stub 又要调用 control stub。

IPV4 UDP 协议和 IPV6 同理。

附件,修改过的 ESP8266 Wifi Client,其它埋点请自行修改。



M5Stack:

EPS32 的 ARDUINO_FRAMEWORK 是 ${USER}/.platformio\packages\framework-arduinoespressif32

TCP events:${ARDUINO_FRAMEWORK }/libraries/WiFi/src/WifiClient.cpp

  • 域名连接事件:int WiFiClient::connect(const char *host, uint16_t port, int32_t timeout) 函数,域名解析完成之后 call 回调函数:lsocClientReportHostAccessEvent,带入域名和地址信息进行关联。
  • IP 地址连接事件:int WiFiClient::connect(IPAddress ip, uint16_t port, int32_t timeout) 函数,直接 call lsocClientReportIPAccessEvent。
  • 上行流量挂钩:size_tWiFiClient::write(constuint8_t*buf, size_tsize) 函数,发送成功之后增加 res 字节数。
  • 下行流量挂钩:int WiFiClient::read(uint8_t *buf, size_t size) 函数,从 __rxBuffer 对象读取流成功之后增加 res 字节数。

(这里注意 ESP32 和 ESP8266 的数据结构略有差别)。

======================================================================

UDP events:${ARDUINO_FRAMEWORK }/libraries/WiFi/src/WifiUdp.cpp

  • 向 IP 地址发送报文:uint8_t WiFiUDP::begin(IPAddress address, uint16_t port) 函数,在建立 UDP socket 之前 call 回调 lsocClientReportIPAccessEvent。
  • 向 URL 发送报文:int WiFiUDP::beginPacket(const char *host, uint16_t port) 函数,在建立 UDP socket 之前 call 回调 lsocClientReportHostAccessEvent。
  • 上行流量挂钩:int WiFiUDP::endPacket() 函数,在 sendto 成功之后增加 sent字节数。
  • 下行流量挂钩:int WiFiUDP::parsePacket() 函数,在 rx_buffer write 成功之后增加 len 字节数。

======================================================================

附件,修改过的 ESP32 Wifi Client,其它埋点请自行修改。


模组主控流程

模组应用层的主控流程位于 src 目录下,其它 ESP 库和三方库可存放在工程目录的 lib 下。应用程序主入口在 main.cpp 的 setup() 函数当中。一些比较重要的模组主控和 SDK 集成的部分为:

  1. ${PROJECT}/lib/AliyunIoTSDK/src/AliyunIoTSDK.cpp,Alink SDK,用于连接 LP。
  2. ${PROJECT}/src/security.cpp,模组应用和 SDK 的集成点源码,当中实现了所有 hal 适配层的函数,包括填充固件信息、实现被动 stub(获取流量)接口等。
  3. ${PROJECT}/src/alink.cpp,模组应用和 AliyunIoTSDK 的集成点源码,实现阿里云上云,消息订阅和发布等基本操作,其中的 iot 对象被设置为了 SDK 当中的 session 对象,负责 SOC 消息收发和回调处理。

安全 SDK 在工程目录中为 ${DAS_ROOT}/src 下,对外部客户以静态库形式提供。包括所有的 SDK 主流程、步进驱动取证、服务、ATI、Stub 和 BSP 相关的接口等,在 ESP32 环境中可以和上述的模组协议栈、模组三方库共同通过源码进行编译。SDK 的作业驱动由模组主控的 security.cpp 当中通过调用 das_stepping 以及 MQTT 下行命令驱动实现,其中包含周期采样、消息上报等。详情参考模组安全 SDK 源代码。

构建、烧录和调试

  1. 点击 PlatformIO 的 build 按钮即可进行构建,如果需要引入额外的 include 路径,需要在 platformio.ini 当中进行 build_flag 配置:

ESP8266 如下:

build_flags =

-DLOG_DEBUG=1

-DLOG_INFO=1

-DLOG_ERROR=1

-DENV_DAILY=1

-DDAS_ESP8266=1

-DDAS_PLATFORM_ESP=1

-DDAS_DEBUG=1

-Wno-unused-function

-Wno-unused-variable

-I${common.workspace}/lib/lsoc_das2/

-I${common.workspace}/lib/lsoc_das2/include

-I${common.workspace}/lib/lsoc_das2/proto

-I${common.workspace}/lib/lsoc_das2/stubs/include

-I${common.workspace}/lib/lsoc_das2/stubs/include/at

-I${common.workspace}/lib/lsoc_das2/stubs/include/hal

-I${common.workspace}/lib/lsoc_das2/stubs/include/osa

-I${common.workspace}/lib/lsoc_das2/ati/inc

M5Stack 如下:

build_flags =

-DCORE_DEBUG_LEVEL=4

-DLOG_DEBUG=1

-DLOG_INFO=1

-DLOG_ERROR=1

-DENV_RELEASE=1

-DWITH_LCD=1

-DDAS_ESP32=1

-DDAS_PLATFORM_ESP=1

-DDAS_DEBUG=1

-Wno-unused-function

-Wno-unused-variable

-I${common.workspace}/lib/lsoc_das2/

-I${common.workspace}/lib/lsoc_das2/include

-I${common.workspace}/lib/lsoc_das2/proto

-I${common.workspace}/lib/lsoc_das2/stubs/include

-I${common.workspace}/lib/lsoc_das2/stubs/include/at

-I${common.workspace}/lib/lsoc_das2/stubs/include/hal

-I${common.workspace}/lib/lsoc_das2/stubs/include/osa

-I${common.workspace}/lib/lsoc_das2/ati/inc

-I${common.workspace}/lib/lsoc_das2/ati/inc/at/internal

  1. 构建好之后在 ${PROJECT}.pio/build/${ESP_PROFILE} 下会生成 firmware.bin 文件,将这个文件导入 ESP flash download tools 即可进行烧写。

  1. 烧写时请将 ESP01 芯片 pin2pin 插入下载器,下载器插入 PC 之后会枚举出 COM 口,选择正确的 COM 口以及波特率(115200)即可下载了。
  2. 下载完成后回到 PlatformIO,点击 monitor 按钮即可重新为更新过固件的 ESP01 模组上电并监控其日志信息,进行调试。


M5Stack 可以直接从 Platform IO 选择 Upload 或者 Upload&Monitor 进行烧录。

附 M5Stack 集成好之后并且访问白名单,不在白名单内的地址访问实施阻止演示:

通过阿里云 IoT 安全中心配置模组安全策略

在 M5Stick 上演示模组安全态势感知和主动防御



关于从 Arduino 环境移植的说明

ESP模组系列 的整个网络通信的技术栈类似常见的 cat1 模组技术栈,都分为芯片厂商闭源区、模组厂商闭源区、模组厂商开放区、用户区等区域。下图对比了二者之间的关系以及各个开发者角色需要开发的部分的工作项。



移植注意事项

  1. 在 ESP32 01 上调试时,das_policy_t 结构体由于需要进行 4 字节对齐的序列化处理,因此只能以全局变量的形态存储在 RAM 的 .bss 段。由于 100 个 IP/domain 实在是太大,会导致 .bss 越界。因此暂时调整至 10 个 IP/domain。在其它模组系统中请按实际情况调整。

此外也可以考虑使用 heap 代替 .bss 存储方式。

  1. 在网络事件上报函数 das_report_network_event 当中,由于是在 HOOK 函数中同步调用的,因此需要将事件加入缓存队列,随后在 stepping 调度中在 das_module_nfi_service 的 info 函数中从队列中取出。由于开发环境的 ESP32 是 non-os 的无锁环境(但需要屏蔽中断),因此队列操作没有上锁。在向 Free-RTOS 或者 Linux 等抢占式系统移植时请注意加锁。
  2. 在模组安全 SDK 的 stepping 驱动当中,目前忽略了第一次对流量进行 sampling 的结果,因为考虑到 SDK 初始化和 MQTT 连接不一定是发生在模组上电时刻的,因此需要轮询 2 个 sampling 周期才会产生第一次有效采样,轮询 2 个 sysinfo 周期才会触发第一次上报,也许有可以优化的空间。
  3. 如果需要 mock HTTP 访问,请在 MQTT 使用的 WiFiClient 之外额外声明一个 WiFiClient 对象,避免底层 ClientContext 实例冲突而导致 TCP 断链。
相关实践学习
使用DAS实现数据库自动扩容和回缩
暂无
相关文章
|
4月前
|
弹性计算 运维 Serverless
项目管理和持续集成系统搭建问题之云效流水线支持阿里云产品的企业用户如何解决
项目管理和持续集成系统搭建问题之云效流水线支持阿里云产品的企业用户如何解决
92 1
项目管理和持续集成系统搭建问题之云效流水线支持阿里云产品的企业用户如何解决
|
3天前
|
安全 定位技术 API
婚恋交友系统匹配功能 婚恋相亲软件实现定位 语音社交app红娘系统集成高德地图SDK
在婚恋交友系统中集成高德地图,可实现用户定位、导航及基于地理位置的匹配推荐等功能。具体步骤如下: 1. **注册账号**:访问高德开放平台,注册并创建应用。 2. **获取API Key**:记录API Key以备开发使用。 3. **集成SDK**:根据开发平台下载并集成高德地图SDK。 4. **配置功能**:实现定位、导航及基于位置的匹配推荐。 5. **注意事项**:保护用户隐私,确保API Key安全,定期更新地图数据,添加错误处理机制。 6. **测试优化**:完成集成后进行全面测试,并根据反馈优化功能。 通过以上步骤,提升用户体验,提供更便捷的服务。
|
1天前
|
弹性计算 监控 安全
API稳定安全最佳实践:用阿里云SDK为业务保驾护航
阿里云智能集团高级技术专家赵建强和曹佩杰介绍了API稳定安全最佳实践,涵盖业务上云真实案例、集成开发最佳实践、配额管理和共担模型四部分。通过分析企业在不同阶段遇到的问题,如签名报错、异常处理不严谨、扩容失败等,提出了解决方案和工具,确保API调用的安全性和稳定性。特别强调了SDK的使用、无AK方案、自动刷新机制以及配额中心的作用,帮助用户构建更稳定、安全的服务,提升运维效率。最终介绍了集成开发共担模型,旨在通过最佳实践和平台工具,保障业务的稳定与安全,推动行业创新与发展。
|
1月前
|
安全 Java API
【三方服务集成】最新版 | 阿里云短信服务SMS使用教程(包含支持单双参数模板的工具类,拿来即用!)
阿里云短信服务提供API/SDK和控制台调用方式,支持验证码、通知、推广等短信类型。需先注册阿里云账号并实名认证,然后在短信服务控制台申请资质、签名和模板,并创建AccessKey。最后通过Maven引入依赖,使用工具类发送短信验证码。
【三方服务集成】最新版 | 阿里云短信服务SMS使用教程(包含支持单双参数模板的工具类,拿来即用!)
|
1月前
|
存储 Prometheus 运维
在云原生环境中,阿里云ARMS与Prometheus的集成提供了强大的应用实时监控解决方案
在云原生环境中,阿里云ARMS与Prometheus的集成提供了强大的应用实时监控解决方案。该集成结合了ARMS的基础设施监控能力和Prometheus的灵活配置及社区支持,实现了全面、精准的系统状态、性能和错误监控,提升了应用的稳定性和管理效率。通过统一的数据视图和高级查询功能,帮助企业有效应对云原生挑战,促进业务的持续发展。
42 3
|
2月前
|
IDE API 开发工具
沉浸式集成阿里云 OpenAPI|Alibaba Cloud API Toolkit for VS Code
Alibaba Cloud API Toolkit for VSCode 是集成了 OpenAPI 开发者门户多项功能的 VSCode 插件,开发者可以通过这个插件方便地查找API文档、进行API调试、插入SDK代码,并配置基础环境设置。我们的目标是缩短开发者在门户和IDE之间的频繁切换,实现API信息和开发流程的无缝结合,让开发者的工作变得更加高效和紧密。
沉浸式集成阿里云 OpenAPI|Alibaba Cloud API Toolkit for VS Code
|
2月前
|
人工智能 自然语言处理 关系型数据库
阿里云云原生数据仓库 AnalyticDB PostgreSQL 版已完成和开源LLMOps平台Dify官方集成
近日,阿里云云原生数据仓库 AnalyticDB PostgreSQL 版已完成和开源LLMOps平台Dify官方集成。
|
3月前
|
机器学习/深度学习 DataWorks 数据挖掘
基于阿里云Hologres和DataWorks数据集成的方案
基于阿里云Hologres和DataWorks数据集成的方案
84 7
|
3月前
|
存储 SQL 分布式计算
Hologres 与阿里云生态的集成:构建高效的数据处理解决方案
【9月更文第1天】随着大数据时代的到来,数据处理和分析的需求日益增长。阿里云作为国内领先的云计算平台之一,提供了多种数据存储和处理的服务,其中Hologres作为一款实时数仓产品,以其高性能、高可用性以及对标准SQL的支持而受到广泛关注。本文将探讨Hologres如何与阿里云上的其他服务如MaxCompute、DataHub等进行集成,以构建一个完整的数据处理解决方案。
103 2
|
4月前
|
测试技术 Java Spring
Spring 框架中的测试之道:揭秘单元测试与集成测试的双重保障,你的应用真的安全了吗?
【8月更文挑战第31天】本文以问答形式深入探讨了Spring框架中的测试策略,包括单元测试与集成测试的有效编写方法,及其对提升代码质量和可靠性的重要性。通过具体示例,展示了如何使用`@MockBean`、`@SpringBootTest`等注解来进行服务和控制器的测试,同时介绍了Spring Boot提供的测试工具,如`@DataJpaTest`,以简化数据库测试流程。合理运用这些测试策略和工具,将助力开发者构建更为稳健的软件系统。
65 0