# update-proxy-cert-client-tui **Repository Path**: rymaker/update-proxy-cert-client-tui ## Basic Information - **Project Name**: update-proxy-cert-client-tui - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-07-13 - **Last Updated**: 2026-07-24 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # singbox-cert-tui Terminal UI tool for managing pinned certificates in [sing-box](https://github.com/sagernet/sing-box) / [mihomo](https://github.com/MetaCubeX/mihomo) proxy configurations. ## Features - **Config scanning** — Automatically discover sing-box/mihomo config files in a directory - **Certificate fetching** — Retrieve live certificates from remote servers (supports TCP and QUIC) - **Certificate preview** — Side-by-side comparison of pinned vs. live certificates - **Safe commit** — Update config files with automatic backup before writing - **Service restart** — Optionally restart the systemd service after commit - **Unattended mode** — `--apply` for cron / systemd-timer automation across multiple configs - **JSON & YAML** — Supports both JSON and YAML config formats - **Signature verification** — Validate config integrity with sing-box before saving ## Installation ```bash npm install -g singbox-cert-tui ``` Or run directly with npx: ```bash npx singbox-cert-tui [directory] ``` ## Requirements - **Node.js** >= 20.0.0 - **OpenSSL >= 3.4** (for QUIC certificate fetching; older versions lack `-quic`) - **sing-box** binary (optional, for config validation) > **OpenSSL too old?** If your system OpenSSL is below 3.4, use the bundled > build script to compile a local copy (doesn't touch system OpenSSL): > > ```bash > # Linux / macOS > ./scripts/build-openssl.sh # default 3.4.0 > ./scripts/build-openssl.sh 3.5.0 # specify version > > # Windows (in Developer PowerShell for VS) > ./scripts/build-openssl.ps1 > ./scripts/build-openssl.ps1 -Version 3.5.0 > ``` > > Then point the tool at it: `singbox-cert-tui --openssl ./scripts/openssl-dist/bin/openssl` ## Usage ```bash # Scan current directory for config files singbox-cert-tui # Scan a specific directory singbox-cert-tui /etc/sing-box/ # Specify custom OpenSSL and sing-box paths singbox-cert-tui /etc/sing-box/ --openssl /usr/bin/openssl --singbox /usr/bin/sing-box # Auto-restart service after commit singbox-cert-tui /etc/sing-box/ --service sing-box # Control backup retention singbox-cert-tui /etc/sing-box/ --backup-keep 10 # Non-interactive mode (preview only, no changes) singbox-cert-tui /etc/sing-box/ --non-interactive # Unattended mode: fetch & commit updates for one or more files/directories singbox-cert-tui /var/www/html/hysteria /var/www/html/hysteria/test --apply --service sing-box ``` ## Automation (unattended updates) Ready-made files live in `deploy/`: `singbox-cert-update.service` + `.timer` (unit files) and `test-apply.sh` (server-side check & trial-run script — run it once without arguments for a read-only preview, then with `--apply` to write for real). `--apply` runs without any interaction: for each given file/directory (directories are scanned top-level only, duplicates are skipped) it fetches live certificates, commits every changed node (with the usual backup + atomic write), and restarts the systemd service **once at the end** if anything was written. Exit codes for scripting/monitoring: - `0` — ran clean, including "everything already up to date" - `1` — a path was invalid or a commit failed (per-node fetch errors are logged but do **not** fail the run; that node is simply left untouched) Example daily systemd timer: ```ini # /etc/systemd/system/singbox-cert-update.service [Unit] Description=Update pinned certificates in proxy configs Wants=network-online.target After=network-online.target [Service] Type=oneshot ExecStart=/usr/local/bin/singbox-cert-tui /var/www/html/hysteria /var/www/html/hysteria/test --apply --service sing-box ``` ```ini # /etc/systemd/system/singbox-cert-update.timer [Unit] Description=Daily pinned-certificate update [Timer] OnCalendar=*-*-* 04:17:00 Persistent=true [Install] WantedBy=timers.target ``` ```bash sudo systemctl daemon-reload sudo systemctl enable --now singbox-cert-update.timer journalctl -u singbox-cert-update.service # view run logs ``` > QUIC nodes (TUIC/Hysteria) additionally need OpenSSL 3.4+ on the server — see > Requirements above. TCP/TLS nodes work without it. ## Workflow The interactive mode is a keyboard-driven dashboard: 1. **Select config** — Pick a directory preset (or enter a custom path), then a config file 2. **Scan** — The dashboard lists all pinned-certificate nodes with their current fingerprints 3. **Fetch** — Press `f` to retrieve live certificates; nodes with updates are marked and pre-selected 4. **Commit** — Adjust the selection with `space`/`a`, then press `c` to write changes (automatic backup) Keys: `f` fetch · `space`/`Enter` toggle node · `a` toggle all · `c` commit · `r` rescan · `o` open another config · `h` help · `q` quit ## Development ```bash # Install dependencies npm install # Run in development mode npm run dev # Run tests npm test # Build npm run build ``` ## Project Structure ``` src/ ├── bin/singbox-cert-tui.ts # CLI entry point ├── core/ │ ├── types.ts # Type definitions │ ├── config.ts # Config file parsing │ ├── fetch.ts # Certificate fetching │ ├── config.test.ts # Config tests │ └── updater.ts # Config update logic └── tui/ ├── index.ts # TUI orchestration ├── scanner.ts # Config file scanner ├── dashboard.ts # Interactive blessed dashboard ├── preview.ts # Non-interactive preview output ├── format.ts # Output formatting └── ui/ # blessed UI primitives (theme, dialogs, picker) scripts/ ├── build-openssl.sh # Build OpenSSL 3.4+ from source (Linux/macOS) └── build-openssl.ps1 # Build OpenSSL 3.4+ from source (Windows) deploy/ ├── singbox-cert-update.service # systemd oneshot unit for --apply ├── singbox-cert-update.timer # daily timer └── test-apply.sh # server-side check + trial-run script ``` ## License MIT