[控场AI]
· 8 分钟阅读· 4,327 字

自托管LiteLLM安全加固清单:master key竟是管理员密码

自托管LiteLLM安全加固清单:master key竟是管理员密码

LiteLLM 代理存在多个默认危险配置与无 CVE 高危漏洞,本文按优先级给出加固步骤。

自托管 LiteLLM 代理掌握团队所有模型供应商的 API Key,但其默认配置存在多个高危风险。文章首先提醒两个没有 CVE 编号的 GHSA 漏洞:GHSA-7hp6-4w63-5g45 允许 internal_user 提权为管理员,GHSA-g5ff-637f-6q2m 允许只读用户读取主机文件,仅靠 CVE 扫描器会漏报。随后给出加固清单:关闭 master key 作为 UI 密码的路径、首次部署即设定永不更改的 LITELLM_SALT_KEY、关闭实验性 UI 登录和 stdio MCP 服务器、将监听地址绑定回环并用反向代理隔离 /ui 与管理路由。最后提供三条 curl 命令验证加固效果,并指向覆盖多种自托管 AI 组件的完整清单。

自托管 LiteLLM 代理通常握着你团队所有模型供应商的 API Key,但它的多个默认配置出乎意料地危险。以下按修复优先级排列,内容全部来自 LiteLLM 官方文档、源码与安全公告。

LiteLLM 安全加固清单来源

先升级:两个没有 CVE 编号的高危漏洞

有两个近期安全公告没有分配 CVE ID,这意味着只依赖 CVE 扫描器的工具不会报警。

GHSA-7hp6-4w63-5g45(CVSS 9.9):从 1.91.0 到 1.100.4(以及 1.101.0-1.101.2、1.102.0-1.102.1、1.103.0)版本中,任何拥有 internal_user 角色的用户都能把自己提权为代理管理员。根因是代理用同一把 key 既加密存储的密钥、又签发会话 token,结果你请求加密的"密文"回来时变成了合法的管理员 token。

GHSA-g5ff-637f-6q2m(高危):1.95.0 之前,拥有只读角色 internal_user_viewer 的用户可通过 vertex_ai_credentials 读取代理主机上的本地文件。该公告在发布时尚未进入 GitHub Advisory Database 或 OSV.dev,pip-audit 扫不出来。

先确认版本,再升级:

curl -s http://127.0.0.1:4000/health/readiness   # 读取 litellm_version

什么是 GHSA 与 CVSS

GHSA 是 GitHub Security Advisory 的缩写,是 GitHub 上发布漏洞公告的官方渠道。许多开源项目的漏洞会先以 GHSA 形式披露,再由 MITRE 分配 CVE ID。因此,在 CVE 正式分配之前,只有订阅 GHSA 或使用 GitHub Advisory Database 的工具才能捕获这些公告,这也是为什么文中两个漏洞会让仅依赖 CVE 扫描器的团队漏报。

CVSS(Common Vulnerability Scoring System)是评估漏洞严重程度的通用评分体系,分值范围 0.0 到 10.0,通常分为低危(0.1-3.9)、中危(4.0-6.9)、高危(7.0-8.9)和严重(9.0-10.0)四档。文中 GHSA-7hp6-4w63-5g45 的 9.9 分属于严重级别,意味着远程可利用、影响范围大且可导致完全提权。理解这两个术语能帮助你判断公告的紧急程度,并建立以 GHSA 为补充的漏洞监控流程。

master key 就是管理后台密码

/ui 后台用 UI_USERNAME(默认 admin)和 UI_PASSWORD 登录。如果 UI_PASSWORD 未设置,LiteLLM 会"接受 master key 本身作为密码",而任何以此方式登录的人都是代理管理员。官方称这是"仅供引导使用"的共享明文凭据。

关闭它的正确顺序是:先在 UI 里创建一个带独立密码的 proxy_admin 用户并验证能登录,再设置:

general_settings:
  master_key: os.environ/LITELLM_MASTER_KEY
  disable_env_credential_login: true

顺序颠倒的代价是把自己锁在管理后台外面。

盐值密钥:设一次,永不更改

LiteLLM 会加密数据库中存储的供应商密钥(UI 里添加的模型、凭据、MCP 服务器凭据)。源码中的 get_salt_key() 会读取 LITELLM_SALT_KEY,未设置时回退到 master key。这带来一条非对称的运维规则:

  • 全新安装:在添加任何模型之前生成两把密钥
  • 之后永不更改盐值密钥,否则已存凭据全部无法解密
  • 已经在裸奔运行?现在补设同样会导致凭据失效
  • 轮换 master key 时:没有盐值密钥,用 POST /key/regenerate 配合 new_master_key(先备份数据库);有盐值密钥则不要调用该端点,直接替换密钥并重启
printf 'LITELLM_MASTER_KEY=sk-%s\nLITELLM_SALT_KEY=sk-%s\n' "$(openssl rand -hex 32)" "$(openssl rand -hex 32)" > .env
chmod 600 .env

盐值密钥与加密回退的风险

在密码学中,盐值(salt)用于在加密或哈希过程中引入随机性,使得相同的明文在不同系统或不同部署中生成不同的密文,从而抵御彩虹表攻击和批量解密。LiteLLM 使用 LITELLM_SALT_KEY 作为派生加密密钥的盐值,用于保护数据库中存储的模型供应商密钥、凭据和 MCP 服务器凭据。

问题在于,当 LITELLM_SALT_KEY 未设置时,get_salt_key() 会回退到使用 master key 作为盐值。这造成两个隐患:一是 master key 一旦泄露,攻击者不仅能管理代理,还能解密所有已存储的供应商密钥;二是 master key 轮换时,如果盐值也随之变化,所有已加密的凭据将无法解密,导致服务中断。因此,官方推荐的做法是在首次部署、尚未添加任何模型之前就独立生成盐值密钥,并把它视为不可变的基础设施密钥。

关闭实验性 UI 登录

按设置参考文档,除非把 EXPERIMENTAL_UI_LOGIN 显式设为 false,代理会"尝试将任何不以 sk- 开头的传入 token 解密为 UI 会话 token"。这正是 GHSA-7hp6 利用的路径(公告称 1.87.0 至 1.90.x 在设为 true 时同样可被利用)。如果你不用 CLI SSO 登录或 Claude Code 网关登录,把它设为 false。

保持 stdio MCP 服务器关闭

stdio MCP 服务器本质上是代理在其主机上执行的命令。当前版本默认关闭,除非进程环境有 LITELLM_ENABLE_MCP_STDIO=true。不需要就别设。如果你的 UI 在缺少该标志时仍提供 stdio 传输选项,说明版本过旧,该升级了。

4000 端口默认监听所有网卡

litellm CLI 的 --host 默认是 0.0.0.0。建议绑定到 127.0.0.1(Docker 用 -p 127.0.0.1:4000:4000),同时设置 NO_DOCS=True——Swagger 默认挂在 / 上,会列出所有管理路由。然后在前面放一个反向代理,对所有人开放模型 API,但把 /ui 和管理路由限制在内网:

llm.example.com {
    @admin_from_outside {
        not remote_ip 127.0.0.1/8 10.0.0.0/8 172.16.0.0/12 192.168.0.0/16 100.64.0.0/10
        not path /v1/* /chat/completions /completions /embeddings /models
    }
    respond @admin_from_outside 404

    reverse_proxy 127.0.0.1:4000 {
        flush_interval -1
    }
}

反向代理与路径隔离的作用

反向代理(如 Nginx、Caddy)位于客户端与 LiteLLM 代理之间,负责转发请求并执行访问控制。文中示例使用 Caddy 语法,通过 remote_ip 匹配内网网段,并通过 path 匹配公开的模型 API 路径,其余请求(如 /ui 和管理路由)一律返回 404。这种设计能在不修改 LiteLLM 自身配置的情况下,实现网络层的强制隔离。

注意示例中的 not path /v1/* /chat/completions /completions /embeddings /models 表示只有当请求路径不属于这些公开 API 时才触发拦截。这样既能对外提供模型推理服务,又能把管理后台和内部路由隐藏在内网。配合 LiteLLM 绑定 127.0.0.1 和设置 NO_DOCS=True,可以形成纵深防御:即使反向代理配置出现疏漏,代理本身也不直接暴露在公网。

验证加固效果

三条命令即可自测:

curl -s -o /dev/null -w "%{http_code}\n" https://llm.example.com/v1/models   # 无 key 应返回 401
curl -s -o /dev/null -w "%{http_code}\n" https://llm.example.com/ui/         # 外网应返回 404
curl --max-time 5 http://<服务器内网IP>:4000/health/liveliness              # 从另一台机器应失败

完整清单(含 nginx 版本、SSO 相关配置 ALLOWED_EMAIL_DOMAINS、trusted_proxy_ranges、PROXY_BASE_URL、指标与常见错误)发布在 GitHub 的 self-hosted-ai-security-checklist 仓库中,该清单还覆盖 Ollama、Open WebUI、vLLM、n8n、Dify、Langflow 等自托管 AI 组件。另有免费的 CVE 检查器可按版本查询受影响的 LiteLLM 公告,以及一个 local-ai-checkup 脚本,能标记出其他机器可以访问的 LiteLLM 代理。

#LiteLLM#自托管AI安全#LLM代理加固#LiteLLM master key#AI安全漏洞#GHSA-7hp6#LLM网关安全#自托管AI安全清单
分享:

相关推荐