第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)。它们各司其职,数据流是单向且分层的。
我画了一张图,帮你理清它们之间的关系:
这张图里,数据流是单向的:终端 -> 网关 -> 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流程如下:
- 终端发送Join Request: 包含AppEUI(应用标识)、DevEUI(设备标识)和DevNonce(随机数)。这个帧是明文发送的,但DevNonce用于防重放。
- NS验证: NS收到后,用AppKey(预共享密钥)验证MIC(消息完整性码)。同时检查DevNonce是否重复,防止重放攻击。
- NS生成会话密钥: 验证通过后,NS派生出NwkSKey(网络会话密钥)和AppSKey(应用会话密钥)。NwkSKey用于MAC层加密和完整性校验,AppSKey用于应用数据加密。
- NS发送Join Accept: 包含DevAddr(设备短地址)、DlSettings(下行参数)、RxDelay(接收窗口延迟)等。这个帧用AppKey加密,终端用AppKey解密。
- 终端存储会话密钥: 终端解密后,存储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。