跳转到内容

安全最佳实践

本指南为 ESPHome 用户提供安全建议,帮助保护他们的设备和网络。

ESPHome 设计用于在可信网络(如家庭或企业网络)上部署。安全模型假设:

  • 设备受到网络边界安全(防火墙、网络分段、VLAN)的保护
  • 设备不直接暴露于不可信网络或互联网
  • 对设备的物理访问受到控制

ESPHome 设备不应被视为针对敌对网络环境加固的设备。如果您需要在敌对或不可信环境中部署设备,则需要超出 ESPHome 内置功能的额外安全措施。

ESPHome 提供了三个应始终启用的主要安全功能:

原生 API 是 ESPHome 设备与 Home Assistant 或其他客户端之间的主要通信方法。

启用 API 加密:

api:
encryption:
key: !secret device_name_api_key

最佳实践:

  • 为每个设备生成唯一的加密密钥 - 请参阅 API 组件文档了解按需密钥生成器
  • 将密钥存储在 secrets.yaml 中(永远不要将此文件提交到版本控制)
  • 切勿在设备之间重用加密密钥
  • 如果设备被入侵,立即重新生成其密钥

没有 API 加密: 本地网络上的任何人可以:

  • 读取您设备的所有传感器数据
  • 控制开关、灯和其他实体
  • 在您的设备上执行服务
  • 可能提取敏感信息

如果您启用 web 服务器 进行设备监控和控制,请始终设置密码:

web_server:
port: 80
auth:
username: !secret device_name_web_username
password: !secret device_name_web_password

最佳实践:

  • 使用强密码且唯一
  • 将凭据存储在 secrets.yaml
  • 如果不需要,考虑完全禁用 web 服务器
  • 如果只需要日志,请使用 Home Assistant 或原生 API

没有 web 服务器认证: 本地网络上的任何人可以:

  • 查看设备状态和传感器数据
  • 通过 web 界面控制开关、按钮和其他实体
  • 可能干扰设备操作

OTA(空中) 更新允许您无线更新固件。使用密码保护:

ota:
- platform: esphome
password: !secret device_name_ota_password

最佳实践:

  • 使用强密码且唯一
  • 将密码存储在 secrets.yaml
  • 切勿在多个设备上使用相同的 OTA 密码
  • 定期轮换密码或在怀疑被入侵后轮换

没有 OTA 密码: 本地网络上的任何人可以:

  • 向您的设备上传恶意固件
  • 完全破坏设备功能
  • 将您的设备作为跳板攻击其他网络资源

重要考虑: ESPHome 设备使用 mDNS 进行发现,这在 VLAN 之间不起作用。对于大多数家庭用户,将 ESPHome 设备放置在与 Home Assistant 相同的网络上是最简单且推荐的方法。

高级:VLAN 隔离(仅适用于高级用户)

对于想要 VLAN 隔离的高级用户:

推荐的方法是将 Home Assistant 连接到两个网络(双宿),而不是使用不可靠的 mDNS 反射器:

互联网 → 防火墙 → VLAN 10(可信 - Home Assistant 管理接口)
→ VLAN 30(IoT - ESPHome 设备)
→ VLAN 20(访客网络)
具有两个网络接口的 Home Assistant:
- eth0 或 wlan0:VLAN 10 (192.168.10.x) - 管理和用户访问
- eth1 或 wlan1:VLAN 30 (192.168.30.x) - IoT 设备通信

双宿设置:

  • Home Assistant 可以通过 VLAN 30 上的 mDNS 发现 ESPHome 设备
  • 用户对 Home Assistant 的访问保留在 VLAN 10 上
  • 不需要不可靠的 mDNS 反射器
  • 需要 Home Assistant 主机具有两个网络接口(物理、USB 以太网或单个接口上的 VLAN)

替代方案:无 mDNS 的静态 IP:

  • 使用静态 IP 配置 ESPHome 设备
  • 在设备上禁用 mDNS
  • 在 Home Assistant 中手动配置设备地址
  • 维护开销更大,但适用于单个接口

有关完整的 WiFi 配置选项,请参阅 WiFi 组件 文档。

尽可能优先使用以太网:

对于支持以太网的设备,使用以太网而不是 WiFi 以获得更好的安全性和可靠性:

  • 无无线加密漏洞
  • 更好的性能和更低的延迟
  • 不受 WiFi 攻击影响(取消认证、干扰等)
  • 减少无线网络拥塞

有关支持的以太网组件和兼容硬件列表,请参阅以太网组件文档

WiFi 配置(WiFi 组件):

wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
# 设置最低 WiFi 安全级别 - 拒绝连接到安全级别较低的网络
# ESP32 默认为 WPA2,ESP8266 默认为 WPA(将在 2026.6.0 更改为 WPA2)
min_auth_mode: WPA2 # 如果您的所有网络都支持,ESP32 可使用 WPA3
# 可选:带密码的回退 AP(仅在需要时)
ap:
ssid: "Fallback-AP"
password: !secret fallback_password

最佳实践:

  • ESP32 用户: 默认的 min_auth_mode: WPA2 是安全的,允许 WPA2 和 WPA3 网络 - 仅当您想限制为仅 WPA3 网络时设置 min_auth_mode: WPA3
  • ESP8266 用户: 明确设置 min_auth_mode: WPA2 以避免不安全的 WPA 默认值
  • WPA (TKIP) 存在已知漏洞 - 仅当您有无法升级的传统路由器时使用
  • 切勿使用开放或 WEP 加密的网络
  • 在路由器上使用 WPA2(最低)或 WPA3(推荐)
  • 使用强 WiFi 密码
  • 在路由器上禁用 WPS(易受暴力攻击)
  • 考虑隐藏 SSID 广播(提供有限的安全性,但减少可见性)

ESPHome 使用 mDNS 进行设备发现。请注意:

  • mDNS 在本地网络上广播设备名称
  • 同一网络上的恶意行为者可以发现设备

对于大多数用户,不建议禁用 mDNS,因为这会使设备非常难以管理。您需要手动跟踪所有设备的静态 IP 地址,如果 IP 更改还需重新配置 Home Assistant。仅当您要求极端安全性并愿意接受重大管理开销时才禁用 mDNS。

高级:禁用 mDNS(不建议大多数用户使用)
# 仅适用于极端安全要求 - 使管理非常困难
wifi:
manual_ip:
static_ip: 192.168.30.10
gateway: 192.168.30.1
subnet: 255.255.255.0
# 禁用 mDNS(需要在 Home Assistant 中手动配置静态 IP)
mdns:
disabled: true

对 ESPHome 设备的物理访问允许攻击者:

  • 通过 USB/串行连接刷写新固件
  • 从闪存中提取加密密钥和密码
  • 完全替换设备

缓解策略:

  • 将设备安装在安全位置(上锁的机柜、天花板吊顶上方)
  • 在外壳上使用防篡改封条
  • 将安装在公共区域的设备视为可能已被入侵
⚠️ 警告:永久且不可逆 - 仅在需要极端安全时展开

警告:以下方法是永久且不可逆的。除非您完全理解后果,否则不要这样做。

如果您有极端的安全要求,可以在初始部署后物理禁用 USB/串行接口:

  • 用环氧树脂填充 USB 端口(永久性 - 如果设备故障无法恢复)
  • 剪断串行引脚(永久性 - 设备无法通过串行重新刷写)
  • 使用 ESP32 上的 eFuses 通过 UART 禁用引导加载程序访问(永久且不可逆 - 阻止所有串行刷写)
  • 将设备放置在难以访问的位置(可逆)

重要考虑:

  • 一旦您使用环氧树脂、剪断引脚或烧录 eFuses,设备只能通过 OTA 更新
  • 如果 OTA 失败或设备无响应,设备将永久变砖
  • 您将无法排除连接问题或从错误固件中恢复
  • eFuses 无法重置 - 一旦烧录,它们在芯片生命周期内是永久的
  • 这仅适用于物理访问是关键威胁的极端高安全环境

对于大多数用户: 只需将设备安装在安全、难以访问的位置即可提供足够的物理安全,而没有永久变砖设备的风险。

使用 secrets.yaml 避免在配置文件中存储敏感信息,特别是当您在公共 Git 存储库中共享配置时:

device1.yaml
api:
encryption:
key: !secret device1_api_key
ota:
- platform: esphome
password: !secret device1_ota_password

secrets.yaml:

# 每个设备应有唯一的密钥和密码
device1_api_key: "uKh1234567890abcdefghijklmnopqrstuvwxyz="
device1_ota_password: "strong-unique-password-device1"
device1_web_username: "device1_admin"
device1_web_password: "strong-unique-web-password-device1"
device2_api_key: "aBc9876543210xyzqrstuvwxyzabcdefghijkl="
device2_ota_password: "strong-unique-password-device2"
device2_web_username: "device2_admin"
device2_web_password: "strong-unique-web-password-device2"
# WiFi 凭据可以在设备之间共享
wifi_ssid: "YourNetworkName"
wifi_password: "your-wifi-password"

重要: 即使使用 secrets.yaml每个设备必须有唯一的 API 加密密钥、OTA 密码和 web 服务器凭据。切勿在设备之间重用这些。只有 WiFi 凭据可以共享。

如果使用 Git 或其他版本控制

添加到 .gitignore

secrets.yaml
*.backup

验证 secrets.yaml 未被跟踪:

Terminal window
git status # secrets.yaml 不应出现
git log --all --full-history -- secrets.yaml # 应该返回空

如果您意外提交了机密:

  1. 立即轮换所有受损凭据
  2. 使用 git filter-branchBFG Repo-Cleaner 从历史记录中删除
  3. 强制推送清理后的存储库
  4. 通知任何克隆了该存储库的人

安全漏洞会定期被发现和修复。按照安装说明保持您的 ESPHome 安装最新。

最佳实践:

  • 在 GitHub 上订阅 ESPHome 发布通知
  • 查看变更日志中的安全修复
  • 首先在非生产环境中测试更新
  • 定期更新设备(每月滚动发布周期)

验证您正在更新正确的设备:

  • 在 OTA 更新之前检查设备主机名和 IP 地址
  • 使用唯一、描述性的设备名称
  • 维护设备及其配置的清单

OTA 安全:

  • OTA 更新通过本地网络进行
  • 启用 OTA 密码保护(见上文)
  • 在更新期间监控设备日志以发现异常行为

谨慎记录您记录的内容。 有关日志配置的更多详情,请参阅 logger 组件

logger:
level: INFO # 生产环境中不要使用 DEBUG
logs:
# 降低可能记录敏感数据的组件的详细程度
wifi: WARN
api: WARN

避免记录:

  • WiFi 密码(可能在 DEBUG/VERBOSE 级别记录 - 保持日志级别为 WARNING 或更高)
  • API 加密密钥
  • 用户凭据
  • 传感器的个人信息(例如 GPS 坐标)

定期审查设备日志以发现:

  • 意外的 API 连接
  • 失败的身份验证尝试
  • 异常的传感器读数或组件行为
  • 内存或崩溃转储(可能包含敏感数据)

通过以下方式访问日志:

  • esphome logs <config>.yaml 命令
  • ESPHome Device Builder web 界面
  • 串行控制台(USB 连接)

WiFi 组件 可以在无法连接到 WiFi 时创建回退 AP(当配置了 ap: 时):

wifi:
# ... 您的正常 wifi 配置 ...
ap:
ssid: "Device-Fallback"
password: !secret device_name_fallback_password # 始终设置此项

没有密码: 附近的人在 WiFi 断开时可以连接并可能:

  • 访问设备的 web 服务器
  • 通过 OTA 刷写新固件
  • 提取配置数据

最佳实践:

  • 始终设置回退 AP 密码
  • 使用强密码且唯一
  • 通过完全删除 ap: 部分考虑在生产中禁用回退 AP

如果使用 MQTT 而不是原生 API:

mqtt:
broker: !secret mqtt_broker
username: !secret mqtt_username
password: !secret mqtt_password
# 对于 ESP8266:使用带有 SSL 指纹的 TLS
# ssl_fingerprints:
# - "SHA1_FINGERPRINT_HERE"
# 对于带有 esp-idf 的 ESP32:使用带有证书颁发机构的 TLS
# certificate_authority: ca_cert.pem

最佳实践:

  • 在代理上启用 MQTT 身份验证
  • 尽可能使用 TLS 加密(检查代理支持)
  • 每个设备使用唯一的 MQTT 凭据
  • 按设备/功能分段 MQTT 主题

自定义/外部组件超出 ESPHome 安全支持范围:

external_components:
- source: github://someone/custom-component

风险:

  • 可能包含漏洞或恶意代码
  • 未经 ESPHome 维护者审查
  • 可能不遵循安全最佳实践

最佳实践:

  • 仅使用来自可信来源的外部组件
  • 使用前审查源代码
  • 保持外部组件更新
  • 考虑维护状态和社区信任
esphome:
name: secure-device
friendly_name: Secure Device
esp32:
board: esp32dev
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
# 带密码的回退热点
ap:
ssid: "Secure-Device-Fallback"
password: !secret secure_device_fallback_password
# 带加密的 API(必需)
api:
encryption:
key: !secret secure_device_api_key
# 带密码的 OTA(必需)
ota:
- platform: esphome
password: !secret secure_device_ota_password
# 如果不需要,禁用 web 服务器
# web_server:
# port: 80
# auth:
# username: !secret secure_device_web_username
# password: !secret secure_device_web_password
logger:
level: INFO
esphome:
name: production-device
friendly_name: Production Device
esp32:
board: esp32dev
framework:
type: esp-idf # ESP-IDF 通常有更好的安全更新
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
# 使用静态 IP 以减少对 mDNS 的依赖
manual_ip:
static_ip: !secret production_device_ip
gateway: !secret gateway_ip
subnet: 255.255.255.0
# 在生产中禁用回退 AP - 完全删除 ap: 部分
# 带加密的 API
api:
encryption:
key: !secret production_device_api_key
# 可选:限制为特定 Home Assistant 实例
# reboot_timeout: 15min
# 带密码的 OTA
ota:
- platform: esphome
password: !secret production_device_ota_password
# 可选:需要 safe_mode 进行故障排除
# safe_mode: true
# Web 服务器已禁用(使用 Home Assistant 进行监控)
# web_server:
logger:
level: INFO
logs:
wifi: WARN
api: WARN
# 可选:禁用 mDNS 以增加安全性
# mdns:
# disabled: true

根据您的司法管辖区和使用情况,您可能需要遵守:

  • GDPR(欧盟):如果设备收集个人数据
  • CCPA(加利福尼亚州):消费者隐私保护
  • HIPAA(美国):如果在医疗环境中使用
  • 行业标准:IEC 62443(工业自动化)、UL 2900(IoT 安全)

ESPHome 不保证符合任何特定法规。 请针对您的具体要求咨询法律和合规专家。

  1. 隔离设备立即(断开网络/电源连接)

  2. 记录您观察到的情况(日志、异常行为、时间戳)

  3. 调查同一网络上的其他设备

  4. 轮换凭据

    • API 加密密钥
    • OTA 密码
    • Web 服务器凭据
    • WiFi 密码(如果设备有权访问)
  5. 刷写新固件(通过 USB/串行,而不是 OTA)

  6. 监控持续的可疑活动

如果您发现 ESPHome 本身的安全漏洞:

作为一个开源项目,ESPHome 按”原样”提供,不提供任何安全保证或担保。用户负责:

  • 正确配置安全功能
  • 维护网络和物理安全
  • 保持软件更新
  • 为其环境实施适当的安全控制

遵循这些最佳实践可显著提高安全性,但无法消除所有风险。安全是 ESPHome 项目与其用户之间的共同责任。