diff --git a/README.md b/README.md index 8843d205..f550ef5b 100644 --- a/README.md +++ b/README.md @@ -204,7 +204,8 @@ cow install-browser "group_speech_recognition": false, # 是否开启群组语音识别 "voice_reply_voice": false, # 是否使用语音回复语音 "use_linkai": false, # 是否使用 LinkAI 接口,默认关闭,设置为 true 后可对接 LinkAI 平台模型 - "web_password": "", # Web 控制台访问密码,留空则不启用密码保护 + "web_host": "0.0.0.0", # Web 控制台监听地址,设为 "127.0.0.1" 表示仅本机可访问 + "web_password": "", # Web 控制台访问密码,留空则不启用密码保护(公网部署强烈建议设置) "agent": true, # 是否启用 Agent 模式,启用后拥有多轮工具决策、长期记忆、Skills 能力等 "agent_workspace": "~/cow", # Agent 的工作空间路径,用于存储 memory、skills、系统设定等 "agent_max_context_tokens": 50000, # Agent 模式下最大上下文 tokens,超出将自动智能压缩处理 @@ -719,6 +720,7 @@ Coding Plan 是各厂商推出的编程包月套餐,所有厂商均可通过 O } ``` +- `web_host`: 默认为 `0.0.0.0`(所有网卡可访问),如只在本机使用可改为 `127.0.0.1` 仅监听本地 - `web_port`: 默认为 9899,可按需更改,需要服务器防火墙和安全组放行该端口 - `web_password`: 访问密码,留空则不启用密码保护。部署在公网环境时建议设置 - 如本地运行,启动后请访问 `http://localhost:9899/chat` ;如服务器运行,请访问 `http://ip:9899/chat` diff --git a/channel/web/web_channel.py b/channel/web/web_channel.py index 1e01cb98..f539fc29 100644 --- a/channel/web/web_channel.py +++ b/channel/web/web_channel.py @@ -696,7 +696,10 @@ class WebChannel(ChatChannel): return f.read() def startup(self): + host = conf().get("web_host", "0.0.0.0") port = conf().get("web_port", 9899) + # Treat wildcard binds as public exposure for the security hint below. + is_public_bind = host in ("0.0.0.0", "", "::") # 打印可用渠道类型提示 logger.info( @@ -712,7 +715,10 @@ class WebChannel(ChatChannel): logger.info("[WebChannel] 9. wechatmp_service - 企业公众号") logger.info("[WebChannel] ✅ Web控制台已运行") logger.info(f"[WebChannel] 🌐 本地访问: http://localhost:{port}") - logger.info(f"[WebChannel] 🌍 服务器访问: http://YOUR_IP:{port} (请将YOUR_IP替换为服务器IP)") + if is_public_bind: + logger.info(f"[WebChannel] 🌍 服务器访问: http://YOUR_IP:{port} (请将YOUR_IP替换为服务器IP)") + if not _is_password_enabled(): + logger.info("[WebChannel] 提示:当前未设置 web_password,如需公网部署请配置访问密码") try: import webbrowser @@ -772,7 +778,7 @@ class WebChannel(ChatChannel): # Build WSGI app with middleware (same as runsimple but without print) func = web.httpserver.StaticMiddleware(app.wsgifunc()) func = web.httpserver.LogMiddleware(func) - server = web.httpserver.WSGIServer(("0.0.0.0", port), func) + server = web.httpserver.WSGIServer((host, port), func) server.daemon_threads = True # Default request_queue_size(5) / timeout(10s) / numthreads(10) are # too small: when SSE streams occupy many threads, the backlog fills diff --git a/config.py b/config.py index 95e851c3..5ea6c9c5 100644 --- a/config.py +++ b/config.py @@ -205,6 +205,7 @@ available_setting = { "Minimax_base_url": "", "deepseek_api_key": "", "deepseek_api_base": "https://api.deepseek.com/v1", + "web_host": "0.0.0.0", # Web console bind address; set to "127.0.0.1" to restrict access to localhost only "web_port": 9899, "web_password": "", # Web console password; empty means no authentication required "web_session_expire_days": 30, # Auth session expiry in days diff --git a/docs/channels/web.mdx b/docs/channels/web.mdx index a936a179..073becac 100644 --- a/docs/channels/web.mdx +++ b/docs/channels/web.mdx @@ -10,6 +10,7 @@ Web 控制台是 CowAgent 的默认通道,启动后会自动运行,通过浏 ```json { "channel_type": "web", + "web_host": "0.0.0.0", "web_port": 9899, "web_password": "", "enable_thinking": false @@ -19,6 +20,7 @@ Web 控制台是 CowAgent 的默认通道,启动后会自动运行,通过浏 | 参数 | 说明 | 默认值 | | --- | --- | --- | | `channel_type` | 设为 `web` | `web` | +| `web_host` | Web 服务监听地址,设为 `127.0.0.1` 表示仅本机可访问 | `0.0.0.0` | | `web_port` | Web 服务监听端口 | `9899` | | `web_password` | 访问密码,留空表示不启用密码保护 | `""` | | `web_session_expire_days` | 登录会话有效天数 | `30` | @@ -26,6 +28,10 @@ Web 控制台是 CowAgent 的默认通道,启动后会自动运行,通过浏 配置密码后,访问控制台时需先输入密码完成登录。登录状态默认保持 30 天,期间重启服务也无需重新登录。密码也支持在控制台的「配置」页面中在线修改。 + + 默认监听 `0.0.0.0`(所有网卡可访问),方便本机和局域网/服务器场景开箱即用。**部署到公网时务必设置 `web_password`**,或将 `web_host` 改为 `127.0.0.1` 仅允许本机访问。控制台启动时会自动检测并提示这一风险。 + + ## 访问地址 启动项目后访问: