Linux nftables:物联网设备的防火墙最后一道防线先说结论:物联网设备跑Linux的(树莓派、工控机、边缘网关),nftables是比iptables更好的选择。语法统一、性能更好、规则管理更方便。### nftables vs iptables| 维度 | iptables | nftables ||------|---------|----------|| 内核版本 | 2.4+ | 3.13+(推荐4.18+) || 语法 | 分散(iptables/ip6tables/ebtables) | 统一 || 性能 | 线性匹配 | 支持集合和字典,更快 || 规则更新 | 替换整条链 | 原子性增量更新 || 日志 | 需ULOG/NFLOG | 内置日志 || 状态跟踪 | 需conntrack模块 | 内置 |### 基础语法bash# 安装apt install nftables# 查看规则nft list ruleset# 清空规则nft flush ruleset### 物联网网关防火墙规则bash#!/bin/bash# /etc/nftables.conf# 清空nft flush ruleset# 基础表nft add table inet iot_filter# input链nft add chain inet iot_filter input '{ type filter hook input priority 0; policy drop; }'nft add chain inet iot_filter forward '{ type filter hook forward priority 0; policy drop; }'nft add chain inet iot_filter output '{ type filter hook output priority 0; policy accept; }'# 允许回环nft add rule inet iot_filter input iif "lo" accept# 允许已建立连接nft add rule inet iot_filter input ct state established,related accept# 允许ICMP(ping和路由发现)nft add rule inet iot_filter input ip protocol icmp acceptnft add rule inet iot_filter input ip6 nexthdr icmpv6 accept# 允许SSH(管理端口)nft add rule inet iot_filter input tcp dport 22 accept# 允许MQTT(内部设备上报)nft add rule inet iot_filter input tcp dport 1883 accept# 允许HTTP/HTTPS(Web管理)nft add rule inet iot_filter input tcp dport { 80, 443 } accept# 允许SNMP(监控)nft add rule inet iot_filter input udp dport 161 accept# 允许NTP(时间同步)nft add rule inet iot_filter input udp dport 123 accept# 允许DNSnft add rule inet iot_filter input udp dport 53 acceptnft add rule inet iot_filter input tcp dport 53 accept# 允许特定子网访问(内部网络)nft add rule inet iot_filter input ip saddr 192.168.1.0/24 accept# 其余全部丢弃(默认policy drop已处理)nft add rule inet iot_filter input log prefix "DROPPED: " limit rate 10/second counter drop# 保存nft list ruleset > /etc/nftables.conf# 启用systemctl enable nftablessystemctl start nftables### 用集合管理白名单bash# 创建设备白名单地址集合nft add set inet iot_filter allowed_devices '{ type ipv4_addr; flags interval; }'# 添加IPnft add element inet iot_filter allowed_devices { 192.168.1.100 }nft add element inet iot_filter allowed_devices { 192.168.1.101 }nft add element inet iot_filter allowed_devices { 192.168.1.0/24 }# 使用集合nft add rule inet iot_filter input ip saddr @allowed_devices accept集合比逐条规则快得多——内核用哈希表查找,1000条IP只需1条规则。### NAT转发bash# 创建NAT表nft add table ip natnft add chain ip nat postrouting '{ type nat hook postrouting priority 100; }'# MASQUERADE(4G出口)nft add rule ip nat postrouting oifname "wwan0" masquerade# 端口转发(外部访问内部MQTT)nft add chain ip nat prerouting '{ type nat hook prerouting priority -100; }'nft add rule ip nat prerouting iifname "eth0" tcp dport 1883 dnat to 192.168.1.100:1883### 限流防DDoSbash# 限制单IP连接速率nft add rule inet iot_filter input tcp dport 1883 \ ct state new \ meter conn_rate { ip saddr limit rate 10/second } \ acceptnft add rule inet iot_filter input tcp dport 1883 \ log prefix "MQTT-DDoS: " limit rate 10/second counter drop### 日志和监控bash# 记录被丢弃的包nft add rule inet iot_filter input \ log prefix "nft-drop: " level warn \ limit rate 10/second burst 20 packets \ counter# 查看计数器nft list ruleset -a# 输出:counter packets 12345 bytes 9876543### 持久化bash# 导出配置nft list ruleset > /etc/nftables.conf# 开机加载systemctl enable nftables# 配置文件格式cat > /etc/nftables.conf << 'EOF'#!/usr/sbin/nft -fflush rulesettable inet iot_filter { set allowed_devices { type ipv4_addr flags interval elements = { 192.168.1.0/24 } } chain input { type filter hook input priority 0; policy drop; iif "lo" accept ct state established,related accept ip protocol icmp accept tcp dport { 22, 80, 443, 1883 } accept udp dport { 53, 123, 161 } accept ip saddr @allowed_devices accept log prefix "DROP: " limit rate 10/second counter } chain forward { type filter hook forward priority 0; policy drop; } chain output { type filter hook output priority 0; policy accept; }}table ip nat { chain prerouting { type nat hook prerouting priority -100; } chain postrouting { type nat hook postrouting priority 100; oifname "wwan0" masquerade }}EOF### 从iptables迁移bash# 转换iptables规则到nftablesiptables-translate -A INPUT -p tcp --dport 22 -j ACCEPT# 输出:nft add rule inet filter input tcp dport 22 counter accept# 批量转换iptables-restore-translate -f /etc/iptables/rules.v4 > /etc/nftables.conf### Python动态管理规则pythonimport subprocessdef add_allowed_ip(ip): """动态添加白名单IP""" cmd = f'nft add element inet iot_filter allowed_devices {{ {ip} }}' subprocess.run(cmd, shell=True, check=True)def remove_allowed_ip(ip): """删除白名单IP""" cmd = f'nft delete element inet iot_filter allowed_devices {{ {ip} }}' subprocess.run(cmd, shell=True, check=True)def list_rules(): """查看当前规则""" result = subprocess.run( ['nft', 'list', 'ruleset'], capture_output=True, text=True ) return result.stdout# 批量添加设备devices = ["192.168.1.100", "192.168.1.101", "192.168.1.102"]for ip in devices: add_allowed_ip(ip)### 踩坑记录1. 顺序很重要:nftables规则从上到下匹配,先加的具体规则要在泛化规则之前2. flush ruleset清空一切:包括NAT表。生产环境慎用,可能断网。分表操作:nft flush table inet iot_filter3. 容器环境:Docker容器内不能用nftables修改主机网络。需要在宿主机操作4. 和Docker冲突:Docker的iptables规则和nftables可能冲突。Docker 20+支持nftables后端5. 日志磁盘:limit rate限制日志速率,否则DDoS时日志写满磁盘一句话:nftables是iptables的继任者,物联网Linux设备用nftables做防火墙——语法统一、性能更好、集合管理白名单方便。从iptables迁移有现成工具。## Zigbee 3.0组网:ESP32-H2协调器配置实战先说结论:Zigbee 3.0比 Zigbee 1.2(老版Zigbee)强在安全性和互操作性。ESP32-H2内置Zigbee协议栈,做协调器(Coordinator)能组50-100节点的智能家居网络。### Zigbee基础概念设备类型:- 协调器(Coordinator):网络的唯一创建者和管理者。每个Zigbee网络只能有一个协调器- 路由器(Router):可以转发消息,扩展网络覆盖。常供电设备(灯泡、插座)- 终端节点(End Device):不能转发消息,可以休眠。电池设备(传感器、开关)信道: Zigbee在2.4GHz频段有16个信道(11-26)。和WiFi 2.4GHz重叠。选信道时避开WiFi:WiFi 1-6: Zigbee 信道11-14(冲突大)WiFi 1-6: Zigbee 信道15-20(冲突小)WiFi 1-6: Zigbee 信道25-26(冲突最小)WiFi 11-13: Zigbee 信道11-20(冲突大)WiFi 11-13: Zigbee 信道25-26(冲突最小)推荐:WiFi用1信道,Zigbee用25信道。或者WiFi用11信道,Zigbee用25信道。PAN ID: 个人局域网标识,16位。同一区域的不同Zigbee网络用不同PAN ID。网络密钥: 128位AES加密密钥,所有节点共享。### ESP32-H2协调器c#include "esp_zigbee_core.h"#include "zigbee_console.h"#define INSTALL_CODE_LEN 8#define INSTALL_CODE_POLICY false // false:不强制安装码static esp_zb_net_config_t zb_net_config = { .esp_zb_pan_id = 0x1234, .esp_zb_channel = 25, // 信道25 .esp_zb_password = (uint8_t *)"ZigBeeAlliance09", // 默认网络密钥};void zb_network_steering(esp_zb_zcl_addr_t *addr, esp_zb_zcl_address_mode_t addr_mode) { // 允许设备加入网络(permit joining) esp_zb_zcl_start_interpan_command(ESP_ZB_ZCL_CLUSTER_TOUCHLINK);}void zb_start_network() { // 初始化Zigbee栈 esp_zb_init(); // 配置网络参数 esp_zb_set_pan_id(zb_net_config.esp_zb_pan_id); esp_zb_set_channel_mask(1ULL << zb_net_config.esp_zb_channel); esp_zb_set_network_key(zb_net_config.esp_zb_password); // 启动协调器 esp_zb_set_network_role(ESP_ZB_DEVICE_COORDINATOR); // 启动网络 esp_zb_start_network();}// 设备入网回调void zb_device_join_cb(uint16_t short_addr, uint8_t *ieee_addr) { printf("Device joined: short=0x%04x, ieee=", short_addr); for (int i = 0; i < 8; i++) { printf("%02x", ieee_addr[i]); } printf("\n"); // 查询设备端点信息 esp_zb_get_endpoints_request(short_addr);}// 设备离线回调void zb_device_leave_cb(uint16_t short_addr, uint8_t *ieee_addr) { printf("Device left: 0x%04x\n", short_addr);}void app_main() { // 初始化硬件 esp_zb_platform_config_t config = { .radio_config.radio_mode = ZB_RADIO_MODE_NATIVE, .radio_config.radio_uart_tx = GPIO_NUM_4, .radio_config.radio_uart_rx = GPIO_NUM_5, }; esp_zb_platform_init(&config); // 启动Zigbee zb_start_network(); // 注册回调 esp_zb_register_device_join_callback(zb_device_join_cb); esp_zb_register_device_leave_callback(zb_device_leave_cb); // 开放入网 esp_zb_permit_joining_request(0xFF, true); // 0xFF=永久开放 printf("Zigbee Coordinator started. PAN: 0x%04x, Channel: %d\n", zb_net_config.esp_zb_pan_id, zb_net_config.esp_zb_channel); while (1) { vTaskDelay(1000 / portTICK_PERIOD_MS); }}### Permit Joining(允许入网)协调器要主动开放入网窗口,新设备才能加入:c// 开放入网60秒esp_zb_permit_joining_request(60, true);// 永久开放(测试用,生产环境不建议)esp_zb_permit_joining_request(0xFF, true);// 关闭入网esp_zb_permit_joining_request(0, true);生产环境建议:每次只开放60秒,加完设备就关。避免陌生设备意外入网。### BDB(Base Device Behavior) TouchlinkZigbee 3.0用BDB(Base Device Behavior)规范统一了配网流程。Touchlink是近距离配网方式:c// 发起Touchlinkesp_zb_zcl_touchlink_command_t cmd = { .command = ESP_ZB_ZCL_CMD_TOUCHLINK_START;};esp_zb_zcl_touchlink_start(&cmd);// 目标设备靠近协调器(1米内),收到Touchlink信号后入网### 读设备信息c// 读取设备属性(以温度传感器为例)void read_device_info(uint16_t short_addr, uint8_t endpoint) { // 读取基本簇 esp_zb_zcl_read_attr_cmd_t read_cmd = { .address = { .addr = short_addr, .addr_mode = ESP_ZB_ZCL_ADDR_MODE_SHORT }, .endpoint = endpoint, .cluster_id = ESP_ZB_ZCL_CLUSTER_ID_BASIC, .attr_id = ESP_ZB_ZCL_ATTR_BASIC_MANUFACTURER_NAME_ID, }; esp_zb_zcl_read_attr(&read_cmd);}// 读取温度测量值void read_temperature(uint16_t short_addr, uint8_t endpoint) { esp_zb_zcl_read_attr_cmd_t read_cmd = { .address = { .addr = short_addr, .addr_mode = ESP_ZB_ZCL_ADDR_MODE_SHORT }, .endpoint = endpoint, .cluster_id = ESP_ZB_ZCL_CLUSTER_ID_TEMP_MEASUREMENT, .attr_id = ESP_ZB_ZCL_ATTR_TEMP_MEASUREMENT_VALUE_ID, }; esp_zb_zcl_read_attr(&read_cmd);}### 配置Report(上报)c// 配置温度传感器每30秒上报esp_zb_zcl_config_report_cmd_t report_cmd = { .address = { .addr = short_addr, .addr_mode = ESP_ZB_ZCL_ADDR_MODE_SHORT }, .endpoint = endpoint, .cluster_id = ESP_ZB_ZCL_CLUSTER_ID_TEMP_MEASUREMENT, .attr_id = ESP_ZB_ZCL_ATTR_TEMP_MEASUREMENT_VALUE_ID, .min_interval = 10, // 最小上报间隔(秒) .max_interval = 60, // 最大上报间隔(秒) .reportable_change = 100, // 变化阈值(0.01°C单位)};esp_zb_zcl_config_report(&report_cmd);### 解除绑定和删除设备c// 删除设备(让设备离开网络)esp_zb_leave_request(uint16_t short_addr);// 强制删除(协调器侧)esp_zb_remove_device(uint16_t short_addr, uint8_t *ieee_addr);### 实测数据ESP32-H2 + 3个Zigbee终端节点(温湿度传感器):| 指标 | 数据 ||------|------|| 信道 | 25 || PAN ID | 0x1234 || 协调器启动时间 | 3秒 || 设备入网时间 | 5-10秒/台 || 消息延迟 | 15-30ms || 最大通信距离 | 室内15米 || 路由跳数 | 最多4跳 || 协调器功耗 | 约25mA(持续) || 终端节点功耗 | DeepSleep约15μA |### 和WiFi共存ESP32-H2没有WiFi。如果需要WiFi+Zigbee,用ESP32-H2做Zigbee协调器,通过UART或I2C和ESP32-C3通信:[WiFi] ESP32-C3 ←UART→ ESP32-H2 [Zigbee] ↓ 云平台### 踩坑记录1. PAN ID冲突:如果附近有其他Zigbee网络(如涂鸦智能、小米),PAN ID可能冲突。用随机PAN ID2. 网络密钥泄露:默认密钥"ZigBeeAlliance09"是公开的。生产环境用随机密钥:esp_zb_set_network_key(random_key)3. 设备掉线:Zigbee设备掉线后不会自动重连。协调器侧配置Heartbeat检测:10分钟没消息就判定离线4. 网络重建:如果协调器重启后网络信息丢失,所有设备需要重新入网。用esp_zb_persist_network()保存网络状态到Flash5. ESP32-H2天线:PCB天线方向性较强。安装时注意朝向,避免信号死角### 替代方案如果不想用ESP32-H2,可以考虑:- CC2530/CC2652:TI的Zigbee SoC,生态成熟,但开发工具链不如ESP-IDF好用- JN5168:NXP的Zigbee芯片,性能强但价格高- EZSP:Silicon Labs的Zigbee模组,有USART/AVR库支持ESP32-H2的优势是价格便宜(约10元)+ ESP-IDF生态。劣势是Zigbee库还不够成熟,文档不如TI和Silicon Labs全。一句话:ESP32-H2做Zigbee协调器,适合50-100节点的智能家居/小型工业网络。信道选25避开WiFi,密钥别用默认值,网络状态持久化——这三点做好,基本稳定。

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐