第2章:LoRaWAN协议栈基础——物理层与MAC层回顾、网络架构与流程

各位好,欢迎来到第二章。上一章我们聊了IoT安全的大背景,今天咱们把目光聚焦到LoRaWAN本身。说实话,很多搞安全的同学容易忽略协议栈本身,一上来就盯着加密算法看。我个人习惯是,先搞清楚数据怎么流、谁跟谁说话,再谈怎么保护它。你想想看,连网关和服务器谁先发消息都不知道,怎么设计安全策略?

这一章,我们快速过一遍物理层和MAC层的关键点,然后重点拆解网络架构和两条核心流程:入网(Join)和上下行数据。嗯,这些都是后面讲安全的基础,别跳过。

2.1 物理层与MAC层:LoRa的“声音”与“语法”

LoRaWAN的底层是LoRa物理层,这是Semtech公司的专利技术。它用的是一种叫Chirp Spread Spectrum(CSS)的调制方式。说白了,就是把信号在频域上“展开”,像鸟叫声一样从低到高或从高到低扫过去。这样做的好处是抗干扰能力强,灵敏度高,代价就是速率慢。

核心参数速记:

  • 频段: 全球各地不同,EU868(欧洲)、US915(北美)、CN470(中国)等。注意,频段决定了合规要求和可用信道。
  • 扩频因子(SF): SF7~SF12。SF越大,速率越慢,但传输距离越远。SF12的灵敏度可以到-137dBm左右。
  • 带宽(BW): 常见125kHz、250kHz、500kHz。带宽越宽,速率越快,但灵敏度会下降。
  • 编码率(CR): 4/5到4/8,用于前向纠错。

MAC层呢,就是LoRaWAN协议本身了。它定义了设备怎么接入网络、怎么确认消息、怎么调整速率。我记得有一次在野外测试,终端离网关很远,数据一直发不上去。后来发现是ADR(自适应数据速率)没开,终端一直用SF7在喊,网关根本听不见。开了ADR后,自动降到SF12,数据就通了。这就是MAC层在背后干活。

MAC层有几个关键机制你得知道:

  • 纯ALOHA接入: 终端想发就发,不监听信道。简单,但冲突概率高。好在LoRaWAN有多个信道和SF,一定程度上缓解了冲突。
  • 确认与非确认消息: 确认消息(Confirmed)需要服务器回ACK,非确认(Unconfirmed)则不需要。安全场景下,关键指令建议用Confirmed,但要注意功耗和网络负载。
  • ADR机制: 网络服务器根据链路质量,动态调整终端的SF和发射功率。这玩意儿在固定场景下很好用,但移动终端慎用。

避坑指南: 我曾经在一个项目中,终端是安装在卡车上的,结果ADR把SF调到了最低,卡车一开远,数据全丢了。后来我强制固定了SF,才解决问题。所以,移动场景下,ADR不一定是最优解。

2.2 LoRaWAN网络架构:四个角色一台戏

LoRaWAN网络由四个核心组件构成:终端节点(End Device)、网关(Gateway)、网络服务器(Network Server, NS)和应用服务器(Application Server, AS)。它们各司其职,数据流是单向且分层的。

我画了一张图,帮你理清它们之间的关系:

LoRaWAN网络架构与数据流 LoRaWAN 网络架构与数据流 终端节点 End Device 网关 Gateway 网络服务器 NS 应用服务器 AS LoRa RF TCP/IP (Semtech GWMP) MQTT/HTTP 关键说明: 终端与网关之间是LoRa无线连接;网关与NS之间是标准TCP/IP(Semtech GWMP协议);NS与AS之间是MQTT或HTTP。 终端永远不直接连接AS,所有应用数据都经过NS转发。

这张图里,数据流是单向的:终端 -> 网关 -> NS -> AS。反过来,下行数据也是这个路径的逆序。注意,终端永远不直接跟AS说话,所有应用数据都经过NS。这个设计对安全有深远影响——NS是中间人,但它不是坏人,它是策略执行点。

四个角色的职责,我用表格总结一下:

组件 职责 安全关注点
终端节点 采集数据、发送上行帧、接收下行帧、执行Join流程 设备身份、密钥存储、固件完整性
网关 透明转发LoRa帧到NS,不解析应用数据 回传链路安全(TLS)、物理防篡改
网络服务器 MAC层处理、去重、ADR、Join处理、会话管理 会话密钥管理、Join流程验证、重放攻击防护
应用服务器 应用数据解密、业务逻辑处理、下行指令生成 应用密钥管理、数据隐私、访问控制

注意: 网关是“透明”的,它不持有任何会话密钥。这意味着即使网关被攻破,攻击者也只能看到加密后的数据,无法解密。但网关可以篡改或丢弃数据包,所以回传链路必须用TLS保护。

2.3 Join流程:设备如何“注册”入网

终端要上网,必须先走Join流程。这就像你去公司报到,HR给你发工牌和门禁卡。在LoRaWAN里,这个“工牌”就是会话密钥。

Join流程有两种方式:OTAA(空中激活)和ABP(个人激活)。我强烈建议生产环境用OTAA,因为安全性高得多。ABP虽然省事,但密钥是预置的,一旦泄露,整个网络都危险。

OTAA流程如下:

  1. 终端发送Join Request: 包含AppEUI(应用标识)、DevEUI(设备标识)和DevNonce(随机数)。这个帧是明文发送的,但DevNonce用于防重放。
  2. NS验证: NS收到后,用AppKey(预共享密钥)验证MIC(消息完整性码)。同时检查DevNonce是否重复,防止重放攻击。
  3. NS生成会话密钥: 验证通过后,NS派生出NwkSKey(网络会话密钥)和AppSKey(应用会话密钥)。NwkSKey用于MAC层加密和完整性校验,AppSKey用于应用数据加密。
  4. NS发送Join Accept: 包含DevAddr(设备短地址)、DlSettings(下行参数)、RxDelay(接收窗口延迟)等。这个帧用AppKey加密,终端用AppKey解密。
  5. 终端存储会话密钥: 终端解密后,存储NwkSKey和AppSKey,后续通信就用这两个密钥。

个人经验: 我在调试一个项目时,发现终端反复Join失败。查了半天,原来是DevNonce计数器在终端重启后重置了,导致NS认为Nonce重复,直接拒绝。后来我在终端固件里把Nonce存到非易失区,问题解决。记住,Nonce管理是Join流程的常见坑。

ABP就简单多了:终端出厂时直接预置了DevAddr、NwkSKey和AppSKey,上电就能发数据,不需要Join。但问题也很明显——密钥是静态的,一旦泄露,无法更换。而且没有Join流程,NS无法确认设备是否合法。所以,ABP只适合实验室或可控环境。

2.4 数据上行与下行流程:数据怎么“飞”

Join完成后,终端就可以正常收发数据了。上行和下行流程,我分开讲。

2.4.1 上行流程

终端主动发数据给网关。流程如下:

  • 终端构造MAC帧,用NwkSKey计算MIC,用AppSKey加密应用数据(FRMPayload)。
  • 终端选择一个信道和SF,发送上行帧。
  • 一个或多个网关收到后,加上接收元数据(RSSI、SNR、时间戳),打包成Semtech GWMP协议,通过TCP/IP发给NS。
  • NS收到后,去重(多个网关可能上报同一帧),验证MIC,解密MAC层数据,然后转发给AS。
  • AS用AppSKey解密应用数据,执行业务逻辑。

这里有个细节:上行帧的FCnt(帧计数器)是递增的,用于防重放。NS会检查FCnt是否大于上次的值,否则丢弃。嗯,这是MAC层安全的基础。

2.4.2 下行流程

下行稍微复杂一点,因为终端不是一直在线。LoRaWAN定义了两种接收窗口:

  • RX1: 上行发送后1秒,终端自动打开接收窗口,使用与上行相同的信道和SF(但有偏移规则)。
  • RX2: 上行发送后2秒,终端打开第二个窗口,使用固定信道和SF(通常是SF12)。

NS要发下行数据时,会先等终端的上行,然后在上行后的RX1或RX2窗口下发。如果终端没收到,NS可以重试,但要注意,下行数据不能主动推送,必须等终端“开门”。

下行安全要点:

  • 下行帧同样用NwkSKey计算MIC,用AppSKey加密应用数据。
  • FCnt是上行和下行分开计数的,下行FCnt也用于防重放。
  • 如果终端在RX1窗口收到了下行帧,就不会再开RX2。这样可以省电。

我遇到过一个问题:终端上报数据后,NS想下发一条指令,但终端在RX1窗口没收到(信号差),RX2窗口又因为配置错误没打开,结果指令一直下不去。后来我调整了RX2的频点和SF,确保覆盖范围,问题才解决。所以,下行链路预算一定要算好,尤其是RX2。

2.5 本章小结