# Nezha Agent Client Secret 更新工具 ## 概述 本工具提供两个 Ansible Playbook,用于安全地更新 Nezha Agent 配置文件中的 `client_secret` 字段。 ## 文件说明 - **nezha_update_secret.yml** (推荐):使用 `lineinfile` 模块,简单可靠 - **nezha_update_secret_v2.yml** (备选):使用 `replace` 模块,正则表达式更灵活 ## 使用方法 ### 方式1:强制更新(不验证旧值) ```bash ansible-playbook nezha_update_secret.yml \ -i inventory.ini \ -e "client_secret=你的新密钥" ``` ### 方式2:安全更新(验证旧值) ```bash ansible-playbook nezha_update_secret.yml \ -i inventory.ini \ -e "client_secret=你的新密钥" \ -e "old_client_secret=旧密钥值" ``` ### 方式3:使用变量文件 创建变量文件 `vars.yml`: ```yaml client_secret: "HWzBMgbtWbSHdTyTVyh5U8bu3JhPmStw" old_client_secret: "OldSecretValue123" # 可选 ``` 执行: ```bash ansible-playbook nezha_update_secret.yml \ -i inventory.ini \ -e @vars.yml ``` ### 方式4:针对特定主机 ```bash ansible-playbook nezha_update_secret.yml \ -i inventory.ini \ --limit "server1,server2" \ -e "client_secret=你的新密钥" ``` ## 参数说明 | 参数 | 类型 | 必填 | 说明 | |------|------|------|------| | `client_secret` | 字符串 | ✅ 是 | 新的 client_secret 值 | | `old_client_secret` | 字符串 | ❌ 否 | 旧的 client_secret 值,用于验证。留空则强制更新 | | `config_file` | 字符串 | ❌ 否 | 配置文件路径,默认 `/opt/nezha/agent/config.yml` | | `service_name` | 字符串 | ❌ 否 | 服务名称,默认 `nezha-agent.service` | ## 功能特性 ### ✅ 安全性保障 - ✔️ 自动备份配置文件(带时间戳) - ✔️ 可选的旧值验证,防止误操作 - ✔️ 配置文件存在性检查 - ✔️ 参数完整性验证 ### ✅ 可靠性保障 - ✔️ 幂等操作,可重复执行 - ✔️ 更新失败时不会重启服务 - ✔️ 服务状态验证和显示 ### ✅ 自动化功能 - ✔️ 配置更新后自动重启 nezha-agent 服务 - ✔️ 使用 handler 机制,只在配置变更时重启 ## 执行流程 1. **参数验证** - 检查必填参数是否提供 2. **文件检查** - 验证配置文件是否存在 3. **备份配置** - 创建带时间戳的备份文件 4. **更新配置** - 根据是否提供旧值选择更新策略 5. **触发重启** - 配置变更时触发服务重启(handler) 6. **状态验证** - 显示服务最终状态 ## 备份说明 每次执行都会创建两个备份: 1. **时间戳备份**: `config.yml.backup.20231216T153045` 2. **Ansible 备份**: `config.yml.[随机后缀]~` 备份文件保存在与原配置文件相同的目录中。 ## 错误处理 ### 错误:client_secret 参数为空 ``` FAILED! => {"msg": "参数 client_secret 不能为空"} ``` **解决**: 确保提供了 `client_secret` 参数 ### 错误:配置文件不存在 ``` FAILED! => {"msg": "配置文件 /opt/nezha/agent/config.yml 不存在"} ``` **解决**: 检查 Nezha Agent 是否已安装,或使用 `-e config_file=路径` 指定正确路径 ### 错误:未找到匹配的旧值 ``` FAILED! => {"msg": "未找到匹配的旧 client_secret 值"} ``` **解决**: 检查 `old_client_secret` 参数是否正确,或使用强制更新模式(不提供旧值) ## 使用示例 ### 示例1:生产环境安全更新 ```bash # 先在测试环境验证 ansible-playbook nezha_update_secret.yml \ -i inventory.ini \ --limit test_servers \ -e "client_secret=NewSecret123" \ -e "old_client_secret=OldSecret456" \ --check --diff # 确认无误后应用到生产环境 ansible-playbook nezha_update_secret.yml \ -i inventory.ini \ --limit prod_servers \ -e "client_secret=NewSecret123" \ -e "old_client_secret=OldSecret456" ``` ### 示例2:批量更新所有服务器 ```bash ansible-playbook nezha_update_secret.yml \ -i inventory.ini \ -e "client_secret=NewUnifiedSecret" ``` ### 示例3:测试模式(不实际执行) ```bash ansible-playbook nezha_update_secret.yml \ -i inventory.ini \ -e "client_secret=TestSecret" \ --check --diff ``` ## 回滚操作 如果更新后需要回滚: ```bash # 方法1:使用备份文件恢复 ansible all -i inventory.ini -b \ -m copy \ -a "src=/opt/nezha/agent/config.yml.backup.20231216T153045 \ dest=/opt/nezha/agent/config.yml \ remote_src=yes" # 方法2:使用原有的 client_secret 再次运行 ansible-playbook nezha_update_secret.yml \ -i inventory.ini \ -e "client_secret=原来的密钥" ``` ## 注意事项 1. **权限要求**: 需要 root 或 sudo 权限 2. **服务中断**: 更新会导致 Nezha Agent 服务短暂重启(通常几秒钟) 3. **批量操作**: 建议先在小范围测试,再批量应用 4. **密钥安全**: 不要将密钥直接写在命令历史中,建议使用变量文件或 Ansible Vault 5. **幂等性**: 可以安全地重复执行,不会造成重复修改 ## 与 Ansible Vault 结合使用 为保护敏感信息,建议使用 Ansible Vault: ```bash # 创建加密的变量文件 ansible-vault create secret_vars.yml # 在文件中添加 client_secret: "你的密钥" # 使用加密文件执行 ansible-playbook nezha_update_secret.yml \ -i inventory.ini \ -e @secret_vars.yml \ --ask-vault-pass ``` ## 最佳实践 1. ✅ 在生产环境使用前,先在测试环境验证 2. ✅ 使用 `--check --diff` 模式预览变更 3. ✅ 使用 `old_client_secret` 参数进行安全验证 4. ✅ 使用 Ansible Vault 保护敏感信息 5. ✅ 定期清理旧的备份文件 6. ✅ 记录每次更新的时间和原因 ## 技术细节 ### 方案A (lineinfile) vs 方案B (replace) | 特性 | lineinfile | replace | |------|-----------|---------| | 复杂度 | 简单 | 中等 | | 灵活性 | 中等 | 高 | | 适用场景 | 单行替换 | 复杂模式匹配 | | 推荐度 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | 推荐使用 `nezha_update_secret.yml` (方案A),除非有特殊的正则表达式需求。 ## 许可证 遵循项目主许可证