当前位置: 首页 > news >正文

飞牛fnOS使用DNS验证方式,用acme自动签发SSL证书

飞牛fnOS在使用DDNS时,需要签发自己域名的SSL证书。但目前并没有该功能。

论坛里有方案:飞牛fnos使用acme.sh自动部署并自动更新ssl证书【脚本更新】 - 攻略分享 飞牛私有云论坛 fnOS,原作者为:https://blog.csdn.net/jummewu

原脚本只能签发RSA证书,因此做了点调整改动,使其能够签发ECC证书。

#!/bin/bash
set -euo pipefail# ==============================
# 🛠️ 配置区(请按需修改)
# ==============================
DOMAIN="domain.com"
DNS_PROVIDER="dns_dp"               # DNSPod
DP_Id="123456"                      # ← 替换为你的 DNSPod ID
DP_Key="1111111"              # ← 替换为你的 DNSPod Token# 证书服务商:letsencrypt 或 zerossl
CERT_SERVER="letsencrypt"# --- ZeroSSL 专用配置(当 CERT_SERVER=zerossl 时必填)---
# 获取 EAB 凭据:https://app.zerossl.com/developer
# Email="admin@cnraft.com"
# EAB_kid="xxxxx"
# EAB_hmac_key="xxxxx"DNS_SLEEP=120
SSLS_DIR="/usr/trim/var/trim_connect/ssls"
CONF_FILE="/usr/trim/etc/network_gateway_cert.conf"
RELOAD_CMD="systemctl restart webdav.service smbftpd.service trim_nginx.service"# ==============================
# 🧰 工具函数
# ==============================
log() { echo -e "\033[1;34m[INFO]\033[0m $*"; }
warn() { echo -e "\033[1;33m[WARN]\033[0m $*" >&2; }
err() { echo -e "\033[1;31m[ERROR]\033[0m $*" >&2; exit 1; }check_cmd() {command -v "$1" &>/dev/null || err "Command '$1' not found."
}install_jq() {if command -v jq &>/dev/null; then return; fiif command -v apt-get &>/dev/null; thenapt-get update && apt-get install -y jq || err "apt install jq failed"elif command -v apk &>/dev/null; thenapk add --no-cache jq || err "apk add jq failed"elseerr "Unsupported OS: cannot auto-install jq."fi
}# ==============================
# 🚀 主流程
# ==============================
START_TT=$(date +%s%3N)# --- 检查依赖 ---
check_cmd date psql openssl
install_jqACME_SH=$(command -v acme.sh 2>/dev/null || echo "/root/.acme.sh/acme.sh")
[[ -x "$ACME_SH" ]] || err "acme.sh not found."export DP_Id DP_Key
[[ -z "$DP_Id" ]] && err "DP_Id is empty!"
[[ -z "$DP_Key" ]] && err "DP_Key is empty!"# --- 申请证书 ---
log "Issuing ECC certificate for $DOMAIN and *.$DOMAIN via $CERT_SERVER..."case "$CERT_SERVER" inletsencrypt)"$ACME_SH" --force --log \--issue \--dns "$DNS_PROVIDER" --dnssleep "$DNS_SLEEP" \-d "$DOMAIN" -d "*.$DOMAIN" \--ecc --keylength ec-256;;zerossl)[[ -z "${Email:-}" || -z "${EAB_kid:-}" || -z "${EAB_hmac_key:-}" ]] && \err "ZeroSSL requires Email, EAB_kid, EAB_hmac_key"export Email EAB_kid EAB_hmac_key"$ACME_SH" --register-account -m "$Email" --server zerossl \--eab-kid "$EAB_kid" --eab-hmac-key "$EAB_hmac_key" || true"$ACME_SH" --force --log \--issue \--dns "$DNS_PROVIDER" --dnssleep "$DNS_SLEEP" \-d "$DOMAIN" -d "*.$DOMAIN" \--ecc --keylength ec-256;;*) err "Unsupported CERT_SERVER: $CERT_SERVER";;
esac# --- 获取证书元数据(使用 Le_ 前缀字段)---
CERT_INFO_RAW="$("$ACME_SH" --info -d "$DOMAIN" --ecc)"Le_CertCreateTimeStr=$(echo "$CERT_INFO_RAW" | grep '^Le_CertCreateTimeStr=' | cut -d= -f2)
Le_NextRenewTimeStr=$(echo "$CERT_INFO_RAW" | grep '^Le_NextRenewTimeStr=' | cut -d= -f2)if [ -z "$Le_CertCreateTimeStr" ] || [ -z "$Le_NextRenewTimeStr" ]; thenerr "Missing Le_CertCreateTimeStr or Le_NextRenewTimeStr in acme.sh output."
fi# UTC+8 中国时区
CERT_CREATE_TT=$(date -d "${Le_CertCreateTimeStr} 8 hours" +%s%3N)
CERT_CREATE=$(date -d "${Le_CertCreateTimeStr} 8 hours" +%s)
CERT_RENEW_TT=$(date -d "${Le_NextRenewTimeStr} 1 month 8 hours" +%s%3N)
CERT_RENEW=$(date -d "${Le_NextRenewTimeStr} 1 month 8 hours" +%s)# --- 创建目录 & 安装证书 ---
CERT_DIR="${SSLS_DIR}/${DOMAIN}/${CERT_CREATE}"
mkdir -p "$CERT_DIR"CERT_FILE="$CERT_DIR/${DOMAIN}.cer"
KEY_FILE="$CERT_DIR/${DOMAIN}.key"
FULLCHAIN_FILE="$CERT_DIR/fullchain.cer"
CA_FILE="$CERT_DIR/issuer_certificate.crt""$ACME_SH" --install-cert -d "$DOMAIN" --ecc \--cert-file "$CERT_FILE" \--key-file "$KEY_FILE" \--fullchain-file "$FULLCHAIN_FILE" \--ca-file "$CA_FILE" \--reloadcmd "$RELOAD_CMD"chmod 755 "$KEY_FILE" "$CERT_FILE" "$FULLCHAIN_FILE" "$CA_FILE"# --- 提取证书信息 ---
ISSUER=$(openssl x509 -in "$CERT_FILE" -noout -issuer | awk -F' = ' '{print $NF}' | sed 's/,.*$//' || echo "unknown")
SIG_ALGO=$(openssl x509 -in "$CERT_FILE" -noout -text | awk '/Signature Algorithm:/{print $3; exit}' || echo "unknown")case "$SIG_ALGO" in*RSA*)      ALGO_TYPE="RSA" ;;*ECDSA*|*ECC*) ALGO_TYPE="ECC" ;;*SM2*)      ALGO_TYPE="SM2" ;;*)          ALGO_TYPE="UNKNOWN" ;;
esac# --- 更新 PostgreSQL 数据库 ---
if psql -qtAX -U postgres -d trim_connect -c "SELECT 1 FROM cert WHERE domain = '$DOMAIN';" | grep -q 1; thenpsql -U postgres -d trim_connect -c "
        UPDATE cert SETvalid_from = $CERT_CREATE_TT,valid_to = $CERT_RENEW_TT,encrypt_type = '$ALGO_TYPE',issued_by = '$ISSUER',last_renew_time = $START_TT,des = '由acme.sh自动生成的正式证书 ($CERT_SERVER)',private_key = '$KEY_FILE',certificate = '$CERT_FILE',issuer_certificate = '$CA_FILE',status = 'suc',updated_time = $START_TTWHERE domain = '$DOMAIN';" >/dev/null
elseMAX_ID=$(psql -qtAX -U postgres -d trim_connect -c "SELECT COALESCE(MAX(id), 0) FROM cert;" 2>/dev/null)DOMAIN_ID=$((MAX_ID + 1))psql -U postgres -d trim_connect -c "
        INSERT INTO cert (id, domain, subject_alt_name, common_name,valid_from, valid_to, encrypt_type, issued_by,created_time, des, retry_count, error_msg,deploy_type, deploy_extra,private_key, certificate, issuer_certificate,status, last_renew_time, updated_time) VALUES ($DOMAIN_ID, '$DOMAIN', '*.$DOMAIN', '$DOMAIN',$CERT_CREATE_TT, $CERT_RENEW_TT, '$ALGO_TYPE', '$ISSUER',$START_TT, '由acme.sh自动生成的正式证书 ($CERT_SERVER)', 0, NULL,'upload', NULL,'$KEY_FILE', '$CERT_FILE', '$CA_FILE','suc', $START_TT, $START_TT);" >/dev/null
fi# --- 更新 NGINX JSON 配置---
[[ -f "$CONF_FILE" ]] || { echo "[]" > "$CONF_FILE"; }NEW_ENTRY=$(jq -n \--arg host "$DOMAIN" \--arg cert "$FULLCHAIN_FILE" \--arg key "$KEY_FILE" \'{host: $host, cert: $cert, key: $key}'
)CURRENT=$(jq -c '.' "$CONF_FILE" 2>/dev/null || echo "[]")if echo "$CURRENT" | jq -e ".[] | select(.host == \"$DOMAIN\")" >/dev/null; thenUPDATED=$(echo "$CURRENT" | jq --argjson new "$NEW_ENTRY" 'map(if .host == $new.host then $new else . end)')
elseUPDATED=$(echo "$CURRENT" | jq --argjson new "$NEW_ENTRY" '. += [$new]')
ficp "$CONF_FILE" "$CONF_FILE.$START_TT.bak"
echo "$UPDATED" | jq -c '.' > "$CONF_FILE"if ! grep -F "$FULLCHAIN_FILE" "$CONF_FILE" >/dev/null; thenerr "NGINX config updated but cert path not found."
fi# --- 重载服务 + 清理旧证书 ---
$RELOAD_CMD || truefind "${SSLS_DIR}/${DOMAIN}" -maxdepth 1 -type d -mtime +90 -exec rm -rf {} + 2>/dev/null || true
find /usr/trim/etc/ -name "network_gateway_cert.conf.*.bak" -mtime +90 -delete 2>/dev/null || true# --- 生成摘要配置 ---
CONF_SUMMARY="${SSLS_DIR}/${DOMAIN}/sslpath.conf"
cat > "$CONF_SUMMARY" <<EOF
DOMAIN=$DOMAIN
CERT_CREATE_TT=$CERT_CREATE_TT
CERT_RENEW_TT=$CERT_RENEW_TT
ALGO_TYPE=$ALGO_TYPE
CERT_ISSUED_BY=$ISSUER
TT=$START_TT
DOMAIN_SSL_DIR=$CERT_DIR
CERT_SERVER=$CERT_SERVER
STAGING=false
EOFlog "✅ Certificate deployed: $CERT_DIR"
log "📌 Summary: $CONF_SUMMARY"

 

保存为deploy-cert.sh并给执行权限:

chmod +x deploy-cert.sh
./deploy-cert.sh

 

最后将其添加到计划任务中:

# 每月1日 2:30 执行
30 2 1 * * /path/to/deploy-cert.sh >> /var/log/acme-deploy.log 2>&1

 

http://www.rkmt.cn/news/84456.html

相关文章:

  • 【API 设计之道】03 非标行为设计:当 REST 无法描述“取消订单”时怎么办?
  • 从零构建PHP扩展:基于Rust的高性能模块开发实战(完整源码级教程)
  • 2025 年 12 月苏作红木家具权威推荐榜:匠心传承与东方美学典范之选 - 品牌企业推荐师(官方)
  • 2025年PVC地板厂家权威推荐榜:导电/防静电/同质透心/复合/商用/磁性/自沉式,专业解析各品类核心优势与选购指南 - 品牌企业推荐师(官方)
  • 算力新标杆:昇腾Atlas 800T NPU实战Llama-2-7b全流程评测与技术解析
  • 联想Battery report准确吗,会显示错误吗
  • Wan2.2-T2V-A14B支持生成投票互动选项吗?短视频营销转化路径设计
  • 千亿参数落地革命:GLM-4.5V-FP8如何助力中小企业AI部署
  • 2025年12月AI培训与GEO服务商权威推荐榜:数字人、智能体、企业获客与短视频营销解决方案深度解析 - 品牌企业推荐师(官方)
  • 多人语音聊天室APP开发全解析:从技术架构到运营策略
  • 合并两个有序链表:双指针迭代法实现(C++)
  • Wan2.2-T2V-A14B已接入某头部视频平台AI剪辑工具链
  • 基于 openFuyao 的 AI 推理加速实战:智能路由与 PD 分离式 KVCache 架构揭秘
  • 2025 年 QMS 质量管理软件权威推荐榜:智能工厂与精益制造必备的数字化管控利器 - 品牌企业推荐师(官方)
  • 人工智能大模型技术突破:引领智能时代新纪元
  • 2025 年建筑加固技术权威推荐榜:碳纤维加固、粘钢加固等创新工艺深度解析与优质服务商精选 - 品牌企业推荐师(官方)
  • CVPR 2025最佳论文突破:DepthCrafter实现开放世界视频深度序列生成新范式
  • 突破跨模态生成瓶颈:Step-Video-TI2V开创图生视频技术新范式
  • 地平线苏治中:开源框架和基础模型赋能具身智能行业
  • 54、深入探索Shell编程:命令、变量与模式匹配的综合指南
  • Wan2.2-T2V-A14B在综艺节目花絮自动生成中的尝试
  • 51单片机:了解最小核心系统
  • 【VSCode量子编程环境搭建指南】:手把手教你5步配置Qiskit开发环境
  • 基于单片机大棚环境控制(温湿度,PH值)系统Proteus仿真(含全部资料)
  • 金融高频交易策略性能评估与优化框架
  • Java两种代理模式详解
  • 【北理工-AAAI26】MODA:首个无人机多光谱目标检测数据集
  • NVIDIA Profile Inspector完全攻略:释放显卡隐藏性能
  • Wan2.2-T2V-A14B能否生成符合ITU标准的国际电信联盟规范视频
  • 一文盘点家政有哪些类型