背景:一个反复折磨我的问题
我管理多台腾讯云轻量应用服务器(Lighthouse),防火墙白名单设为当前公网出口 IP。家用宽带每次重拨 IP 即变更,办公室访问时 IP 亦不同。IP 变动导致 SSH 无法连接,只能手动修改腾讯云控制台防火墙规则。
单台服务器尚可操作,多台则繁琐——需逐一登录控制台,删除旧规则、新增 IP 及端口配置,重复操作易错且枯燥。
起初,我编写 Python 单文件脚本实现自动化。随着功能增加,代码行数从 200 涨至 483,维护难度增大,遂重构为完整 Python 包并开源。
这就是 lighthouse-fw。
核心功能
一句话总结:自动获取公网 IP,批量更新多台 Lighthouse 服务器防火墙白名单规则。
具体能力:
-
• IP 自动探测:多源获取当前公网 IPv4,单源故障自动切换 -
• 增量更新:仅修改需变更规则,保留其他配置,降低误删风险 -
• 多服务器批量操作:单命令更新全部服务器,单台失败不影响整体 -
• TUI + CLI 双模式:支持终端图形界面与命令行操作 -
• 密钥安全存储:优先使用系统钥匙串,回退至本地加密文件 -
• Dry-run 预览:执行前展示差异比对,确认无误后写入
快速开始
安装
无需克隆仓库或 pip 安装,直接使用 uv[2]:
uvx lighthouse-fw
自动下载运行,首次执行进入 TUI 界面。
或安装命令工具:
uv tool install lighthouse-fw
lhfw
初始化配置
lhfw init
于系统标准目录创建配置文件与状态目录。
添加凭据
# 设置凭据元信息(region、endpoint 等)
lhfw credential set my-cred --region ap-guangzhou
# 交互式输入 SecretId 和 SecretKey
lhfw credential set-secret my-cred
密钥自动存入系统钥匙串(Windows Credential Manager/macOS Keychain/Linux Secret Service)。若无安全钥匙串,回退至 Fernet 加密本地文件。
添加服务器
lhfw server set my-server \
--instance-id lhins-xxxxxx \
--credential my-cred \
--tag prod \
--tag cn \
--enabled
添加防火墙规则
# SSH 白名单,CIDR 填 AUTO 自动替换为当前公网 IP/32
lhfw server rule-add my-server \
--protocol TCP \
--port 22 \
--cidr AUTO \
--description "SSH"
# HTTP
lhfw server rule-add my-server \
--protocol TCP \
--port 80 \
--cidr 0.0.0.0/0 \
--description "HTTP"
预览与执行
# 预览变更内容
lhfw run
# 确认后实际写入
lhfw run --apply
run 先进行 dry-run 展示差异(红色删除、绿色新增),确认后才调用 API 写入。
TUI 终端图形界面
运行 lhfw 或 lighthouse-fw 进入 TUI:
uvx lighthouse-fw
TUI 基于 Textual[3],含四个标签页:
Servers — 管理服务器列表,支持新增、编辑、批量操作及 tag 过滤。编辑时可内联管理防火墙规则。
Credentials — 管理凭据,密钥字段默认隐藏,支持临时显示。
Run — 执行面板。支持 tag 批量选中、差异预览、一键应用,底部 RichLog 实时显示日志。
History — 查看最近 20 次执行记录,含时间、模式、IP 及结果摘要。
Apply 前弹出确认对话框展示完整差异,需手动确认执行。
核心设计:增量 Diff 引擎
关键设计原则:增量更新而非全量覆盖。
全量覆盖风险高:删除全部规则后再写入,一旦出错将导致防火墙失效。
增量更新逻辑:
-
1. 获取服务器当前防火墙规则 -
2. 对比用户定义的 managed_rules与现有规则 -
3. 仅计算需变更部分(删除/新增) -
4. 执行变更
匹配基于 protocol + port + action 三元组。规则协议、端口、动作匹配但 CIDR 不同时,删除旧规则并创建新规则;完全一致则跳过。
核心机制 AUTO:配置中 cidr="AUTO" 运行时自动替换为当前公网 IP 的 /32 地址:
def _build_desired_rule(managed_rule, current_ipv4):
cidr = managed_rule.cidr
if cidr == "AUTO":
cidr = f"{current_ipv4}/32"
return RuleSpec(
protocol=managed_rule.protocol,
port=managed_rule.port,
cidr=cidr,
action=managed_rule.action,
description=managed_rule.description,
)
另优化腾讯云乐观锁机制:每次修改传入 FirewallVersion。删除规则后重新查询最新版本,避免冲突。
安全设计
密钥存储
密钥不存于配置文件,采用三级策略:
-
1. 系统钥匙串(优先):Windows Credential Manager、macOS Keychain、Linux Secret Service -
2. 加密文件(回退):使用 cryptography库的 Fernet 对称加密 -
3. 环境变量(兼容):支持 secret_id_env/secret_key_env指定变量名
自动检测系统钥匙链安全性,若为 plaintext 或 fail 则切换至加密文件模式。
操作确认
所有写入操作需显式确认:
-
• CLI 模式: lhfw run --apply展示 diff 后调用typer.confirm() -
• TUI 模式:弹出 Modal 确认对话框 -
• 仅 --yes标志可跳过(用于自动化脚本)
错误隔离
批量执行时,各服务器独立处理异常,单台失败不影响其他。最终汇总完整报告。
命令行速查
lhfw doctor # 环境与凭据健康检查
lhfw run # 预览 enabled 服务器差异
lhfw run --apply # 执行更新
lhfw run --tag prod --tag sg # tag 过滤
lhfw run --apply --yes # 跳过确认
lhfw config show # 查看配置
lhfw config history # 执行历史
lhfw credential list # 凭据列表
lhfw server list # 服务器列表
lhfw server rule-list my-srv # 服务器规则查询
旧脚本迁移
旧版 tencent_lighthouse_fw.toml 配置可一键导入:
lhfw import-legacy ./tencent_lighthouse_fw.toml
自动迁移 defaults、credentials、servers 及 managed_rules 配置。
技术栈
|
|
|
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
要求 Python >= 3.11,数据模型使用 @dataclass(frozen=True, slots=True) 保障不可变性。
CI/CD
采用 GitHub Actions 实现:
-
• CI:每次推送触发,跨平台运行单元测试与冒烟测试 -
• CD: v*.*.*标签自动构建发布至 PyPI
版本号由 git tag 动态决定,pyproject.toml 不硬编码版本。
发布使用 PyPI Trusted Publishing,通过 GitHub OIDC 令牌认证,免维护 API Token。配置指南见 docs/pypi-trusted-publisher.md。
写在最后
本工具解决腾讯云轻量服务器 IP 变动导致 SSH 断连的痛点。
仓库地址:https://github.com/star-plan/tencent-lighthouse-fw
欢迎提交 issue 与 PR。
引用链接
lighthouse-fw: https://github.com/star-plan/tencent-lighthouse-fw[2] uv: https://docs.astral.sh/uv/[3] Textual: https://textual.textualize.io/
</

