跳转到内容

安全最佳实践

本指南为 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 界面控制开关、按钮和其他实体
  • 可能干扰设备运行

NOTE

Web 服务器设计上不提供跨站请求伪造(CSRF)保护:它不检查请求的 Origin,并使用宽松的 CORS 策略。因此,您在同一网络上访问的网页可以通过您的浏览器向设备发送命令,即使该网页的作者从未在您的网络上。启用 auth: 并将设备放在受信任的分段网络上是防御措施。这是有意为之的;请参阅项目的威胁模型。

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 反射器:

Internet → Firewall → VLAN 10 (Trusted - Home Assistant management interface)
→ VLAN 30 (IoT - ESPHome devices)
→ VLAN 20 (Guest Network)
Home Assistant with two network interfaces:
- eth0 or wlan0: VLAN 10 (192.168.10.x) - Management and user access
- eth1 or wlan1: VLAN 30 (192.168.30.x) - IoT device communication

双宿主设置:

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

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

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

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

尽可能优先使用以太网:

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

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

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

WiFi 配置(WiFi 组件):

wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
# 设置最低 WiFi 安全级别 - 拒绝连接安全级别较低的网络
# ESP32 和 ESP8266 默认值为 WPA2
min_auth_mode: WPA2 # 如果所有网络都支持,可在 ESP32 上设置为 WPA3
# 可选:带密码的后备 AP(仅在需要时)
ap:
ssid: "Fallback-AP"
password: !secret fallback_password

最佳实践:

  • 默认的 min_auth_mode: WPA2 在 ESP32 和 ESP8266 上都是安全的,允许 WPA2 和 WPA3 网络 - 在 ESP32 上可以设置 min_auth_mode: WPA3 以限制仅使用 WPA3 网络
  • 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 上的 eFuse 禁用通过 UART 的引导加载程序访问(永久且不可逆 - 阻止所有串口刷写)
  • 将设备安装在难以访问的位置(可逆)

重要考虑:

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

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

使用 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-branch 或 BFG Repo-Cleaner 从历史记录中删除
  3. 强制推送清理后的仓库
  4. 通知所有克隆了该仓库的人

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

最佳实践:

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

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

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

OTA 安全:

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

注意记录的内容。 有关日志配置的更多详细信息,请参阅日志组件。

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
# 对于使用 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(物联网安全)

ESPHome 不保证遵守任何特定法规。请咨询法律和合规专家以满足您的具体要求。

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

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

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

  4. 轮换凭据:

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

  6. 监控持续的可疑活动

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

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

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

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