打开/关闭菜单
打开/关闭外观设置菜单
打开/关闭个人菜单
未登录
未登录用户的IP地址会在进行任意编辑后公开展示。

部署https中转服务教程

来自md5.pw
这是此页面的最新修订,它没有已核准修订。

为什么要做https转发

因为公司业务在美国,服务器已经使用很久,迁移非常麻烦,现在正好有瓦工稳定机器故想到这个解决方案,可能不是最优,但是目前满足我的业务稳定分享给大家,如有不足欢迎大佬们指点。


部署Nginx

宿主机先创建这些文件

/home/docker/nginx/nginx.conf
/home/docker/nginx/conf.d
/home/docker/nginx/log
/home/docker/nginx/html
/home/docker/nginx/ssl
/home/docker/letsencrypt

安装docker

curl -fsSL https://get.docker.com -o install-docker.sh
sudo sh install-docker.sh
启动脚本startNginx.sh
sudo docker run \
-p 80:80 \
-p 443:443 \
-p 8081:8081 \
--name nginx \
-v /home/docker/nginx/nginx.conf:/etc/nginx/nginx.conf \
-v /home/docker/nginx/conf.d:/etc/nginx/conf.d \
-v /home/docker/nginx/log:/var/log/nginx \
-v /home/docker/nginx/html:/usr/share/nginx/html \
-v /home/docker/nginx/ssl:/etc/nginx/ssl \
-v /home/docker/letsencrypt:/var/www/letsencrypt \
-d nginx

证书自动续期ssl_auto.sh

#!/bin/bash

# ==============================
#  智能 SSL 自动管理脚本
#  - 每日检查证书剩余天数
#  - ≤30 天自动续期
#  - webroot 模式(不中断服务)
# ========== 运行模式 ==========
DRY_RUN=false   # true = 测试模式(不真正续期)
# ==============================


NGINX_CONTAINER="nginx"
WEBROOT="/home/docker/letsencrypt"
SSL_DIR="/home/docker/nginx/ssl"
RENEW_BEFORE_DAYS=30

DOMAINS=(
  "xxxxx"
)

echo "============================"
echo " 🔐 SSL 自动检查启动 $(date)"
echo "============================"

mkdir -p "$WEBROOT/.well-known/acme-challenge/"

need_restart_nginx=false

for DOMAIN in "${DOMAINS[@]}"; do
  CERT_PATH="/etc/letsencrypt/live/$DOMAIN/fullchain.pem"

  echo ""
  echo "👉 检查域名:$DOMAIN"

  # 如果证书不存在,直接申请
  if [ ! -f "$CERT_PATH" ]; then
    echo "⚠  未发现证书,立即申请"
    renew=true
  else
    # 获取过期时间
    expire_date=$(openssl x509 -enddate -noout -in "$CERT_PATH" | cut -d= -f2)
    expire_ts=$(date -d "$expire_date" +%s)
    now_ts=$(date +%s)

    days_left=$(( (expire_ts - now_ts) / 86400 ))

    echo "📅 剩余有效期:$days_left 天"

    if [ "$days_left" -le "$RENEW_BEFORE_DAYS" ]; then
      echo "⏰ 低于 $RENEW_BEFORE_DAYS 天,需要续期"
      renew=true
    else
      echo "✅ 证书仍然有效,跳过"
      renew=false
    fi
  fi

#   if [ "$renew" = true ]; then
#     echo "🔄 正在申请/续期:$DOMAIN"

#     certbot certonly \
#       --webroot -w "$WEBROOT" \
#       -d "$DOMAIN" \
#       --non-interactive \
#       --agree-tos \
#       -m admin@$DOMAIN

#     if [ $? -ne 0 ]; then
#       echo "❌ 续期失败:$DOMAIN"
#       continue
#     fi

if [ "$renew" = true ]; then
  echo "🔄 正在申请/续期:$DOMAIN"

  CERTBOT_ARGS=(
    certonly
    --webroot -w "$WEBROOT"
    -d "$DOMAIN"
    --non-interactive
    --agree-tos
    -m admin@$DOMAIN
  )

  if [ "$DRY_RUN" = true ]; then
    CERTBOT_ARGS+=(--dry-run)
    echo "🧪 DRY-RUN 模式:仅测试,不会真正更新证书"
  fi

  certbot "${CERTBOT_ARGS[@]}"

  if [ $? -ne 0 ]; then
    echo "❌ 续期失败:$DOMAIN"
    # 这里之后你可以接邮件/钉钉告警
    continue
  fi

  echo "✅ certbot 执行成功:$DOMAIN"

  # dry-run 模式不做后续动作
  if [ "$DRY_RUN" = true ]; then
    echo "🧪 DRY-RUN 模式:跳过证书复制与 Nginx 重启"
    continue
  fi


    echo "✅ 续期成功:$DOMAIN"

    # 复制到 nginx ssl 目录
    cp -f /etc/letsencrypt/live/$DOMAIN/fullchain.pem \
      $SSL_DIR/$DOMAIN.pem
    cp -f /etc/letsencrypt/live/$DOMAIN/privkey.pem \
      $SSL_DIR/$DOMAIN.key

    chmod 644 $SSL_DIR/$DOMAIN.pem
    chmod 600 $SSL_DIR/$DOMAIN.key

    need_restart_nginx=true
    echo "📦 证书已更新到 Nginx 目录"
  fi
done

# 如有证书更新才重启 nginx
if [ "$need_restart_nginx" = true ]; then
  echo ""
  echo "🔄 重启 Nginx 容器"
  docker restart $NGINX_CONTAINER
  echo "✅ Nginx 重启完成"
else
  echo ""
  echo "ℹ️  无证书变更,无需重启 Nginx"
fi

echo ""
echo "🎉 SSL 检查完成"

Nginx.conf配置文件

server {
    listen 80;
    server_name xxx;

    location /.well-known/acme-challenge/ {
        alias /var/www/letsencrypt/.well-known/acme-challenge/;
        try_files $uri =404;
    }

    location / {
        return 301 https://$host$request_uri;
    }
}

upstream put_api_backend {
    server xxxxx:443;
    keepalive 100;
}

server {
    listen 443 ssl;
    server_name xxx;

    ssl_certificate     /etc/nginx/ssl/xxx.pem;
    ssl_certificate_key /etc/nginx/ssl/xxx.key;

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;

    access_log /var/log/nginx/xxx.access.log;
    error_log  /var/log/nginx/xxx.error.log warn;

    # ACME challenge(HTTPS 续期仍然需要)
    location /.well-known/acme-challenge/ {
        alias /var/www/letsencrypt/.well-known/acme-challenge/;
        try_files $uri =404;
    }

    # API 中转
    location /api {
        proxy_pass https://put_api_backend;
        proxy_ssl_server_name on;

        proxy_http_version 1.1;
        proxy_set_header Connection "";

        proxy_set_header Host xxx;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto https;

        proxy_connect_timeout 5s;
        proxy_read_timeout    30s;
        proxy_send_timeout    30s;
    }

    # 其他路径拒绝
    location / {
        return 404;
    }
}

重启Nginx

docker exec -it nginx nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
root@ubuntu:/home/docker/nginx# docker exec -it nginx nginx -s reload