Appearance
💡 最适合你的方案
👉 在 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-tencentcloud3️⃣ 确认 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或将这些网站配置成其他的证书后再删除