From 3b6a0fb00254edd9ccd5b3c988bd765cdd0fbef0 Mon Sep 17 00:00:00 2001 From: qing <1776177662@qq.com> Date: Mon, 10 Aug 2026 09:56:41 +0000 Subject: [PATCH] =?UTF-8?q?captcha2:=20=E8=BF=81=E7=A7=BB=20captcha.ini=20?= =?UTF-8?q?=E8=87=B3=20CLI=20args=EF=BC=8C=E7=A7=BB=E9=99=A4=20confs=20?= =?UTF-8?q?=E4=BE=9D=E8=B5=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - captcha2/src/main.cpp: 移除 fetch_config_from_confs/merge_ini/RpcClient, 扩展 CLI 至 11 项(--instance/--log-level/--len/--ttl/--font-path/ --max-store/--rate-limit),配置优先级 CLI > env > 默认值 - core/services.yaml: captcha2 全部 8 项参数迁入 CLI args - confs/configs/captcha.ini: 已删除 - README.md: 移除 captcha.ini 表行 - _inst.sh: 新增 inst_module captcha2 --- README.md | 1 - _inst.sh | 1 + captcha2/src/main.cpp | 117 +++++++++++--------------------------- confs/configs/captcha.ini | 11 ---- core/services.yaml | 25 +++++++- 5 files changed, 56 insertions(+), 99 deletions(-) delete mode 100644 confs/configs/captcha.ini diff --git a/README.md b/README.md index a093eaf..7d27e36 100755 --- a/README.md +++ b/README.md @@ -209,7 +209,6 @@ |----------|----------|----------| | `gateway.ini` | gateway | confs 拉取(0.7.0 起配置完全迁入) | | `static.ini` | static(fsys.py)/ fsys | 强依赖(拉取失败直接退出) | -| `captcha.ini` | captcha / captcha2 | confs 拉取 | | `example.ini` | —(旧 gateway 示例模板) | 无消费方 | - **部署安全约定**:`confs/configs/*.ini` 含敏感字段,权限必须收紧为 `root:root 0640`,仅 root 可写;被同机普通用户篡改可劫持对应服务(详见 `docs/security/core_SECURITY_AUDIT_20260801.md` 2026-08-10 复审)。原 `ca.ini` 管理员白名单已随 ca v1.1.0 迁入 `core/services.yaml` 的 CLI args;原 `smtp.ini` 全部配置已随 smtp3 迁入 `core/services.yaml` 的 CLI args(SMTP 凭据仍经 `.env` 注入),防护对象相应转为 `services.yaml` 与 `.env` 的文件权限。 diff --git a/_inst.sh b/_inst.sh index de732f6..8e9f43b 100755 --- a/_inst.sh +++ b/_inst.sh @@ -42,6 +42,7 @@ inst_module "db2" inst_module "smtp" inst_module "smtp3" inst_module "captcha" +inst_module "captcha2" inst_module "confs" inst_module "ai_review" # 需联网拉 chromadb onnx 模型(_fetch_onnx_model.sh 走 ModelScope 镜像) inst_module "aibox" # 需 ~/.cert/deepseek.key(见 _setenv.sh) diff --git a/captcha2/src/main.cpp b/captcha2/src/main.cpp index fcb808d..07d7a2b 100644 --- a/captcha2/src/main.cpp +++ b/captcha2/src/main.cpp @@ -10,7 +10,6 @@ #include #include -#include #include #include @@ -70,70 +69,7 @@ struct CaptchaConfig { int rate_limit_per_min = 600; // P1-1: 全局限流仅作最后防线,主要限流由 gateway 按 IP 负责 }; -// 从 confs 拉取 captcha.ini 全文,阻塞等待 confs 就绪 -static std::string fetch_config_from_confs(const std::string& confs_host, int confs_port) { - pmc::net::RpcClient client(confs_host, confs_port, "captcha2", - /*timeout=*/5.0, /*retry_on_refused=*/true); - try { - auto data = client.call("get", {{"name", "captcha.ini"}}); - auto* content = data.as_object().if_contains("content"); - if (!content || !content->is_string()) { - std::cerr << "[captcha2] confs 返回的 captcha.ini 无 content 字段" << std::endl; - std::exit(1); - } - return json::value_to(*content); - } catch (const std::exception& e) { - std::cerr << "[captcha2] 致命错误: 从 confs 获取 captcha.ini 失败: " << e.what() << std::endl; - std::exit(1); - } -} - -// 把 ini 文本合并进 config(仅覆盖已知 section/key,白名单策略) -static void merge_ini(CaptchaConfig& cfg, const std::string& text) { - std::istringstream stream(text); - std::string line, section; - while (std::getline(stream, line)) { - // trim - auto start = line.find_first_not_of(" \t\r"); - if (start == std::string::npos || line[start] == '#' || line[start] == ';') - continue; - auto end = line.find_last_not_of(" \t\r"); - line = line.substr(start, end - start + 1); - - if (line.front() == '[' && line.back() == ']') { - section = line.substr(1, line.size() - 2); - continue; - } - auto eq = line.find('='); - if (eq == std::string::npos) continue; - std::string key = line.substr(0, eq); - std::string val = line.substr(eq + 1); - // trim key - auto ke = key.find_last_not_of(" \t"); - if (ke != std::string::npos) key = key.substr(0, ke + 1); - auto ks = key.find_first_not_of(" \t"); - if (ks != std::string::npos) key = key.substr(ks); - // trim val - auto vs = val.find_first_not_of(" \t"); - if (vs != std::string::npos) val = val.substr(vs); - auto ve = val.find_last_not_of(" \t"); - if (ve != std::string::npos) val = val.substr(0, ve + 1); - - if (section == "server") { - if (key == "host") cfg.host = val; - else if (key == "port") cfg.port = parse_int(key, val); - else if (key == "workers") cfg.workers = parse_int(key, val); - } else if (section == "captcha") { - if (key == "len") cfg.len = parse_int(key, val); - else if (key == "ttl") cfg.ttl = parse_int(key, val); - else if (key == "font_path") cfg.font_path = val; - else if (key == "max_store") cfg.max_store = parse_int(key, val); - else if (key == "rate_limit_per_min") cfg.rate_limit_per_min = parse_int(key, val); - } - } -} - -// 环境变量覆盖(最高优先级,Docker 兼容) +// 环境变量覆盖(Docker 兼容;CLI > 环境变量 > 默认值) static void apply_env_overrides(CaptchaConfig& cfg) { if (auto* v = std::getenv("LISTEN_ADDR")) cfg.host = v; if (auto* v = std::getenv("LISTEN_PORT")) cfg.port = parse_int("LISTEN_PORT", v); @@ -530,20 +466,24 @@ static const auto _log_init = (LogC::instance().set_service_name("captcha2-log") int main(int argc, char* argv[]) { try { // ── 命令行参数 ── - std::string confs_host = "127.0.0.1"; - int confs_port = 8010; - { - const char* env; - if ((env = std::getenv("CONFS_HOST"))) confs_host = env; - if ((env = std::getenv("CONFS_PORT"))) confs_port = std::stoi(env); - } - po::options_description desc("captcha2 — pymsg 验证码服务"); desc.add_options() ("help,h", "显示帮助") - ("addr,a", po::value(), "监听地址(覆盖 confs)") - ("port,p", po::value(), "监听端口(覆盖 confs)") - ("workers,w", po::value(), "工作线程数(覆盖 confs)"); + ("instance", po::value()->default_value("captcha2"), + "实例名(注册中心用)") + ("log-level", po::value()->default_value("info"), + "日志级别(debug|info|warn|error)") + ("addr,a", po::value(), "监听地址") + ("port,p", po::value(), "监听端口") + ("workers,w", po::value(), "工作线程数") + ("len", po::value(), "验证码长度(2~8,默认 4)") + ("ttl", po::value(), "验证码有效期秒数(默认 300)") + ("font-path", po::value(), + "TrueType 字体路径") + ("max-store", po::value(), + "内存中最大待验证 token 数(默认 10000)") + ("rate-limit", po::value(), + "全局每分钟生成上限(默认 600)"); po::variables_map vm; po::store(po::parse_command_line(argc, argv, desc), vm); po::notify(vm); @@ -553,20 +493,27 @@ int main(int argc, char* argv[]) { return 0; } - // ── 配置加载:confs → env → 命令行 ── - std::string ini_text = fetch_config_from_confs(confs_host, confs_port); - merge_ini(g_config, ini_text); - + // ── 配置加载:CLI > 环境变量 > 默认值 ── apply_env_overrides(g_config); - if (vm.count("addr")) g_config.host = vm["addr"].as(); - if (vm.count("port")) g_config.port = vm["port"].as(); - if (vm.count("workers")) g_config.workers = vm["workers"].as(); + if (vm.count("addr")) g_config.host = vm["addr"].as(); + if (vm.count("port")) g_config.port = vm["port"].as(); + if (vm.count("workers")) g_config.workers = vm["workers"].as(); + if (vm.count("len")) g_config.len = vm["len"].as(); + if (vm.count("ttl")) g_config.ttl = vm["ttl"].as(); + if (vm.count("font-path")) g_config.font_path = vm["font-path"].as(); + if (vm.count("max-store")) g_config.max_store = vm["max-store"].as(); + if (vm.count("rate-limit")) g_config.rate_limit_per_min = vm["rate-limit"].as(); validate_config(g_config); - std::cerr << "[captcha2] 配置来源: confs captcha.ini @ " - << confs_host << ":" << confs_port << std::endl; + // 日志级别 + std::string log_level = vm["log-level"].as(); + std::string instance = vm["instance"].as(); + g_log.set_level(log_level); + + std::cerr << "[captcha2] instance=" << instance << " log-level=" << log_level << std::endl; + std::cerr << "[captcha2] 配置来源: CLI > 环境变量 > 默认值" << std::endl; std::cerr << "[captcha2] captcha_len=" << g_config.len << " ttl=" << g_config.ttl << " max_store=" << g_config.max_store diff --git a/confs/configs/captcha.ini b/confs/configs/captcha.ini deleted file mode 100644 index d1a76af..0000000 --- a/confs/configs/captcha.ini +++ /dev/null @@ -1,11 +0,0 @@ -[server] -host = 127.0.0.1 -port = 8009 -workers = 4 - -[captcha] -len = 4 -ttl = 300 -font_path = /usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf -max_store = 10000 -rate_limit_per_min = 600 # 全局限流仅作最后防线,主要限流由 gateway 按 IP 负责 diff --git a/core/services.yaml b/core/services.yaml index d86fe0f..69e01a4 100644 --- a/core/services.yaml +++ b/core/services.yaml @@ -145,9 +145,30 @@ services: # --- 验证码 --- - name: captcha2 cmd: bash /opt/micro_servers/captcha2/_run.sh - args: ["--instance", "captcha2", "--log-level", "info"] + args: + - "--instance" + - "captcha2" + - "--log-level" + - "info" + # --- 配置全部经 CLI 传递(原 confs/configs/captcha.ini 迁入) --- + - "--addr" + - "127.0.0.1" + - "--port" + - "8009" + - "--workers" + - "4" + - "--len" + - "4" + - "--ttl" + - "300" + - "--font-path" + - "/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf" + - "--max-store" + - "10000" + - "--rate-limit" + - "600" depends_on: [] - sleep_before: 1 + sleep_before: 0 # --- AI 工具箱 --- - name: aibox