🔧 fix(deploy): 证书方案从 certbot 迁移到 acme.sh
- 证书目录改为可配置 CERT_DIR(默认 /etc/nginx/ssl),适配 acme.sh --install-cert 安装位置 - nginx 模板与提示文案同步去 certbot 依赖,ACME http-01 验证路径保持 webroot 兼容
This commit is contained in:
1 parent
af9004adaf
commit
3768ec0a31
2 files changed
+35
-37
No files matched your search
+3
-1
@@ -32,8 +32,10 @@ SRC_DIR="/root/code/novel/fanqie-go"
|
|||||||
DOMAIN="fq.20010117.xyz"
|
DOMAIN="fq.20010117.xyz"
|
||||||
|
|
||||||
# ---------- 证书 ----------
|
# ---------- 证书 ----------
|
||||||
# Certbot 申请证书的邮箱,用于接收过期提醒
|
# acme.sh 申请证书的邮箱,用于账户注册与过期提醒
|
||||||
CERT_EMAIL="you@example.com"
|
CERT_EMAIL="you@example.com"
|
||||||
|
# 证书安装目录(acme.sh --install-cert 目标,nginx 配置从此处读取)
|
||||||
|
# CERT_DIR="/etc/nginx/ssl"
|
||||||
|
|
||||||
# ---------- 编译 ----------
|
# ---------- 编译 ----------
|
||||||
# BUILD_TARGET="./cmd/fanqie"
|
# BUILD_TARGET="./cmd/fanqie"
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ NGINX_CONF="${NGINX_CONF:-/etc/nginx/conf.d/${APP_NAME}.conf}"
|
|||||||
APP_PORT="${APP_PORT:-40180}" # 程序监听端口
|
APP_PORT="${APP_PORT:-40180}" # 程序监听端口
|
||||||
DOMAIN="${DOMAIN:-fq.20010117.xyz}" # 域名
|
DOMAIN="${DOMAIN:-fq.20010117.xyz}" # 域名
|
||||||
CERT_EMAIL="${CERT_EMAIL:-admin@${DOMAIN}}" # 证书申请邮箱(过期提醒)
|
CERT_EMAIL="${CERT_EMAIL:-admin@${DOMAIN}}" # 证书申请邮箱(过期提醒)
|
||||||
|
CERT_DIR="${CERT_DIR:-/etc/nginx/ssl}" # 证书目录(acme.sh --install-cert 安装位置)
|
||||||
BUILD_TARGET="${BUILD_TARGET:-./cmd/fanqie}" # go build 的包路径
|
BUILD_TARGET="${BUILD_TARGET:-./cmd/fanqie}" # go build 的包路径
|
||||||
ENV_FILE="${ENV_FILE:-${SRC_DIR}/.env}" # 应用环境变量(.env.example 为模板)
|
ENV_FILE="${ENV_FILE:-${SRC_DIR}/.env}" # 应用环境变量(.env.example 为模板)
|
||||||
KEEP_VERSIONS="${KEEP_VERSIONS:-5}" # 保留最近几个版本
|
KEEP_VERSIONS="${KEEP_VERSIONS:-5}" # 保留最近几个版本
|
||||||
@@ -245,8 +246,8 @@ restart_and_verify() {
|
|||||||
|
|
||||||
|
|
||||||
# 写入 nginx 配置(--init 与 --sync-nginx 共用的唯一模板来源)
|
# 写入 nginx 配置(--init 与 --sync-nginx 共用的唯一模板来源)
|
||||||
# 模板自带完整 443/证书配置(证书存在时启用),不依赖 certbot --nginx 注入——
|
# 模板自带完整 443/证书配置(证书存在时启用),不依赖签发工具注入——
|
||||||
# 这样 --sync-nginx 覆盖配置时不会丢失 HTTPS 段(certbot 注入式配置会被覆盖回 80-only)
|
# 这样 --sync-nginx 覆盖配置时不会丢失 HTTPS 段(注入式配置会被覆盖回 80-only)
|
||||||
write_nginx_conf() {
|
write_nginx_conf() {
|
||||||
# 反代 location(80 无证书时与 443 共用)
|
# 反代 location(80 无证书时与 443 共用)
|
||||||
local proxy_locations
|
local proxy_locations
|
||||||
@@ -281,7 +282,7 @@ LOC_EOF
|
|||||||
)
|
)
|
||||||
|
|
||||||
local ssl_block=""
|
local ssl_block=""
|
||||||
if [ -f "/etc/letsencrypt/live/${DOMAIN}/fullchain.pem" ]; then
|
if [ -f "${CERT_DIR}/${DOMAIN}/fullchain.pem" ]; then
|
||||||
log "检测到 ${DOMAIN} 证书,配置启用 443"
|
log "检测到 ${DOMAIN} 证书,配置启用 443"
|
||||||
ssl_block=$(cat <<SSL_EOF
|
ssl_block=$(cat <<SSL_EOF
|
||||||
|
|
||||||
@@ -289,8 +290,8 @@ server {
|
|||||||
listen 443 ssl http2;
|
listen 443 ssl http2;
|
||||||
server_name ${DOMAIN};
|
server_name ${DOMAIN};
|
||||||
|
|
||||||
ssl_certificate /etc/letsencrypt/live/${DOMAIN}/fullchain.pem;
|
ssl_certificate ${CERT_DIR}/${DOMAIN}/fullchain.pem;
|
||||||
ssl_certificate_key /etc/letsencrypt/live/${DOMAIN}/privkey.pem;
|
ssl_certificate_key ${CERT_DIR}/${DOMAIN}/privkey.pem;
|
||||||
ssl_protocols TLSv1.2 TLSv1.3;
|
ssl_protocols TLSv1.2 TLSv1.3;
|
||||||
|
|
||||||
access_log /var/log/nginx/${APP_NAME}.access.log;
|
access_log /var/log/nginx/${APP_NAME}.access.log;
|
||||||
@@ -300,7 +301,7 @@ ${proxy_locations}
|
|||||||
SSL_EOF
|
SSL_EOF
|
||||||
)
|
)
|
||||||
else
|
else
|
||||||
warn "未找到 /etc/letsencrypt/live/${DOMAIN}/ 证书,本次仅写 80 配置(不跳转 HTTPS);证书签发后重跑: $0 --sync-nginx"
|
warn "未找到 ${CERT_DIR}/${DOMAIN}/ 证书,本次仅写 80 配置(不跳转 HTTPS);证书签发后重跑: $0 --sync-nginx"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# 80 端口:有证书时仅 ACME 验证 + 301 跳转;无证书时直接反代
|
# 80 端口:有证书时仅 ACME 验证 + 301 跳转;无证书时直接反代
|
||||||
@@ -321,7 +322,7 @@ server {
|
|||||||
access_log /var/log/nginx/${APP_NAME}.access.log;
|
access_log /var/log/nginx/${APP_NAME}.access.log;
|
||||||
error_log /var/log/nginx/${APP_NAME}.error.log;
|
error_log /var/log/nginx/${APP_NAME}.error.log;
|
||||||
|
|
||||||
# ACME http-01 验证(certbot webroot 模式依赖)
|
# ACME http-01 验证(acme.sh webroot 模式依赖)
|
||||||
location /.well-known/acme-challenge/ {
|
location /.well-known/acme-challenge/ {
|
||||||
root /var/www/html;
|
root /var/www/html;
|
||||||
}
|
}
|
||||||
@@ -506,36 +507,31 @@ EOF
|
|||||||
write_nginx_conf
|
write_nginx_conf
|
||||||
|
|
||||||
|
|
||||||
# ---- Certbot 续期后自动重载 Nginx(deploy-hook 只在续期成功时执行)----
|
# ---- 首次初始化自动申请 HTTPS 证书(一次性;续期由 acme.sh cron 自动处理)----
|
||||||
HOOK_FILE="/etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh"
|
if [ -f "${CERT_DIR}/${DOMAIN}/fullchain.pem" ]; then
|
||||||
if [ ! -f "${HOOK_FILE}" ]; then
|
|
||||||
log "创建 Certbot 续期重载 Hook: ${HOOK_FILE}"
|
|
||||||
$SUDO mkdir -p /etc/letsencrypt/renewal-hooks/deploy/
|
|
||||||
$SUDO tee "${HOOK_FILE}" >/dev/null <<'HOOK'
|
|
||||||
#!/bin/bash
|
|
||||||
if /usr/sbin/nginx -t 2>/dev/null; then
|
|
||||||
systemctl reload nginx
|
|
||||||
fi
|
|
||||||
HOOK
|
|
||||||
$SUDO chmod +x "${HOOK_FILE}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# ---- 首次初始化自动申请 HTTPS 证书(一次性;续期由 certbot.timer 自动处理)----
|
|
||||||
if [ ! -d "/etc/letsencrypt/live/${DOMAIN}" ]; then
|
|
||||||
if command -v certbot >/dev/null 2>&1; then
|
|
||||||
log "未检测到证书,尝试自动申请: ${DOMAIN}"
|
|
||||||
$SUDO mkdir -p /var/www/html
|
|
||||||
if $SUDO certbot certonly --webroot -w /var/www/html -d "${DOMAIN}" --non-interactive --agree-tos -m "${CERT_EMAIL}"; then
|
|
||||||
log "证书申请成功,写入 443 配置..."
|
|
||||||
write_nginx_conf
|
|
||||||
else
|
|
||||||
warn "证书申请失败,请检查域名解析与 80 端口;成功后重跑: $0 --sync-nginx"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
warn "未安装 certbot,跳过证书申请。可手动执行: dnf install certbot python3-certbot-nginx"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
log "证书已存在,跳过申请"
|
log "证书已存在,跳过申请"
|
||||||
|
else
|
||||||
|
# 定位 acme.sh:PATH → 当前用户目录 → root 目录(sudo 后 HOME 可能被重置)
|
||||||
|
ACME_SH="$(command -v acme.sh 2>/dev/null || true)"
|
||||||
|
for c in "${HOME}/.acme.sh/acme.sh" "/root/.acme.sh/acme.sh"; do
|
||||||
|
if [ -z "$ACME_SH" ] && [ -x "$c" ]; then ACME_SH="$c"; fi
|
||||||
|
done
|
||||||
|
if [ -z "$ACME_SH" ]; then
|
||||||
|
err "未找到 acme.sh,请先安装: curl https://get.acme.sh | sh -s email=${CERT_EMAIL}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
log "未检测到证书,使用 acme.sh 申请: ${DOMAIN}"
|
||||||
|
$SUDO mkdir -p /var/www/html "${CERT_DIR}/${DOMAIN}"
|
||||||
|
if $SUDO "$ACME_SH" --issue -d "${DOMAIN}" -w /var/www/html --server letsencrypt --keylength ec-256 -m "${CERT_EMAIL}" \
|
||||||
|
&& $SUDO "$ACME_SH" --install-cert -d "${DOMAIN}" --ecc \
|
||||||
|
--fullchain-file "${CERT_DIR}/${DOMAIN}/fullchain.pem" \
|
||||||
|
--key-file "${CERT_DIR}/${DOMAIN}/privkey.pem" \
|
||||||
|
--reloadcmd "systemctl reload nginx"; then
|
||||||
|
log "证书申请成功,写入 443 配置..."
|
||||||
|
write_nginx_conf
|
||||||
|
else
|
||||||
|
warn "证书申请失败,请检查域名解析与 80 端口;成功后重跑: $0 --sync-nginx"
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if command -v getenforce >/dev/null 2>&1 && [ "$(getenforce)" != "Disabled" ]; then
|
if command -v getenforce >/dev/null 2>&1 && [ "$(getenforce)" != "Disabled" ]; then
|
||||||
|
|||||||
Reference in new issue
Block a user