部署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