#!/bin/bash # 智能项目定价模型 - SSL 证书配置脚本 # 使用 Let's Encrypt 申请免费 SSL 证书 # 遵循瑞小美部署规范 set -e # 配置 DOMAIN="${DOMAIN:-pricing.example.com}" EMAIL="${EMAIL:-admin@example.com}" WEBROOT="/var/www/certbot" CERT_DIR="/etc/letsencrypt/live/${DOMAIN}" NGINX_SSL_DIR="/etc/nginx/ssl" # 颜色输出 RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' log_info() { echo -e "${GREEN}[INFO]${NC} $1" } log_warn() { echo -e "${YELLOW}[WARN]${NC} $1" } log_error() { echo -e "${RED}[ERROR]${NC} $1" } # 检查 certbot check_certbot() { if ! command -v certbot &> /dev/null; then log_info "安装 certbot..." # Debian/Ubuntu if command -v apt-get &> /dev/null; then apt-get update apt-get install -y certbot # CentOS/RHEL elif command -v yum &> /dev/null; then yum install -y epel-release yum install -y certbot else log_error "不支持的系统,请手动安装 certbot" exit 1 fi fi log_info "certbot 版本: $(certbot --version)" } # 创建 webroot 目录 create_webroot() { if [ ! -d "$WEBROOT" ]; then mkdir -p "$WEBROOT" chmod 755 "$WEBROOT" fi } # 申请证书 request_certificate() { log_info "申请 SSL 证书: $DOMAIN" # 确保 webroot 可访问 create_webroot # 申请证书 certbot certonly \ --webroot \ --webroot-path="$WEBROOT" \ --email "$EMAIL" \ --agree-tos \ --no-eff-email \ -d "$DOMAIN" if [ $? -eq 0 ]; then log_info "证书申请成功" else log_error "证书申请失败" exit 1 fi } # 复制证书到 Nginx 目录 copy_certificates() { log_info "复制证书到 Nginx 配置目录..." if [ ! -d "$NGINX_SSL_DIR" ]; then mkdir -p "$NGINX_SSL_DIR" fi # Let's Encrypt 证书路径 if [ -d "$CERT_DIR" ]; then cp "${CERT_DIR}/fullchain.pem" "${NGINX_SSL_DIR}/${DOMAIN}.pem" cp "${CERT_DIR}/privkey.pem" "${NGINX_SSL_DIR}/${DOMAIN}.key" chmod 600 "${NGINX_SSL_DIR}/${DOMAIN}.key" log_info "证书已复制到 ${NGINX_SSL_DIR}/" else log_error "证书目录不存在: $CERT_DIR" exit 1 fi } # 配置自动续期 setup_auto_renewal() { log_info "配置证书自动续期..." # 创建续期后的钩子脚本 local hook_script="/etc/letsencrypt/renewal-hooks/post/pricing-ssl-renewal.sh" cat > "$hook_script" << 'EOF' #!/bin/bash # SSL 证书续期后自动更新 DOMAIN="pricing.example.com" NGINX_SSL_DIR="/etc/nginx/ssl" CERT_DIR="/etc/letsencrypt/live/${DOMAIN}" cp "${CERT_DIR}/fullchain.pem" "${NGINX_SSL_DIR}/${DOMAIN}.pem" cp "${CERT_DIR}/privkey.pem" "${NGINX_SSL_DIR}/${DOMAIN}.key" chmod 600 "${NGINX_SSL_DIR}/${DOMAIN}.key" # 重载 Nginx docker exec nginx_proxy nginx -s reload 2>/dev/null || nginx -s reload 2>/dev/null || true EOF chmod +x "$hook_script" # 测试续期 certbot renew --dry-run log_info "自动续期已配置(每天自动检查)" } # 显示证书信息 show_certificate_info() { log_info "证书信息:" echo "" if [ -f "${NGINX_SSL_DIR}/${DOMAIN}.pem" ]; then openssl x509 -in "${NGINX_SSL_DIR}/${DOMAIN}.pem" -noout -subject -dates else log_warn "证书文件不存在" fi echo "" } # 手动证书配置说明 show_manual_instructions() { cat << EOF =============================================== 手动配置 SSL 证书说明 =============================================== 如果您已有 SSL 证书(购买的或其他方式获取),请按以下步骤配置: 1. 将证书文件复制到 Nginx SSL 目录: mkdir -p /etc/nginx/ssl cp your_certificate.pem /etc/nginx/ssl/${DOMAIN}.pem cp your_private_key.key /etc/nginx/ssl/${DOMAIN}.key chmod 600 /etc/nginx/ssl/${DOMAIN}.key 2. 确保 nginx.conf 中的证书路径正确: ssl_certificate /etc/nginx/ssl/${DOMAIN}.pem; ssl_certificate_key /etc/nginx/ssl/${DOMAIN}.key; 3. 重载 Nginx: docker exec nginx_proxy nginx -s reload =============================================== EOF } # 主函数 main() { local action="${1:-help}" case $action in request) check_certbot request_certificate copy_certificates setup_auto_renewal show_certificate_info ;; renew) certbot renew copy_certificates docker exec nginx_proxy nginx -s reload 2>/dev/null || log_warn "请手动重载 Nginx" ;; copy) copy_certificates ;; info) show_certificate_info ;; manual) show_manual_instructions ;; *) echo "智能项目定价模型 - SSL 证书配置" echo "" echo "用法: DOMAIN=your.domain.com EMAIL=your@email.com $0 {request|renew|copy|info|manual}" echo "" echo "命令:" echo " request 申请 Let's Encrypt 证书" echo " renew 续期证书" echo " copy 复制证书到 Nginx 目录" echo " info 显示证书信息" echo " manual 显示手动配置说明" echo "" echo "环境变量:" echo " DOMAIN 域名 (默认: pricing.example.com)" echo " EMAIL 管理员邮箱 (默认: admin@example.com)" echo "" echo "示例:" echo " DOMAIN=pricing.mycompany.com EMAIL=admin@mycompany.com $0 request" ;; esac } main "$@"