# OHTTPS 部署节点 (API)自动更新
在后台采用 nginx 进行前端网页部署,常常会需要进行证书的刷新,应为现在的证书一般最长不超过一年就需要进行更新替换,短的甚至一个月、90天就需要进行替换了,味了解决这个麻烦事,所以写下了这一个自动刷新证书的 bash 命令。
采用的方案是:
一个bash脚本,读取制定文件下的所有配置文件,再加上 crontab 修订添加定时任务。
# 1. BASH 命令内容
在这其中需要配置的就是配置文件的目录,修改 CONFIG_DIR 的值就可
#!/bin/bash
# 配置文件的目录
CONFIG_DIR="---"
# 遍历每个配置文件
for config_file in "$CONFIG_DIR"/*.conf; do
echo "===== 开始处理配置文件:$config_file ====="
# 读取配置文件内容
source "$config_file"
# 检查必填项
if [[ -z "$apiId" || -z "$apiKey" || -z "$certificateId" || -z "$savePath" ]]; then
echo "❌ 缺少必要参数,跳过 $config_file"
continue
fi
# 设置默认值
certName="${certName:-fullchain}"
certKeyName="${certKeyName:-cert}"
cycleDays="${cycleDays:-0}"
expireThresholdDays="${expireThresholdDays:-15}"
startDate="${startDate:-2025-06-10}"
logName="${logName:-renew.log}"
reloadCommand="${reloadCommand:-"nginx -s reload"}"
mkdir -p "$savePath"
LOG_FILE="${savePath}/${logName}"
# 日志函数
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" | tee -a "$LOG_FILE"
}
log "📄 加载配置文件:$config_file"
# 计算当前是第几天
days_since_start=$(( ( $(date +%s) - $(date -d "$startDate" +%s) ) / 86400 ))
# 缓存文件路径
expireCacheFile="${savePath}/.cert_expired_time"
# 默认不续签
shouldRenew=false
# 检查周期触发
if (( cycleDays > 0 )) && (( days_since_start % cycleDays == 0 )); then
log "📆 满足周期条件(每 $cycleDays 天,第 $days_since_start 天)"
shouldRenew=true
fi
# 检查本地过期时间缓存
if [ -f "$expireCacheFile" ]; then
cached_expire_ts=$(date -d "$(cat "$expireCacheFile")" +%s)
now_ts=$(date +%s)
remain_days=$(( (cached_expire_ts - now_ts) / 86400 ))
log "📁 本地缓存证书剩余有效天数:$remain_days 天"
if (( remain_days <= expireThresholdDays )); then
log "⚠️ 剩余天数 ≤ 阈值($expireThresholdDays),触发续签"
shouldRenew=true
fi
else
log "⚠️ 无缓存过期时间,默认尝试请求"
shouldRenew=true
fi
# 不满足条件则跳过
if [[ "$shouldRenew" != "true" ]]; then
log "✅ 条件未满足,跳过续签"
continue
fi
# 请求参数
timestamp=$(date +%s%3N)
stringForSign=$(echo -e "apiId=${apiId}\napiKey=${apiKey}\ncertificateId=${certificateId}\ntimestamp=${timestamp}" | sort | paste -sd '&')
sign=$(echo -n "$stringForSign" | md5sum | awk '{print $1}')
request_url="https://ohttps.com/api/open/getCertificate?apiId=${apiId}&certificateId=${certificateId}×tamp=${timestamp}&sign=${sign}"
log "🌐 请求证书信息..."
response=$(curl -s "$request_url")
success=$(echo "$response" | jq -r '.success')
if [ "$success" = "true" ]; then
certKey=$(echo "$response" | jq -r '.payload.certKey')
fullChainCerts=$(echo "$response" | jq -r '.payload.fullChainCerts')
expiredTime=$(echo "$response" | jq -r '.payload.expiredTime')
# 保存文件
echo "$certKey" > "${savePath}/${certKeyName}.key"
echo "$fullChainCerts" > "${savePath}/${certName}.cer"
echo "$expiredTime" > "$expireCacheFile"
log "✅ 证书续签成功"
log "🔒 私钥路径:${savePath}/${certKeyName}.key"
log "📜 证书路径:${savePath}/${certName}.cer"
log "📅 过期时间:$expiredTime"
# 重载 Nginx 或其他服务
log "🚀 执行 reload 命令:$reloadCommand"
$reloadCommand &>> "$LOG_FILE"
if [[ $? -eq 0 ]]; then
log "🔁 服务重载成功"
else
log "❌ 服务重载失败,请检查日志"
fi
else
msg=$(echo "$response" | jq -r '.msg')
log "❌ 请求失败:$msg"
fi
echo "" >> "$LOG_FILE"
done
# 2. 配置文件的内容
配置文件字段
| 字段 | 内容 | 示例 |
|---|---|---|
| domain | 域名 | |
| apiId | OHttps 证书部署节点ID | |
| apiKey | OHttps 证书部署密钥 | |
| certificateId | OHttps 证书ID | |
| certName | 部署的证书节点名称, 会保存为 ${certName}.cer | |
| certKeyName | 部署的证书节点密钥, 会保存为 ${certKeyName}.key | |
| savePath | 部署证书的保存位置 eg. | /etc/nginx/cert/www.example.com |
| startDate | 开始日期,一般会从Ohttps 先获取该日期 | |
| cycleDays | 循环周期,多久会刷新,或者过期 | |
| expireThresholdDays | 失效时间阈值,会提前刷新 |
示例:
domain="www.example.com"
apiId="push-xxxxx"
apiKey="xxxxxxxxxxxxxxxxxxxxxxx"
certificateId="cert-xxxxxxxxxx"
certName="fullchain"
certKeyName="cert"
savePath="/xxx/xxx/xxx"
startDate="2025-06-01"
cycleDays=39
expireThresholdDays=15
注意事项
设置这个循环周期只是为了减少这个API接口的调用,因为本人发现每调用一次api就会扣除 OHTTPS 中的余额
