可以使用 Nginx 的 SNI(Server Name Indication) 机制,在同一个 IP 地址上通过不同的域名提供 HTTPS 服务。核心思路是:
- 每个域名使用独立的 SSL 证书(可以是通配符或泛域名证书);
- 在
server块中通过server_name区分不同域名; - 所有
server块监听同一 IP:443,但通过 SNI 自动选择对应证书。
✅ 示例配置(Nginx)
# /etc/nginx/sites-available/example.com.conf
# 域名 A
server {
listen 443 ssl;
server_name example.com www.example.com;
ssl_certificate /etc/ssl/certs/example.com.crt;
ssl_certificate_key /etc/ssl/private/example.com.key;
# 其他配置...
location / {
proxy_pass http://backend-a;
}
}
# 域名 B
server {
listen 443 ssl;
server_name test.org www.test.org;
ssl_certificate /etc/ssl/certs/test.org.crt;
ssl_certificate_key /etc/ssl/private/test.org.key;
location / {
proxy_pass http://backend-b;
}
}
# 可选:默认站点(用于未匹配 SNI 或旧客户端)
server {
listen 443 ssl default_server;
server_name _;
ssl_certificate /etc/ssl/certs/default.crt;
ssl_certificate_key /etc/ssl/private/default.key;
return 444; # 或返回错误页面
}
🔔 注意:
listen 443 ssl;可省略 IP,即监听所有 IPv4/IPv6 接口;若需绑定特定 IP,可写为listen 192.0.2.1:443 ssl;default_server仅当浏览器不支持 SNI 或请求无 Host 时使用(现代浏览器基本都支持 SNI)- 确保每个域名的证书路径正确且权限合理(如
chmod 600 key)
🌐 客户端兼容性说明
| 客户端类型 | 是否支持 SNI | 行为说明 |
|---|---|---|
| 现代浏览器 | ✅ 是 | 正常协商对应证书 |
| Android 4.2+ | ✅ 是 | 支持良好 |
| iOS 6+ | ✅ 是 | 完全支持 |
| IE8 / 老版系统 | ❌ 否 | 可能回退到 default_server 或报错 |
💡 若需兼容极老旧客户端,可考虑:
- 使用 多 IP 方案(每个域名一个独立 IP,不依赖 SNI)
- 或使用 Let’s Encrypt + ACME 自动化管理多域名证书(如
*.example.com通配符证书)
🔍 验证方式
# 检查某域名是否正确返回对应证书
openssl s_client -connect your-ip:443 -servername example.com
# 查看返回的证书主题(Subject CN 或 SAN)
输出中应显示与 example.com 匹配的证书信息。
需要我帮你生成一个完整的自动化部署脚本(含 Let’s Encrypt 证书申请),或针对反向X_X/负载均衡场景进一步优化吗?
PHPWP博客