返回文章列表文章索引阅读全文
STARBLOG / 阅读手记
DevOps

lighthouse-fw: A Terminal Tool for Managing Tencent Cloud Lighthouse Firewalls

Public IP changed and you're still editing the firewall by hand? Call yourself a programmer with that kind of efficiency? An incremental diff engine + system keychain + TUI/CLI dual mode—443 lines refactored into a package, done. Run it with uvx. Don't tell me you still need pip install.

曦远 (DealiAxy)约 24 分钟
目录20 个章节

Background: A Problem That Kept Tormenting Me

I have a few Tencent Cloud Lighthouse instances, and the firewall whitelist is set to my current public egress IP. The problem is, every time my home broadband reconnects, the IP changes; accessing the servers from the office uses a different IP as well. Once the IP changes, SSH stops working, and I have to go to the Tencent Cloud console to edit the firewall rules by hand.

One server is manageable; several of them get annoying—for each one you have to log into the console, find the firewall, delete the old rule, add a new one, fill in the IP, pick the protocol and port… The repetition is both tedious and error-prone.

I originally wrote a single-file Python script to automate this. Features kept piling on, the script grew from 200 lines to 483, and it became hard to maintain. So I refactored it into a full Python package and open-sourced it.

This is lighthouse-fw.

What It Can Do

The core feature in one sentence: automatically get your public IP, then batch-update firewall whitelist rules across multiple Lighthouse servers.

Specifically:

  • IP auto-detection: fetch the current public IPv4 from multiple sources; automatically switch if a single source fails
  • Incremental updates: only change the rules that need changing, leave the rest alone, reducing the risk of accidental deletion
  • Multi-server batch operations: update all servers with one command; a failure on one doesn't affect the others
  • TUI + CLI dual mode: both a terminal GUI and the command line
  • Secure credential storage: prefer the system keychain, fall back to a locally encrypted file
  • Dry-run preview: inspect the diff before applying, write only after confirmation

Quick Start

Install

No need to clone the repo, no need to pip install. Run it directly with uv:

uvx lighthouse-fw

This downloads and runs it automatically; the first run opens the TUI.

If you'd rather install it as a command:

uv tool install lighthouse-fw
lhfw

Initialize Config

lhfw init

This creates the config file and state directory under the system's standard paths.

Add Credentials

# 设置凭据元信息(region、endpoint 等)
lhfw credential set my-cred --region ap-guangzhou

# 交互式输入 SecretId 和 SecretKey(输入时不可见)
lhfw credential set-secret my-cred

Secrets are stored in the system keychain automatically (Windows Credential Manager / macOS Keychain / Linux Secret Service). If the system has no secure keychain backend, it falls back to a Fernet-encrypted local file.

Add a Server

lhfw server set my-server \
  --instance-id lhins-xxxxxx \
  --credential my-cred \
  --tag prod \
  --tag cn \
  --enabled

Add Firewall Rules

# 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"

Preview and Apply

# 先预览,看看会改什么
lhfw run

# 确认没问题后,实际写入
lhfw run --apply

The run command first does a dry-run, shows a diff preview (red for deletions, green for additions), then asks for confirmation. The API write only happens if you type y.

TUI: A GUI in the Terminal

If you don't like typing commands, just run lhfw or lighthouse-fw (with no arguments) to enter the TUI:

uvx lighthouse-fw

The TUI is built on Textual and has four tabs:

Servers — manage the server list: add, edit, multi-select, filter by tag. When editing a server you can manage firewall rules inline.

Credentials — manage credentials; secret fields are hidden by default and can be revealed temporarily when needed.

Run — the execution panel. Multi-select servers by tag, preview the diff, Apply in one click. A RichLog at the bottom streams execution logs in real time.

History — view the last 20 runs, including time, mode (dry-run/apply), IP, and a result summary.

Before Apply, a confirmation dialog pops up showing the full change diff; you have to confirm manually before it runs.

Core Design: Incremental Diff Engine

The most important design decision in lighthouse-fw is incremental updates rather than full overwrite.

Full overwrite is simple—delete every existing rule, then write the new ones. But that's very risky: if something fails in the middle, the server could lose firewall protection entirely.

The incremental-update logic is:

  1. Fetch all current firewall rules on the server
  2. Compare the user-defined managed_rules with the existing rules
  3. Compute only the parts that need to change (what to delete, what to add)
  4. Apply the changes

Matching is based on the protocol + port + action triple. If a rule matches on protocol, port, and action but the CIDR differs (e.g. the IP changed), the old one is deleted and a new one created. If they match completely, it's skipped.

There's a key AUTO mechanism: if you write cidr="AUTO" in the config, at runtime it is automatically replaced with the current public IP as a /32. That means you don't have to hard-code the IP; the tool detects and fills it in.

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,
    )

Another detail is Tencent Cloud's optimistic locking. Every firewall-rule change requires a FirewallVersion number. After deleting rules, lighthouse-fw re-fetches the latest version number before creating, to avoid version conflicts.

Security Design

Secret Storage

lighthouse-fw never writes API secrets into the config file. It has a three-tier storage strategy:

  1. System keychain (preferred): Windows Credential Manager, macOS Keychain, Linux Secret Service/KWallet
  2. Encrypted file (fallback): Fernet symmetric encryption from the cryptography library; the key and the encrypted data are stored separately
  3. Environment variables (compatibility): you can specify env var names via secret_id_env / secret_key_env

The program automatically checks whether the current system's keychain is secure. If it detects a plaintext or fail backend, it automatically switches to encrypted-file mode.

Operation Confirmation

All write operations require explicit confirmation:

  • In CLI mode, lhfw run --apply shows the diff first, then calls typer.confirm() and waits for input
  • In TUI mode, a Modal confirmation dialog pops up
  • Only the --yes flag can skip confirmation (for automation-script scenarios)

Error Isolation

During batch execution, each server has its own try/except. An API failure on one server does not block the others. All results are collected into a single report at the end.

CLI Cheatsheet

lhfw doctor                  # 健康检查(环境 + 凭据可达性)
lhfw run                     # 预览所有 enabled 服务器的 diff
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 # 查看某台服务器的规则

Migrating from the Old Script

If you previously used the old single-file script's tencent_lighthouse_fw.toml config format, you can import it in one command:

lhfw import-legacy ./tencent_lighthouse_fw.toml

It automatically migrates defaults, credentials, servers, and managed_rules, including environment variable names.

Tech Stack

ComponentChoice
CLI frameworkTyper
TUI frameworkTextual
Terminal stylingRich
Config formatTOML (tomllib + tomli-w)
Secret encryptioncryptography (Fernet)
System keychainkeyring
Cross-platform pathsplatformdirs
Tencent Cloud SDKtencentcloud-sdk-python
Build systemHatchling + hatch-vcs
Package manageruv
PublishingPyPI Trusted Publishing (OIDC)

Python >= 3.11; all models use @dataclass(frozen=True, slots=True) to guarantee immutability.

CI/CD

The project uses GitHub Actions for a full CI/CD pipeline:

  • CI: triggered on every push and PR; unit tests and smoke tests run cross-platform (Ubuntu + Windows)
  • CD: pushing a git tag in v*.*.* format automatically builds and publishes to PyPI

The version is determined dynamically from the git tag (via hatch-vcs); it is not hard-coded in pyproject.toml.

Publishing uses PyPI Trusted Publishing, authenticated with a GitHub OIDC token, so you don't have to maintain an API Token. See docs/pypi-trusted-publisher.md in the repo for the detailed setup guide.

Closing

This tool solves a small but annoying problem. If you also use Tencent Cloud Lighthouse and have been bitten by SSH dropping when your IP changes, give it a try.

Repo: https://github.com/star-plan/tencent-lighthouse-fw

Issues and PRs welcome.

_EOF_

lighthouse-fw: A Terminal Tool for Managing Tencent Cloud Lighthouse Firewalls

本文作者:
程序设计实验室
版权声明:
本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!

相关文章

讨论

共 0 条

良言一句三冬暖,恶语伤人六月寒。

加载评论中…