Skip to content

💡 最适合你的方案

👉 在 OpenCloudOS 9 上:

正确路线是:启用 EPEL 源 → 直接用 dnf 安装 certbot

这是最稳定、最标准的方式。


一、先安装 EPEL 源

OpenCloudOS 9 兼容 RHEL 9 / CentOS 9 的 EPEL

执行:

sudo dnf install -y epel-release

如果提示没有 epel-release,可以手动安装:

sudo dnf install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-9.noarch.rpm

二、刷新仓库

sudo dnf makecache

三、安装 Certbot(不需要 pip!)

👉 安装 certbot 核心:

sudo dnf install -y certbot

如果你是 Nginx 环境(强烈建议)

再安装 nginx 插件:

sudo dnf install -y python3-certbot-nginx

如果你是 Apache:

sudo dnf install -y python3-certbot-apache

四、验证安装

certbot --version

应该可以正常显示版本:

certbot x.x.x

方案 A(推荐):pip 全家桶(最稳) 安装docker

用 pip 安装 certbot 本体 + 插件

pip3 install --upgrade pip
pip3 install certbot certbot-dns-tencentcloud

3️⃣ 确认 certbot 来源(关键)

which certbot

应为类似:

/usr/local/bin/certbot

确认插件:

certbot plugins

你必须看到:

dns-tencentcloud
[root@VM-0-6-opencloudos ~]# certbot plugins
Saving debug log to /var/log/letsencrypt/letsencrypt.log

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
* dns-tencentcloud
Description: Obtain certificates using a DNS TXT record (if you are using
TencentCloud for DNS).
Interfaces: Authenticator, Plugin
Entry point: EntryPoint(name='dns-tencentcloud',
value='certbot_dns_tencentcloud.certbot_tencentcloud_plugins:Authenticator',
group='certbot.plugins')

* standalone
Description: Runs an HTTP server locally which serves the necessary validation
files under the /.well-known/acme-challenge/ request path. Suitable if there is
no HTTP server already running. HTTP challenge only (wildcards not supported).
Interfaces: Authenticator, Plugin
Entry point: EntryPoint(name='standalone',
value='certbot._internal.plugins.standalone:Authenticator',
group='certbot.plugins')

* webroot
Description: Saves the necessary validation files to a
.well-known/acme-challenge/ directory within the nominated webroot path. A
separate HTTP server must be running and serving files from the webroot path.
HTTP challenge only (wildcards not supported).
Interfaces: Authenticator, Plugin
Entry point: EntryPoint(name='webroot',
value='certbot._internal.plugins.webroot:Authenticator',
group='certbot.plugins')

使用过版

sh
#!/bin/bash
# -------------------------------------------------------------
# OpenCloudOS 9 + Docker Nginx 泛域名 SSL 自动化一键部署脚本
# Author: ChatGPT
# -------------------------------------------------------------

# --- 配置区 ---
DOMAIN="hellocode.vip"            # 主域名
EMAIL="your_email@example.com"    # 用于注册 ACME 账号
DOCKER_COMPOSE_PATH="/www/docker-compose.yml"   # Docker compose 文件路径
SLEEP_TIME=20                     # DNS TXT 生效等待时间(秒)

# --- 安装依赖 ---
echo ">>> 安装 Python3 pip3 tccli certbot ..."
yum install -y python3 python3-pip
pip3 install --upgrade pip
pip3 install tencentcloud-sdk-python tccli certbot

# --- 配置腾讯云 tccli ---
if [ ! -f ~/.tccli/config ]; then
    echo ">>> 配置 tccli,请输入腾讯云 SecretId / SecretKey"
    tccli configure
fi

# --- 创建 DNS 操作脚本 ---
cat > /www/dnspod_tccli.sh <<EOF
#!/bin/bash
RECORD_FILE="/tmp/_acme-challenge.\${CERTBOT_DOMAIN}_\${CERTBOT_VALIDATION}"
if [ "\$1" = "clean" ]; then
    if [ -f "\${RECORD_FILE}" ]; then
        RECORD_ID=\$(cat \${RECORD_FILE})
        tccli dnspod DeleteRecord --cli-unfold-argument --Domain \${CERTBOT_DOMAIN} --RecordId \${RECORD_ID} >/dev/null
        rm -f \${RECORD_FILE}
    fi
else
    RECORD_ID=\$(tccli dnspod CreateRecord --cli-unfold-argument \
        --Domain \${CERTBOT_DOMAIN} \
        --SubDomain "_acme-challenge" \
        --RecordType TXT \
        --RecordLine "默认" \
        --Value "\${CERTBOT_VALIDATION}" \
        --TTL 600 | grep -Eo '"RecordId"[ ]*:[ ]*"[0-9]+"' | grep -Eo '[0-9]+')
    echo \${RECORD_ID} > \${RECORD_FILE}
    sleep $SLEEP_TIME
fi
EOF

chmod +x /www/dnspod_tccli.sh

# --- 创建 Nginx 重载脚本 ---
cat > /www/reload_nginx.sh <<EOF
#!/bin/bash
docker compose -f $DOCKER_COMPOSE_PATH up -d nginx
EOF
chmod +x /www/reload_nginx.sh

# --- 首次申请泛域名证书 ---
echo ">>> 开始申请泛域名证书..."
export PATH=$(python3 -m site --user-base)/bin:$PATH
certbot certonly \
    --manual \
    --preferred-challenges dns \
    --manual-auth-hook "/www/dnspod_tccli.sh" \
    --manual-cleanup-hook "/www/dnspod_tccli.sh clean" \
    --deploy-hook "/www/reload_nginx.sh" \
    -d "*.$DOMAIN" \
    -d "$DOMAIN" \
    --email $EMAIL \
    --agree-tos

# --- 创建自动续期脚本 ---
cat > /www/renew_cert.sh <<EOF
#!/bin/bash
export PATH=$(python3 -m site --user-base)/bin:\$PATH
certbot renew \
  --manual \
  --preferred-challenges dns \
  --manual-auth-hook "/www/dnspod_tccli.sh" \
  --manual-cleanup-hook "/www/dnspod_tccli.sh clean" \
  --deploy-hook "/www/reload_nginx.sh" \
  --quiet
EOF
chmod +x /www/renew_cert.sh

# --- 配置 Crontab 自动续期 ---
(crontab -l 2>/dev/null; echo "0 2 */10 * * /www/renew_cert.sh >> /var/log/certbot-renew.log 2>&1") | crontab -

echo ">>> 一键部署完成!"
echo "证书路径:/etc/letsencrypt/live/$DOMAIN/"
echo "可通过 sudo certbot certificates 查看证书状态"

更在版本没使用

sh
#!/bin/bash
# -------------------------------------------------------------
# OpenCloudOS 9 + Docker Nginx 泛域名 SSL 自动化一键部署脚本
# Author: ChatGPT
# 修正版:修复 tccli 清理报错、docker PATH 问题
# -------------------------------------------------------------

# --- 配置区 ---
DOMAIN="hellocode.vip"            # 主域名
EMAIL="your_email@example.com"    # 用于注册 ACME 账号
DOCKER_COMPOSE_PATH="/www/docker-compose.yml"   # Docker compose 文件路径
SLEEP_TIME=20                     # DNS TXT 生效等待时间(秒)

# --- 安装依赖 ---
echo ">>> 安装 Python3 pip3 tccli certbot ..."
yum install -y python3 python3-pip
pip3 install --upgrade pip
pip3 install tencentcloud-sdk-python tccli certbot

# --- 配置腾讯云 tccli ---
if [ ! -f ~/.tccli/config ]; then
    echo ">>> 配置 tccli,请输入腾讯云 SecretId / SecretKey"
    tccli configure
fi

# --- 创建 DNS 操作脚本 ---
cat > /www/dnspod_tccli.sh <<'EOF'
#!/bin/bash
RECORD_FILE="/tmp/_acme-challenge.${CERTBOT_DOMAIN}_${CERTBOT_VALIDATION}"

if [ "$1" = "clean" ]; then
    if [ -f "${RECORD_FILE}" ]; then
        RECORD_ID=$(cat ${RECORD_FILE})
        if [ -n "$RECORD_ID" ]; then
            tccli dnspod DeleteRecord --cli-unfold-argument \
                --Domain ${CERTBOT_DOMAIN} \
                --RecordId ${RECORD_ID} >/dev/null
        fi
        rm -f ${RECORD_FILE}
    fi
else
    RECORD_ID=$(tccli dnspod CreateRecord --cli-unfold-argument \
        --Domain ${CERTBOT_DOMAIN} \
        --SubDomain "_acme-challenge" \
        --RecordType TXT \
        --RecordLine "默认" \
        --Value "${CERTBOT_VALIDATION}" \
        --TTL 600 | grep -Eo '"RecordId"[ ]*:[ ]*"[0-9]+"' | grep -Eo '[0-9]+')
    echo ${RECORD_ID} > ${RECORD_FILE}
    sleep '"$SLEEP_TIME"'
fi
EOF

chmod +x /www/dnspod_tccli.sh

# --- 创建 Nginx 重载脚本 ---
cat > /www/reload_nginx.sh <<EOF
#!/bin/bash
# 确保 PATH 中包含 docker
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/bin
docker compose -f $DOCKER_COMPOSE_PATH up -d nginx
EOF
chmod +x /www/reload_nginx.sh

# --- 首次申请泛域名证书 ---
echo ">>> 开始申请泛域名证书..."
export PATH=$(python3 -m site --user-base)/bin:$PATH
certbot certonly \
    --manual \
    --preferred-challenges dns \
    --manual-auth-hook "/www/dnspod_tccli.sh" \
    --manual-cleanup-hook "/www/dnspod_tccli.sh clean" \
    --deploy-hook "/www/reload_nginx.sh" \
    -d "*.$DOMAIN" \
    -d "$DOMAIN" \
    --email $EMAIL \
    --agree-tos

# --- 创建自动续期脚本 ---
cat > /www/renew_cert.sh <<'EOF'
#!/bin/bash
export PATH=$(python3 -m site --user-base)/bin:$PATH
certbot renew \
  --manual \
  --preferred-challenges dns \
  --manual-auth-hook "/www/dnspod_tccli.sh" \
  --manual-cleanup-hook "/www/dnspod_tccli.sh clean" \
  --deploy-hook "/www/reload_nginx.sh" \
  --quiet
EOF
chmod +x /www/renew_cert.sh

# --- 配置 Crontab 自动续期 ---
(crontab -l 2>/dev/null; echo "0 2 */10 * * /www/renew_cert.sh >> /var/log/certbot-renew.log 2>&1") | crontab -

echo ">>> 一键部署完成!"
echo "证书路径:/etc/letsencrypt/live/$DOMAIN/"
echo "可通过 sudo certbot certificates 查看证书状态"

宝塔版本没使用

sh
#!/bin/bash
# ===============================================
# 宝塔 OpenCloudOS 9 + Nginx 泛域名 SSL 自动化
# ===============================================
# 使用说明:
# 1. 修改下面的 DOMAIN 和邮箱
# 2. 确保系统已安装 python3
# 3. 运行 bash /www/setup_ssl_bt.sh
# ===============================================

# ====== 配置区域 ======
DOMAIN="hellocode.vip"
EMAIL="youremail@example.com"    # Let’s Encrypt 邮箱
# 腾讯云 API 文件路径
TC_CREDENTIALS="/etc/letsencrypt/tencentcloud.ini"
# SSL 安装路径(宝塔 Nginx)
SSL_CERT_PATH="/etc/letsencrypt/live/$DOMAIN"
# Nginx reload 命令
NGINX_RELOAD_CMD="systemctl reload nginx"

# ====== 安装依赖 ======
echo ">>> 安装依赖..."
yum update -y
yum install -y python3 python3-pip

# 安装 Certbot 和 DNS 插件
pip3 install --upgrade pip
pip3 install certbot certbot-dns-tencentcloud

# 安装 tccli(腾讯云 CLI)
pip3 install tencentcloud-sdk-python tccli

# ====== 创建 DNS 钩子脚本 ======
HOOK_SCRIPT="/www/dnspod_tccli.sh"
cat > $HOOK_SCRIPT << 'EOF'
#!/bin/bash
RECORD_FILE="/tmp/_acme-challenge.${CERTBOT_DOMAIN}_${CERTBOT_VALIDATION}"

if ! command -v tccli >/dev/null; then
    echo "tccli not found"
    exit 1
fi

if [ "$1" = "clean" ]; then
    if [ -f "${RECORD_FILE}" ]; then
        RECORD_ID=$(cat ${RECORD_FILE})
        if [ -n "$RECORD_ID" ]; then
            tccli dnspod DeleteRecord --cli-unfold-argument \
                --Domain ${CERTBOT_DOMAIN} \
                --RecordId ${RECORD_ID} >/dev/null
        fi
        rm -f ${RECORD_FILE}
    fi
else
    RECORD_ID=$(
        tccli dnspod CreateRecord --cli-unfold-argument \
            --Domain ${CERTBOT_DOMAIN} \
            --SubDomain _acme-challenge \
            --RecordType TXT \
            --RecordLine 默认 \
            --Value ${CERTBOT_VALIDATION} \
            --TTL 600 \
        | grep "RecordId" | grep -Eo "[0-9]+"
    )
    echo ${RECORD_ID} > ${RECORD_FILE}
    sleep 20
fi
EOF
chmod +x $HOOK_SCRIPT

# ====== 创建续期脚本 ======
RENEW_SCRIPT="/www/renew_cert_bt.sh"
cat > $RENEW_SCRIPT << EOF
#!/bin/bash
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/bin
certbot renew \
  --manual \
  --preferred-challenges dns \
  --manual-auth-hook "$HOOK_SCRIPT" \
  --manual-cleanup-hook "$HOOK_SCRIPT clean" \
  --deploy-hook "$NGINX_RELOAD_CMD" \
  --quiet
echo "\$(date '+%Y-%m-%d %H:%M:%S') Certbot renew executed" >> /var/log/certbot-renew.log
EOF
chmod +x $RENEW_SCRIPT

# ====== 申请泛域名证书 ======
echo ">>> 开始申请泛域名证书..."
certbot certonly \
  --manual \
  --preferred-challenges dns \
  --manual-auth-hook "$HOOK_SCRIPT" \
  --manual-cleanup-hook "$HOOK_SCRIPT clean" \
  -d "*.$DOMAIN" \
  -d "$DOMAIN" \
  --email $EMAIL \
  --agree-tos \
  --non-interactive

echo ">>> 证书已生成:$SSL_CERT_PATH"

# ====== 宝塔计划任务提示 ======
echo ">>> 请在宝塔计划任务添加以下任务,实现自动续期:"
echo "类型:Shell 脚本"
echo "脚本内容:bash $RENEW_SCRIPT"
echo "周期:每 10 天执行一次"

echo ">>> 安装完成,证书路径:$SSL_CERT_PATH"
echo ">>> 宝塔 Nginx SSL 配置请使用 fullchain.pem 与 privkey.pem"

证书文件: /etc/letsencrypt/live/hellocode.vip/fullchain.pem 私钥文件: /etc/letsencrypt/live/hellocode.vip/privkey.pem

未配置

nginx
server
{
    listen 80;
    listen [::]:80;
    server_name mac.hellocode.vip;
    index index.php index.html index.htm default.php default.htm default.html;
    root /www/wwwroot/mac.hellocode.vip;
    #CERT-APPLY-CHECK--START
    # 用于SSL证书申请时的文件验证相关配置 -- 请勿删除
    include /www/server/panel/vhost/nginx/well-known/mac.hellocode.vip.conf;
    #CERT-APPLY-CHECK--END
    include /www/server/panel/vhost/nginx/extension/mac.hellocode.vip/*.conf;
    
    #SSL-START SSL相关配置,请勿删除或修改下一行带注释的404规则
    #error_page 404/404.html;
    #SSL-END

    #ERROR-PAGE-START  错误页配置,可以注释、删除或修改
    error_page 404 /404.html;
    #error_page 502 /502.html;
    #ERROR-PAGE-END

    #PHP-INFO-START  PHP引用配置,可以注释或修改
    include enable-php-00.conf;
    #PHP-INFO-END

    #REWRITE-START URL重写规则引用,修改后将导致面板设置的伪静态规则失效
    include /www/server/panel/vhost/rewrite/mac.hellocode.vip.conf;
    #REWRITE-END

    #禁止访问的文件或目录
    location ~ ^/(\.user.ini|\.htaccess|\.git|\.env|\.svn|\.project|LICENSE|README.md)
    {
        return 404;
    }

    #一键申请SSL证书验证目录相关设置
    location ~ \.well-known{
        allow all;
    }

    #禁止在证书验证目录放入敏感文件
    if ( $uri ~ "^/\.well-known/.*\.(php|jsp|py|js|css|lua|ts|go|zip|tar\.gz|rar|7z|sql|bak)$" ) {
        return 403;
    }

    location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$
    {
        expires      30d;
        error_log /dev/null;
        access_log /dev/null;
    }

    location ~ .*\.(js|css)?$
    {
        expires      12h;
        error_log /dev/null;
        access_log /dev/null;
    }
    access_log  /www/wwwlogs/mac.hellocode.vip.log;
    error_log  /www/wwwlogs/mac.hellocode.vip.error.log;
}
本地证书删除失败: 证书正在被网站【blueadmin.hellocode.vip,csm.hellocode.vip,good.hellocode.vip,blue.hellocode.vip,ehr.hellocode.vip,ray.hellocode.vip,jenkins.hellocode.vip,blog.hellocode.vip,pdf.hellocode.vip,paste.hellocode.vip,xui.hellocode.vip】使用,请关闭这些网站的SSL或将这些网站配置成其他的证书后再删除

Lucking