把 ComfyUI 放到公网前要想清楚的事

2026-08-09

「我在服务器上装了 ComfyUI,同事访问不了」——这个问题的答案是 --listen。但很多人加完这个参数、发现同事能访问了,就停在这儿了。真正该问的是下一个问题:加上这个参数之后,还有谁能访问?

这篇不打算给你一份「安全部署清单」。ComfyUI 在这件事上的官方边界比大多数人以为的要窄,硬把它包装成一套完备方案,反而会误导人。下面按你的实际处境,一层层往下走。

先确认你到底在哪一档

在动任何参数之前,先把自己归到下面三种处境里的一种。后面所有结论都随这个分档变化。

第一档:只有你自己用,机器就在手边。 这一档什么都不用做。以 v0.31.0(2026-08-08)的 comfy/cli_args.py 为准,--listen 的默认值是 127.0.0.1,也就是只监听本机回环地址。你不加参数,它就不对外。这是个好默认值,别去动它。

第二档:局域网内几个人共用一台带卡的机器。 这一档需要 --listen,但要非常清楚你写了什么。

第三档:想让 ComfyUI 跑在公网上,随时随地能开。 这一档我的建议是:先看完下面「官方给了什么、没给什么」那一节,再决定要不要继续。

--listen 的两种写法差别很大

comfy/cli_args.py(v0.31.0)里这个参数的 help 说得很清楚:指定监听 IP,可以逗号分隔多个地址,比如 127.2.2.2,127.3.3.3不带参数使用 --listen 时,它等于 0.0.0.0,::,也就是同时监听所有 IPv4 和所有 IPv6 网卡。

这个设计其实挺反直觉的。argparse 里一个参数「可选带值」的写法,让 --listen--listen 192.168.1.50 变成了安全性质完全不同的两条命令,而命令行上看起来只差几个字符。裸写 --listen 意味着这台机器上任何一张网卡能到达的地方都能到达 ComfyUI ——如果这台机器同时插着内网和公网,或者跑在一台有公网 IP 的云主机上,你以为的「让同事能访问」,实际范围要大得多。

所以第二档的处置是:--listen 显式写上那张内网网卡的地址,而不是裸写。这不是什么高级技巧,只是把参数用完整。

顺带说一句判断方法:如果你的现象是「局域网访问不到」,第一步就是确认启动命令里到底有没有 --listen,而不是先去翻防火墙。默认只听本机这件事,是「明明起来了却连不上」最先该排除的一条。

顺手会被打开的两个口子

--listen 的时候,很多人会一并抄来另外两个参数,这两个都值得单独说。

--enable-cors-header [ORIGIN],默认是 None(即不启用)。它可以指定一个 origin,但不带参数时值为 *,等于允许所有来源。同样是「可选带值」的坑:如果你只是为了让某个自己写的前端页面能调 ComfyUI,那就把那个 origin 写出来,别用裸的 --enable-cors-header

--max-upload-size 是 float,默认 100,单位 MB。这个默认值在本机自己用的时候几乎没人注意,但在对外开放的实例上,它就是别人往你磁盘里写数据的单次上限。ComfyUI 没有把它默认为 0 或者无限,说明官方本身给了一个约束值;你要调,最好是往小了调,而不是因为一次上传失败就顺手加个零。

官方给了什么,没给什么

这是全篇最关键的一节,也是我认为很多「ComfyUI 公网部署教程」讲糊涂了的地方。

TLS:给了,但官方自己划了线。 --tls-keyfile--tls-certfile 这两个参数必须成对给出才生效——help 里两条互相点名对方。README 给了一条生成自签证书的命令:

openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -sha256 -days 3650 -nodes -subj "/C=XX/ST=StateName/L=CityName/O=CompanyName/OU=CompanySectionName/CN=CommonNameOrHostname"

然后用 --tls-keyfile key.pem --tls-certfile cert.pem 启动,之后走 https://。README 同时给 Windows 用户指了路:可以用 alexisrolland/docker-openssl 或第三方 OpenSSL 二进制发行版来执行这条命令,容器场景下 -v 支持相对路径,例如 ... -v ".\:/openssl-certs" ... 会把 key 和 cert 生成到当前目录。

但 README 对这个自签证书写了一句话,必须原样带出来:它 “not appropriate for shared/production use”(不适合共享或生产使用)。也就是说,官方给的 TLS 示例是给你本地自己加密链路用的,官方并没有说这套配置可以拿去做多人共享或生产环境。你想上生产,证书这一环得自己另想办法,而那部分不在 ComfyUI 的文档范围内。

认证:这是最需要说清楚的一格。 用户名密码认证在官方仓库里至今仍是一个 open 的 feature request——issue #987,创建于 2023-07-27,标签为 Feature,截至 2026-08-09 仍为 open,有 26 个 reactions。另一方面,v0.23.0(2026-06-01)里确实新增过 OAuth 2.1 与 RFC 7591 动态客户端注册(DCR)端点(PR #14026)。

这两条不冲突,但都不足以让我下任何断言。我没有读过 #987 的正文与评论,也没有验证过那组 OAuth 端点覆盖哪些路径、在什么条件下生效。所以我能说的只有事实本身:一个「加用户名密码」的请求开了三年还开着;同时仓库里有过一次 OAuth 相关的端点新增。你不能据此得出「ComfyUI 没有任何鉴权」,也不能据此得出「ComfyUI 已经有可用的登录保护」。真要判断,得自己去读那部分代码和端点行为。

另有一个相关参数是 --multi-user,help 的意思是启用按用户分离的存储。注意这是存储隔离,别把它读成身份认证。

nginx、防火墙、VPN 呢? 这类做法在部署这件事上当然是常规操作,但我必须标明:这属于通用运维做法,不是 ComfyUI 官方文档里的内容。ComfyUI 的 README 和 cli_args.py 里没有任何反向代理配置、防火墙规则或访问控制方案。你在网上看到的那些 nginx 片段,来源是运维经验而不是这个项目的官方推荐,选用与否、配得对不对,责任在你自己身上。

版本这一关先过

参数配得再细,跑在有已知问题的版本上也没意义。

在 ComfyUI 的 GitHub Security Advisories 里,我们取到了四条已披露条目,全部于 2026-07-15 发布,严重等级均为 high,修复版本均为 0.28.0

GHSA ID等级官方 summary(原意)
GHSA-rj8c-c4p8-3c5hhigh通过 /view 端点上传 SVG 导致的存储型 XSS
GHSA-53g8-45wq-pcv8high/userdata/{file} 缺少 Content-Type 处理导致的存储型 XSS
GHSA-rvxv-29p8-pxgqhighLoadImage 经 /prompt API 的路径穿越,可探测任意文件是否存在并外传图片
GHSA-pj59-g5vv-74q4high/experiment/models/preview 的路径穿越,可读取任意图片文件

对应的 release note 在 v0.28.0(2026-07-15):「security: fix four vulnerabilities (GHSA-779p-m5rp-r4h4)」,PR #14734。

这是本文唯一一条我愿意说得很硬的结论:运行 0.28.0 之前版本的实例存在上述四个 high 级问题,官方修复版本是 0.28.0。如果你打算对外开放,先把版本抬到 0.28.0 或更高,这一步没有讨价还价的余地。至于漏洞的利用方式、复现步骤、CVSS 分值,我这边没有依据,也不会写。

这里还有个值得记住的教训:那个安全修复本身引出过一个回归——v0.30.0(2026-08-03)有一条「Fix user.css loading broken by #14734」(PR #15000),也就是说前端 user.css 的加载被安全修复搞坏了,两周后才修回来。安全补丁不是零成本的,升级之后该验的还得验。另外 v0.30.0 还加了一条「Add dataset folder to avoid arbitrary folder access for dataset stuff」(PR #14807),也属于收窄访问面的改动。

第三方节点这一层,官方给的是开关不是保证

社区在 issue #11791 中报告了通过 Comfy Registry 分发的、名为 Upscaler_4K 的自定义节点携带 Akira Stealer 的情况,该 issue 创建于 2026-01-10,截至 2026-08-09 仍为 open。我没有读过这条 issue 的正文与评论,具体行为、影响范围、清除办法都不在我能说的范围内——但它足以说明一件事:自定义节点是会执行代码的第三方内容,一个对外开放的实例上装着一堆来路不同的节点,这两件事叠在一起需要你自己权衡。

官方在 cli_args.py(v0.31.0)里给的相关开关有这么几个:

  • --disable-all-custom-nodes:不加载任何自定义节点
  • --whitelist-custom-nodes NAME [...]:在上一条开启时,仍然加载指定的节点目录
  • --disable-api-nodes:不加载所有 api 节点,同时阻止前端与互联网通信
  • --disable-manager-ui:只禁用 Manager 的 UI 与端点,但 README 说明后台任务(安全检查、计划安装完成等)仍会运行

这四个开关的组合可以帮你把一台对外实例收得很窄:只跑你自己审过的节点、切断前端外联。README 也提到 ComfyUI 可以完全离线运行,核心不会主动下载任何东西,除非你要求。

但我不会写「这样配就安全了」。这些是官方提供的开关,不是官方给的安全保证,二者差别很大。

一条按语义组合的示例,以及验收要点

如果你是第二档(内网几个人共用),把上面几条落到一条启动命令上大致是这样:

python main.py --listen <你的内网网卡 IP> --max-upload-size <你需要的上限MB> --disable-api-nodes

两个尖括号里的值按你自己的环境填,别照抄。逐项说明为什么在这:--listen 写成具体内网地址而不是裸参数,避免变成 0.0.0.0,::--max-upload-size 从默认 100 收到一个你实际需要的值;--disable-api-nodes 切断前端外联并关掉可选的付费 API 节点。以上为按官方参数语义组合的示例,未逐项实测,以官方文档与 python main.py --help 的实际输出为准。

验收时人要看的是这几处:启动后从另一台机器按你写的那个地址访问,确认能通;再从你不希望它被访问到的位置试一次,确认结果和你的预期一致——--listen 只约束监听哪张网卡,网络层能不能到达还取决于你自己的网络环境,这一层官方文档不管。另外,--tls-keyfile--tls-certfile 如果只给了一个,按 help 的说法 TLS 是不会生效的,别看到进程起来了就当配好了,得确认地址栏走的是 https://

什么情况下这套思路不适用

如果你的需求是「给不特定的人提供在线出图服务」,那这篇讲的都不够用。ComfyUI 的官方边界停在参数语义这一层:默认只听本机、TLS 需要成对参数且自签证书官方说不适合生产、用户名密码认证仍是 open 的 feature request。再往外就是通用运维和你自己的安全工程了,那部分没有官方文档兜底。

反过来,如果你只是想在自家沙发上用平板连一下书房那台机器,第二档那条命令加上内网地址基本就够了,别把公网那套复杂度扛回家。

延伸阅读


本文依据 ComfyUI 官方仓库(github.com/Comfy-Org/ComfyUI)的 README、comfy/cli_args.py、release notes 与官方安全公告整理,核对日 2026-08-09,对应版本 v0.31.0;文中引用的 issue 状态为该日期的快照。本文内容为官方文档与源码口径,非本机实测。参数、默认值与功能随版本变动,请以官方文档与 python main.py --help 的实际输出为准。安全公告信息来自 GitHub Security Advisories,本文不含漏洞利用细节。

想系统学会用 AI?报名体系课或加入会员,照着学、照着用。