LINUX SB 快照站

QuasarRyan

用户 ID 18291 · 当前名首次快照 2026-08-12 10:22:05 · 当前名始于 2026-08-12 10:22:05 · 原站主页: https://linux.sb/user/18291

发言

共 10 楼

Linux人社区为了庆祝LINUXSB火爆全网,免费开放注册
#29 · QuasarRyan
发帖 2026-08-12 16:32:22 · 快照 2026-08-12 16:35:30

@NodeSeek #28 你是指哪儿?

Linux人社区为了庆祝LINUXSB火爆全网,免费开放注册
#27 · QuasarRyan
发帖 2026-08-12 16:24:52 · 快照 2026-08-12 16:26:56

支持iCloud邮箱吗?

为Db2配置acme.sh获取的ZeroSSL证书
#0 · QuasarRyan
发帖 2026-08-12 16:20:08 · 快照 2026-08-12 16:20:38

本文介绍如何把 acme.sh 已签发的 ZeroSSL ECC 证书自动复制到 Db2 服务器,再使用 OpenSSL 和 IBM GSKit 转换、导入 Db2 可识别的 KDB 密钥数据库,最后配置 Db2 TLS。

示例域名为 example.com,Db2 实例用户为 db2inst1,服务器为 db2.example.com(域名和IP地址皆可)。请按实际环境替换。

1. 工作原理

1. acme.sh 从 ZeroSSL 获取或续期证书;
2. SSH deploy hook 将服务器私钥、服务器证书和中间 CA 复制到 Db2 主机;
3. 远程执行 update-db2-cert.sh
4. 脚本从系统信任库提取 USERTrust ECC 根证书;
5. OpenSSL 将私钥、服务器证书和中间证书打包为 PKCS#12;
6. GSKit 创建 KDB,导入个人证书及完整信任链;
7. 更新 Db2 Database Manager Configuration 并重启服务。

证书链通常为:

example.com 服务器证书
  └─ ZeroSSL ECC DV SSL CA 2(中间 CA)
       └─ USERTrust ECC Certification Authority(根 CA)

KDB 中必须具备带私钥的服务器证书(personal certificate),以及中间 CA、根 CA(signer certificate)。

2. 前置条件

Db2 服务器需要安装 IBM Db2、GSKit、OpenSSL 和 trust(通常来自 p11-kit):

command -v db2
command -v gsk9certutil_64
command -v openssl
command -v trust

创建证书目录和密码文件:

# 这里假定你创建db2实例是使用的用户的默认用户组是db2iadm1
sudo install -d -m 700 -o db2inst1 -g db2iadm1 /home/db2inst1/ssl
sudo -u db2inst1 sh -c 'umask 077; printf "%s\n" "替换为高强度密码" > /home/db2inst1/ssl/.kdb_password'

建议私钥、KDB、stash 和密码文件权限为 600.sth 虽不是明文密码文件,仍应按敏感凭据保护。

如果脚本通过 systemd 管理 Db2,需给 db2inst1 最小化 sudo 权限。先确认服务单元和 systemctl 路径,再通过 visudo 配置,例如:

db2inst1 ALL=(root) NOPASSWD: /usr/bin/systemctl stop db2inst1, /usr/bin/systemctl start db2inst1

3. 配置 SSL 服务端口

本文使用服务名 db2cs_db2inst1。确保 /etc/services 中有对应条目:

db2cs_db2inst1  50001/tcp

验证并开放防火墙端口:

getent services db2cs_db2inst1

4. 部署脚本

将以下内容保存为 /home/db2inst1/ssl/update-db2-cert.sh

#!/usr/bin/env bash
set -Eeuo pipefail
umask 077

SSL_DIR="/home/db2inst1/ssl"
KDB="$SSL_DIR/db2.kdb"
P12="$SSL_DIR/db2.p12"
ACME_DOMAIN_NAME="example.com" # 换成你自己的域名
ROOT_CA="$SSL_DIR/usertrust-ecc-root.pem"
KEY_FILE="$SSL_DIR/$ACME_DOMAIN_NAME.key.pem"
CERT_FILE="$SSL_DIR/$ACME_DOMAIN_NAME.pem"
CA_FILE="$SSL_DIR/ca.pem"
PASSWORD_FILE="$SSL_DIR/.kdb_password"
CERT_LABEL="CN=$ACME_DOMAIN_NAME"
DB2_SSL_SERVICE="db2cs_db2inst1"
SYSTEMD_UNIT="db2inst1"

# SSH 非交互会话通常不会自动加载 Db2 环境。
. /home/db2inst1/sqllib/db2profile
cd "$SSL_DIR"

TMP_DIR=""
cleanup() {
    rm -f "$P12"
    if [[ -n "$TMP_DIR" && -d "$TMP_DIR" ]]; then
        rm -rf "$TMP_DIR"
    fi
}
trap cleanup EXIT

for cmd in openssl trust gsk9certutil_64 db2; do
    command -v "$cmd" >/dev/null 2>&1 || {
        echo "错误:找不到命令 $cmd" >&2
        exit 1
    }
done

for file in "$KEY_FILE" "$CERT_FILE" "$CA_FILE" "$PASSWORD_FILE"; do
    [[ -s "$file" ]] || {
        echo "错误:文件不存在或为空:$file" >&2
        exit 1
    }
done

PASSWORD="$(<"$PASSWORD_FILE")"
[[ -n "$PASSWORD" ]] || { echo "错误:KDB 密码为空" >&2; exit 1; }

# 至少保证证书在未来 24 小时内仍有效。
openssl x509 -in "$CERT_FILE" -checkend 86400 -noout

# ECC/RSA 均适用:比较公钥摘要,确认私钥与证书匹配。
CERT_PUBKEY_HASH="$(openssl x509 -in "$CERT_FILE" -pubkey -noout | openssl pkey -pubin -outform DER | openssl sha256)"
KEY_PUBKEY_HASH="$(openssl pkey -in "$KEY_FILE" -pubout -outform DER | openssl sha256)"
[[ "$CERT_PUBKEY_HASH" == "$KEY_PUBKEY_HASH" ]] || {
    echo "错误:证书与私钥不匹配" >&2
    exit 1
}

echo "[1/10] 停止 Db2"
sudo systemctl stop "$SYSTEMD_UNIT" || true

echo "[2/10] 提取 USERTrust ECC 根 CA"
TMP_DIR="$(mktemp -d)"
trust extract --format=pem-bundle --filter=ca-anchors "$TMP_DIR/ca-bundle.pem"

awk -v dir="$TMP_DIR" '
/BEGIN CERTIFICATE/ { n++ }
n > 0 { print > (dir "/cert-" n ".pem") }
' "$TMP_DIR/ca-bundle.pem"

FOUND=0
for cert in "$TMP_DIR"/cert-*.pem; do
    if openssl x509 -in "$cert" -subject -noout 2>/dev/null | grep -Fq "USERTrust ECC Certification Authority"; then
        cp "$cert" "$ROOT_CA"
        FOUND=1
        break
    fi
done
[[ "$FOUND" -eq 1 ]] || { echo "错误:未找到 USERTrust ECC 根 CA" >&2; exit 1; }

echo "[3/10] 删除旧 KDB"
rm -f "$KDB" "${KDB%.kdb}.rdb" "${KDB%.kdb}.crl" "${KDB%.kdb}.sth" "$P12"

echo "[4/10] 创建 KDB"
gsk9certutil_64 -keydb -create -db "$KDB" -pw "$PASSWORD" -type kdb -stash

echo "[5/10] 创建 PKCS#12"
openssl pkcs12 -export \
    -inkey "$KEY_FILE" \
    -in "$CERT_FILE" \
    -certfile "$CA_FILE" \
    -name "$CERT_LABEL" \
    -out "$P12" \
    -passout pass:"$PASSWORD"

echo "[6/10] 导入服务器证书"
gsk9certutil_64 -cert -import \
    -file "$P12" -type p12 -pw "$PASSWORD" \
    -target "$KDB" -target_type kdb -target_pw "$PASSWORD"

echo "[7/10] 导入中间 CA"
# PKCS#12 导入后中间证书可能已存在;如版本行为不同,可保留此显式导入。
if ! gsk9certutil_64 -cert -list -db "$KDB" -pw "$PASSWORD" | grep -Fq "ZeroSSL ECC DV SSL CA 2"; then
    gsk9certutil_64 -cert -add -db "$KDB" -pw "$PASSWORD" \
        -file "$CA_FILE" -label "ZeroSSL ECC DV SSL CA 2"
fi

echo "[8/10] 导入根 CA"
if ! gsk9certutil_64 -cert -list -db "$KDB" -pw "$PASSWORD" | grep -Fq "USERTrust ECC Certification Authority"; then
    gsk9certutil_64 -cert -add -db "$KDB" -pw "$PASSWORD" \
        -file "$ROOT_CA" -label "USERTrust ECC Certification Authority"
fi

echo "[9/10] 验证 KDB"
gsk9certutil_64 -cert -list -db "$KDB" -pw "$PASSWORD"
gsk9certutil_64 -cert -details -db "$KDB" -pw "$PASSWORD" -label "$CERT_LABEL"
chmod 600 "$KDB" "${KDB%.kdb}.sth" "$PASSWORD_FILE" "$KEY_FILE"

echo "[10/10] 配置 Db2 TLS"
db2 update dbm cfg using SSL_SVR_KEYDB "$KDB"
db2 update dbm cfg using SSL_SVR_STASH "${KDB%.kdb}.sth"
db2 update dbm cfg using SSL_SVR_LABEL "$CERT_LABEL"
db2 update dbm cfg using SSL_SVCENAME "$DB2_SSL_SERVICE"
db2set DB2COMM=TCPIP,SSL

sudo systemctl start "$SYSTEMD_UNIT"
echo "完成"

db2无法使用fullchain证书公钥,必须将证书链层层拆开

赋予执行权限:

chown db2inst1:db2iadm1 /home/db2inst1/ssl/update-db2-cert.sh
chmod 700 /home/db2inst1/ssl/update-db2-cert.sh

Shell 续行符 \ 后不能有空格。复制脚本时请勿把显示层的空格带到反斜杠后面。

5. acme.sh Multi Deploy 配置

首先在db2的证书存储路径先创建证书的同名文件占位,防止acme脚本失败(它会备份旧的证书,如果路径里找不到证书同名文件,会直接报错)

cd /home/db2inst1/ssl/
touch example.com.key.pem" # 将“example.com”换成你的域名
touch example.com.pem" # 将“example.com”换成你的域名

接下来,推荐使用 multideploy 的 delployhook 来部署证书。

在 acme.sh 的配置存储路径中新建multideploy.yml
touch ~/.acme.sh/example.com_ecc/multideploy.yml 将“example.com”换成你的域名

示例节选:

version: "1.0"

services:
  - name: "db2"
    hook: "ssh"
    environment:
      DEPLOY_SSH_USER: "db2inst1"
      DEPLOY_SSH_SERVER: "db2.example.com" # 将db2.example.com换成你的db2服务器的域名/IP地址
      DEPLOY_SSH_KEYFILE: "/home/db2inst1/ssl/example.com.key.pem" # 将“example.com”换成你的域名
      DEPLOY_SSH_CERTFILE: "/home/db2inst1/ssl/example.com.pem" # 将“example.com”换成你的域名
      DEPLOY_SSH_CAFILE: "/home/db2inst1/ssl/ca.pem"
      DEPLOY_SSH_REMOTE_CMD: "/home/db2inst1/ssl/update-db2-cert.sh"
      DEPLOY_SSH_USE_SCP: "yes"

脚本写完之后,部署证书:

acme.sh --deploy -d example.com --deploy-hook multideploy # 将“example.com”换成你的域名

注意:原配置中的 DEPLOY_SSH_USE_SCP: "yes 缺少右侧双引号,会导致 YAML 解析失败。

这些路径表示证书和脚本的远端存储位置。acme.sh 在续期成功后复制证书并执行远程命令。首次自动部署前,建议先手工运行脚本验证 sudo、Db2 profile、GSKit 和服务名均正确。

6. 标签为什么必须一致

SSL_SVR_LABEL 必须指向 KDB 中包含私钥的个人证书标签,而不是 CA 标签。PKCS#12 导入时标签可能来自 friendlyName,也可能被工具按证书主题生成。

脚本通过以下参数固定标签:

openssl pkcs12 -export -name "CN=example.com" ...

随后 Db2 使用同一个值:

db2 update dbm cfg using SSL_SVR_LABEL "CN=example.com"

务必以实际列表为准:

gsk9certutil_64 -cert -list -db /home/db2inst1/ssl/db2.kdb -stashed

如果 GSKit 版本未保留 friendlyName,应把 CERT_LABELSSL_SVR_LABEL 改为 KDB 中实际显示的个人证书标签。

7. 验证部署

查看 Db2 配置:

db2 get dbm cfg | grep -i SSL
db2set -all | grep DB2COMM

查看监听端口:

ss -lntp | grep 50001

从客户端检查握手和证书链:

openssl s_client \
  -connect db2.example.com:50001 \
  -servername example.com # 换成你申请证书的域名\
  -showcerts \
  -verify_return_error </dev/null

应重点确认:

  • 服务端返回 example.com 证书;
  • SAN 包含客户端实际使用的主机名;
  • 能构建到 USERTrust ECC 根 CA 的信任链;
  • 最终显示 Verify return code: 0 (ok)

客户端连接时必须使用 SSL 端口并启用 SSL。不同 Db2 驱动的参数名称不同,常见形式为 security=SSLsslConnection=true

8. 技术细节

8.1 PEM、PKCS#12 与 KDB

acme.sh 输出通常是 PEM:私钥与证书分别存储。Db2 服务端使用 GSKit KDB,服务器证书必须在 KDB 中与私钥关联。PKCS#12 是两者之间的通用中间格式,可同时携带私钥、服务器证书和附加证书链。

8.2 KDB 配套文件

创建 KDB 时可能出现:

  • db2.kdb:密钥数据库;
  • db2.sth:stash 文件,供 Db2 无人值守读取 KDB;
  • db2.rdb:请求数据库;
  • db2.crl:证书吊销相关数据库。

SSL_SVR_STASH 必须指向实际生成的 db2.sth

8.3 为什么不应只导入服务器证书

只有服务器证书和私钥时,GSKit 或客户端可能无法构建完整证书链。中间 CA 通常必须由服务端提供;根 CA主要用于建立信任。显式导入中间证书和根证书可减少不同 GSKit 版本、PKCS#12 导入行为和系统信任库差异造成的问题。

8.4 为什么比较公钥而不是 modulus

传统 RSA 脚本常比较 modulus,但 ECC 证书没有 RSA modulus。本文提取证书和私钥的 DER 公钥并计算 SHA-256,因而同时适用于 RSA 和 ECC。

8.5 重建 KDB 的取舍

本文每次续期都重建 KDB,优点是流程确定、不会残留旧标签;缺点是脚本失败期间服务可能处于停止状态,且会移除 KDB 中其他证书。若同一 KDB 还保存其他用途证书,应改为原位更新,或为 Db2 TLS 使用独立 KDB。

生产环境还可先构建临时 KDB,验证成功后再原子替换,以缩短中断并保留回滚能力。

9. 常见故障

db2: command not found

SSH 非交互会话没有加载实例环境。确认脚本包含:

. /home/db2inst1/sqllib/db2profile

找不到根证书

检查系统是否安装或更新 CA 信任库:

trust list | grep -A3 -B3 "USERTrust ECC"

也可将经过校验的根证书固定放入 SSL 目录,但不要从不可信 URL 临时下载后直接导入。

SSL_SVR_LABEL 不存在

列出 KDB,找到带私钥的个人证书标签,并同步更新 CERT_LABEL 与 Db2 配置。不要误用中间 CA 或根 CA 标签。

Db2 启动后未监听 SSL 端口

检查 /etc/servicesSSL_SVCENAMEDB2COMM、防火墙和 Db2 日志;修改 Database Manager Configuration 后通常需要重启实例。

客户端提示证书主机名不匹配

客户端连接名必须存在于证书 SAN。使用 IP 地址连接时,证书通常没有对应 IP SAN;应使用证书中的 DNS 名,并保证 DNS 或 hosts 解析正确。

脚本停止 Db2 后失败

当前脚本采取 fail-fast 策略。生产环境建议增加失败恢复 trap、保留上一套 KDB,或先在临时路径完成构建和验证,再切换文件并重启。

10. 安全建议

  • 不要把 .kdb_password、私钥、KDB、stash 提交到 Git;
  • 限制 SSL 目录权限,仅允许实例用户访问;
  • acme.sh 主机到 Db2 主机使用专用 SSH key,并限制 authorized_keys 权限;
  • sudo 只放行指定的 start/stop 命令;
  • 定期检查证书到期时间和自动部署日志;
  • 若无兼容性需求,可考虑仅启用 DB2COMM=SSL,避免同时暴露明文 TCP 监听;
  • 在生产变更前保留旧 KDB 和 Db2 配置,以便快速回滚。

完成以上配置后,后续 acme.sh 续期成功时即可自动复制新证书、重建 Db2 KDB 并使新证书生效。

大家都是用哪里的GPT Plus/Codex?
#10 · QuasarRyan
发帖 2026-08-12 15:54:11 · 快照 2026-08-12 15:55:50

@Sam.Altman #9 我是支付宝PockytShop应用买的美区礼品卡,实在不行美区官网也能买

已严格按照国家要求
#11 · QuasarRyan
发帖 2026-08-12 14:35:47 · 快照 2026-08-12 14:39:12

@Denia-bot #7 参考文献:人民锐评:用“Token”还是“词元”,事关科技话语权

已严格按照国家要求
#6 · QuasarRyan
发帖 2026-08-12 14:28:46 · 快照 2026-08-12 14:30:30

善

大家都是用哪里的GPT Plus/Codex?
#7 · QuasarRyan
发帖 2026-08-12 14:17:51 · 快照 2026-08-12 14:31:29

@aiddup #5 以后,可能不止用这一家的,家里Mac mini过一两年可能会换,到时候不想东一个域名西一个IP地址的,先部署个网关(Cloudflare AI Gateway延迟太高),看看流程能不能跑通。我现在实际使用的是Open WebUI,后端接的LiteLLM。

services:
  frontend:
    image: ghcr.nju.edu.cn/open-webui/open-webui:main
    restart: unless-stopped
    pull_policy: always
    hostname: openwebui
    ports:
      - "8080:8080"
    environment:
      WEBUI_URL: ${OPEN_WEBUI_URL}
      ENABLE_SIGNUP: ${OPEN_WEBUI_ENABLE_SIGNUP}
      ENABLE_INITIAL_ADMIN_SIGNUP: ${OPEN_WEBUI_ENABLE_INITIAL_ADMIN_SIGNUP}
      WEBUI_ADMIN_EMAIL: ${OPEN_WEBUI_ADMIN_EMAIL}
      WEBUI_ADMIN_PASSWORD: ${OPEN_WEBUI_ADMIN_PASSWORD}
      WEBUI_ADMIN_NAME: ${OPEN_WEBUI_ADMIN_NAME}
      ENABLE_LOGIN_FROM: ${OPEN_WEBUI_ENABLE_LOGIN_FROM}
      ENABLE_PASSWORD_CHANGE_FORM: ${OPEN_WEBUI_ENABLE_PASSWORD_CHANGE_FORM}
      ENABLE_PASSWORD_AUTH: ${OPEN_WEBUI_ENABLE_PASSWORD_AUTH}
      DEFAULT_LOCALE: ${OPEN_WEBUI_DEFAULT_LOCALE}
      DEFAULT_USER_ROLE: ${OPEN_WEBUI_DEFAULT_USER_ROLE}
      ENABLE_CALENDAR: ${OPEN_WEBUI_ENABLE_CALENDAR}
      ENABLE_CHANNELS: ${OPEN_WEBUI_ENABLE_CHANNELS}
      CHANNEL_MODEL_RESPONSE_MODE: ${OPEN_WEBUI_CHANNEL_MODEL_RESPONSE_MODE}
      ENABLE_FOLDERS: ${OPEN_WEBUI_ENABLE_FOLDERS}
      ENABLE_AUTOMATIONS: ${OPEN_WEBUI_ENABLE_AUTOMATIONS}
      ENABLE_SUBAGENTS: ${OPEN_WEBUI_ENABLE_SUBAGENTS}
      THREAD_POOL_SIZE: ${OPEN_WEBUI_THREAD_POOL_SIZE}
      SHOW_ADMIN_DETAILS: ${OPEN_WEBUI_SHOW_ADMIN_DETAILS}
      ENV: ${OPEN_WEBUI_ENV}
      WEBUI_NAME: ${OPEN_WEBUI_NAME}
      PORT: ${OPEN_WEBUI_PORT}
      DOCKER: True
      OPENAI_API_BASE_URL: ${OPEN_WEBUI_OPENAI_API_BASE_URL:-http://gateway:4000/v1}
      OPENAI_API_KEY: ${OPEN_WEBUI_OPENAI_API_KEY}
      ENABLE_OPENAI_API_PASSTHROUGH: True
      WEBUI_SECRET_KEY: ${OPEN_WEBUI_WEBUI_SECRET_KEY}
      VECTOR_DB: ${OPEN_WEBUI_VECTOR_DB}
      PGVECTOR_DB_URL: ${OPEN_WEBUI_DATABASE_URL}
      PGVECTOR_INITIALIZE_MAX_VECTOR_LENGTH: ${OPEN_WEBUI_PGVECTOR_INITIALIZE_MAX_VECTOR_LENGTH}
      PGVECTOR_CREATE_EXTENSION: ${OPEN_WEBUI_PGVECTOR_CREATE_EXTENSION}
      PGVECTOR_INDEX_METHOD: ${OPEN_WEBUI_PGVECTOR_INDEX_METHOD}
      RAG_EMBEDDING_ENGINE: ${OPEN_WEBUI_RAG_EMBEDDING_ENGINE}
      RAG_EMBEDDING_MODEL: ${OPEN_WEBUI_RAG_EMBEDDING_MODEL}
      RAG_OPENAI_API_BASE_URL: ${OPEN_WEBUI_OPENAI_API_BASE_URL:-http://gateway:4000/v1}
      RAG_OPENAI_API_KEY: ${OPEN_WEBUI_OPENAI_API_KEY}
      ENABLE_WEB_SEARCH: ${OPEN_WEBUI_ENABLE_WEB_SEARCH}
      WEB_SEARCH_ENGINE: ${OPEN_WEBUI_WEB_SEARCH_ENGINE}
      SEARXNG_QUERY_URL: ${OPEN_WEBUI_SEARXNG_QUERY_URL}
      WEB_LOADER_ENGINE: ${OPEN_WEBUI_WEB_LOADER_ENGINE}
      FIRECRAWL_API_BASE_URL: ${OPEN_WEBUI_FIRECRAWL_API_BASE_URL}
      ENABLE_IMAGE_GENERATION: ${OPEN_WEBUI_ENABLE_IMAGE_GENERATION}
      IMAGE_GENERATION_ENGINE: ${OPEN_WEBUI_IMAGE_GENERATION_ENGINE}
      IMAGE_GENERATION_MODEL: ${OPEN_WEBUI_IMAGE_GENERATION_MODEL}
      ENABLE_IMAGE_EDIT: ${OPEN_WEBUI_ENABLE_IMAGE_EDIT}
      ENABLE_OAUTH: ${OPEN_WEBUI_ENABLE_OAUTH}
      ENABLE_OAUTH_SIGNUP: ${OPEN_WEBUI_ENABLE_OAUTH_SIGNUP}
      OAUTH_AUTO_REDIRECT: ${OPEN_WEBUI_OAUTH_AUTO_REDIRECT}
      OAUTH_MERGE_ACCOUNTS_BY_EMAIL: ${OPEN_WEBUI_OAUTH_MERGE_ACCOUNTS_BY_EMAIL}
      OAUTH_UPDATE_PICTURE_ON_LOGIN: ${OPEN_WEBUI_OAUTH_UPDATE_PICTURE_ON_LOGIN}
      OAUTH_CLIENT_INFO_ENCRYPTION_KEY: ${OPEN_WEBUI_OAUTH_CLIENT_KEY}
      OAUTH_SESSION_TOKEN_ENCRYPTION_KEY: ${OPEN_WEBUI_OAUTH_SESSION_KEY}
      OAUTH_CLIENT_ID: ${OPEN_WEBUI_OAUTH_CLIENT_ID}
      OAUTH_CLIENT_SECRET: ${OPEN_WEBUI_OAUTH_CLIENT_SECRET}
      OPENID_PROVIDER_URL: ${OPEN_WEBUI_OPENID_PROVIDER_URL}
      OPENID_REDIRECT_URI: ${OPEN_WEBUI_OPENID_REDIRECT_URI}
      OAUTH_SCOPES: ${OPEN_WEBUI_OAUTH_SCOPES}
      # OAUTH_CODE_CHALLENGE_METHOD: ${OPEN_WEBUI_OAUTH_CODE_CHALLENGE_METHOD}
      OAUTH_PROVIDER_NAME: ${OPEN_WEBUI_OAUTH_PROVIDER_NAME}
      STORAGE_PROVIDER: ${OPEN_WEBUI_STORAGE_PROVIDER}
      STORAGE_LOCAL_CACHE: ${OPEN_WEBUI_STORAGE_LOCAL_CACHE}
      S3_ACCESS_KEY_ID: ${OPEN_WEBUI_S3_ACCESS_KEY_ID}
      S3_ADDRESSING_STYLE: ${OPEN_WEBUI_S3_ADDRESSING_STYLE}
      S3_BUCKET_NAME: ${OPEN_WEBUI_S3_BUCKET_NAME}
      S3_ENDPOINT_URL: ${OPEN_WEBUI_S3_ENDPOINT_URL}
      S3_REGION_NAME: ${OPEN_WEBUI_S3_REGION_NAME}
      S3_SECRET_ACCESS_KEY: ${OPEN_WEBUI_S3_SECRET_ACCESS_KEY}
      DATABASE_URL: ${OPEN_WEBUI_DATABASE_URL}
      REDIS_URL: ${OPEN_WEBUI_REDIS_URL}
      # http_proxy: ${OPEN_WEBUI_HTTP_PROXY}
      # https_proxy: ${OPEN_WEBUI_HTTPS_PROXY}
      # no_proxy: ${OPEN_WEBUI_NO_PROXY}
      PIP_OPTIONS: ${OPEN_WEBUI_PIP_OPTIONS}
      PIP_PACKAGE_INDEX_OPTIONS: ${OPEN_WEBUI_PIP_PACKAGE_INDEX_OPTIONS}
    volumes:
      - ${OPEN_WEBUI_LOCAL_DATA_PATH}:/app/backend/data
    networks:
      - backend
  gateway:
    image: docker.litellm.ai/berriai/litellm-database:latest
    restart: unless-stopped
    pull_policy: always
    hostname: litellm
    ports:
      - "4000:4000"
    environment:
      LITELLM_MASTER_KEY: ${LITELLM_MASTER_KEY}
      LITELLM_SALT_KEY: ${LITELLM_SALT_KEY}
      DATABASE_URL: ${LITELLM_DATABASE_URL}
      SEARXNG_API_BASE: ${LITELLM_SEARXNG_API_BASE}
      STORE_MODEL_IN_DB: "True"
    networks:
      - backend
  upstream:
    image: ${CLI_PROXY_IMAGE:-eceasy/cli-proxy-api:latest}
    restart: unless-stopped
    pull_policy: always
    hostname: cliproxyapi
    volumes:
      - ${CLI_PROXY_CONFIG_PATH:-./config.yaml}:/CLIProxyAPI/config.yaml
      - ${CLI_PROXY_AUTH_PATH:-./auths}:/root/.cli-proxy-api
      - ${CLI_PROXY_LOG_PATH:-./logs}:/CLIProxyAPI/logs
      - ${CLI_PROXY_PLUGIN_PATH:-./plugins}:/CLIProxyAPI/plugins
    networks:
      - backend
  mcpo:
    image: ghcr.nju.edu.cn/open-webui/mcpo:main
    restart: unless-stopped
    pull_policy: always
    hostname: mcpo
    command:
      - "--config"
      - "/config.json"
      - "--host"
      - "0.0.0.0"
      - "--port"
      - "8000"
    volumes:
      - ${MCPO_CONFIG_PATH}:/config.json:ro
    networks:
      - backend
networks:
  backend:
    driver: bridge
大家都是用哪里的GPT Plus/Codex?
#0 · QuasarRyan
发帖 2026-08-12 12:15:36 · 快照 2026-08-12 12:19:18

我用的是原版的GPT Plus账号,docker compose跑CLIProxyAPI+LiteLLM,然后有LiteLLM提供的兼容API的。

SB站也是越来越壮大了
#10 · QuasarRyan
发帖 2026-08-12 12:07:54 · 快照 2026-08-12 12:09:50

就是对邮箱域名有限定,但好歹是能注册上了

置顶【论坛建议/Bug反馈集中贴】精华
#150 · QuasarRyan
发帖 2026-08-12 10:20:50 · 快照 2026-08-12 10:22:05

支持更多邮箱,如iCloud、Outlook等。有类似于限流的问题吗?我看到了有关Gmail限流导致无法发送验证码的帖子