一、业务背景
在现代Web开发中,HTTPS已成为保障数据传输安全的标准协议。特别是对于地图类API服务(如高德地图),往往需要同时支持多个子域名(如webapi.amap.com
、restapi.amap.com
等)的HTTPS访问。传统方式需要为每个域名单独配置证书,不仅管理成本高,而且容易出错。本文将详细介绍如何使用单张通配符证书+SAN证书技术,配合Nginx实现多域名HTTPS的统一管理。
二、解决思路
针对多域名HTTPS配置的挑战,我们采用以下技术方案:
-
证书生成阶段:
-
使用OpenSSL生成包含通配符域名和特定子域名的SAN证书
-
一次性覆盖
*.amap.com
及特定业务域名
-
-
Nginx配置阶段:
-
单server块监听443端口
-
动态代理到不同后端服务
-
启用SNI支持多域名
-
-
客户端适配:
-
自签名证书需要手动安装到受信任根证书
-
浏览器/移动端特殊处理
-
三、解决内容
3.1 证书生成步骤
1. 准备SAN配置文件(san.cnf
)
[req]
distinguished_name = req_distinguished_name
x509_extensions = v3_req
prompt = no[req_distinguished_name]
C = CN
ST = Beijing
L = Beijing
O = AMap
OU = Dev
CN = *.amap.com[v3_req]
keyUsage = keyEncipherment, dataEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names[alt_names]
DNS.1 = *.amap.com
DNS.2 = webapi.amap.com
DNS.3 = restapi.amap.com
DNS.4 = vdata.amap.com
2. 执行生成命令
openssl req -x509 -nodes -days 3650 -newkey rsa:2048 keyout "F:/amap.key" -out "F:/amap.crt" -config "F:/san.cnf" -extensions v3_req
3.2 客户端证书安装
Windows系统安装步骤:
-
双击
amap.crt
文件 -
选择"安装证书" → "本地计算机" → "受信任的根证书颁发机构"
-
完成向导后重启浏览器
3.3 Nginx核心配置
worker_processes auto;events {worker_connections 1024;
}http {include mime.types;default_type application/octet-stream;sendfile on;keepalive_timeout 65;# 全局DNS配置(关键)resolver 8.8.8.8 114.114.114.114 valid=300s; # 公共DNS + 超时设置resolver_timeout 5s;# 请求体大小限制client_body_buffer_size 100m;client_max_body_size 100m;# SSL优化参数ssl_session_cache shared:SSL:10m;ssl_session_timeout 10m;ssl_protocols TLSv1.2 TLSv1.3;ssl_ciphers HIGH:!aNULL:!MD5:!SHA1;ssl_prefer_server_ciphers on;# 通配符证书服务器server {listen 443 ssl;server_name webapi.amap.com restapi.amap.com vdata.amap.com www.amap.com*.amap.com;ssl_certificate cert/amap.crt;ssl_certificate_key cert/amap.key;# 动态代理核心配置location / {# 关键:使用$host变量动态代理到对应域名proxy_pass https://$host$request_uri;# HTTPS代理必须参数proxy_ssl_server_name on; # 启用SNI支持proxy_ssl_name $host; # 传递原始域名# 保持原始请求头proxy_set_header Host $host;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 $scheme;# 连接优化proxy_http_version 1.1;proxy_set_header Connection "";proxy_read_timeout 300s;proxy_cache_valid 200 302 12h;proxy_cache_key "$host$request_uri";}}
}
3.4 常见错误及解决方案
错误信息 | 原因分析 | 解决方案 |
---|---|---|
SSL_ERROR_BAD_CERT_DOMAIN | 证书域名不匹配请求域名 | 检查SAN配置包含所有子域名 |
ERR_CERT_AUTHORITY_INVALID | 证书未受信任 | 确保证书安装到"受信任的根证书" |
upstream SSL certificate verify error | Nginx证书验证失败 | 检查proxy_ssl_trusted_certificate 路径 |
certificate chain too long | 证书链不完整 | 合并中间证书到crt文件 |
no valid SSL certificate found | 证书密钥不匹配 | 重新生成证书对 |
四、总结
通过本文的实践,我们实现了:
-
一证多用:单张证书支持通配符域名和特定子域名
-
动态代理:Nginx根据请求域名自动路由
-
安全加固:启用TLS 1.2+协议和强密码套件
最佳实践建议:
-
生产环境建议使用Let's Encrypt等权威CA
-
定期轮换证书(建议不超过1年)
-
使用OCSP Stapling提升验证效率
注:本文示例适用于开发测试环境,生产环境请根据实际情况调整安全策略。