同一 IP 上如何为多个域名配置 SSL
SNI 让同一 IP:443 按域名选择 HTTPS 证书,也可用覆盖多个名称的 SAN 证书。介绍 Nginx/Apache 配置片段、默认证书与域名验证边界。
一句话回答:可以,靠的是 TLS 的 SNI 扩展——客户端在握手开始时先明文发送"我要访问的域名",服务器据此从多张证书里挑对的那张返回。Nginx/Apache/IIS 全都支持:为每个域名建独立的 server 块(VirtualHost),各自指定证书和私钥即可,所有域名共用同一个 IP 和 443 端口。
原理一句话
TLS 握手在 HTTP 之前;没有 SNI 时通常只能选择默认 TLS 配置。也可用一张覆盖全部域名的 SAN/泛域名证书共用入口,并非任何多域名都必需独立 IP。SNI 把域名前置到握手阶段,"一 IP 一证书"的限制就此解除。
Nginx 配置
server {
listen 443 ssl;
server_name site-a.com;
ssl_certificate /etc/ssl/site-a.crt;
ssl_certificate_key /etc/ssl/site-a.key;
root /var/www/site-a;
}
server {
listen 443 ssl;
server_name site-b.com;
ssl_certificate /etc/ssl/site-b.crt;
ssl_certificate_key /etc/ssl/site-b.key;
root /var/www/site-b;
}
Apache 配置
<VirtualHost *:443>
ServerName site-a.com
SSLEngine on
SSLCertificateFile /etc/ssl/site-a.crt
SSLCertificateKeyFile /etc/ssl/site-a.key
DocumentRoot /var/www/site-a
</VirtualHost>
<VirtualHost *:443>
ServerName site-b.com
SSLEngine on
SSLCertificateFile /etc/ssl/site-b.crt
SSLCertificateKeyFile /etc/ssl/site-b.key
DocumentRoot /var/www/site-b
</VirtualHost>
验证与排错
# 分别验证各域名拿到的是不是自己的证书
echo | openssl s_client -connect 服务器IP:443 -servername site-a.com 2>/dev/null | openssl x509 -noout -subject -ext subjectAltName
echo | openssl s_client -connect 服务器IP:443 -servername site-b.com 2>/dev/null | openssl x509 -noout -subject
- 不带 -servername 时返回的是"默认证书"(第一个 server 块或 default_server)——拿错证书先查这个
- 域名身份以 SAN 为准,不能只看 subject/CN。要实际验证:
openssl s_client -connect 服务器IP:443 -servername site-a.com -verify_hostname site-a.com -verify_return_error </dev/null
共享 IP 的域名仍需分别检查证书和响应。需要持续检查时,可在观测云为各域名分别建立 HTTPS 请求任务和 SSL 证书任务,避免只检查一个域名而漏掉其他站点。
兼容性提醒
SNI 需要客户端支持。现代浏览器/操作系统全部支持;真正的盲区是上古客户端(IE6、Android 2.x、老 Java 6)。2026 年的今天除非维护特殊遗留系统,否则不需要为兼容 SNI 准备独立 IP。
常见问题(FAQ)
Q:一台服务器几十个域名,证书管理太麻烦怎么办?
A:两个方向:用泛域名证书(*.example.com 一张覆盖所有一级子域名);或 SAN 多域名证书把多个域名打进一张。Certbot/lego 都支持自动批量签发与续期。
Q:默认证书放什么好?
A:可在支持的 Nginx 版本中给独立默认 server 配 ssl_reject_handshake on;,拒绝未匹配名称的 TLS 握手。403/444 是握手后的 HTTP 行为,不能替代握手拒绝;默认站点还需限制未知 Host。
Q:SNI 是明文,会不会泄露访问的域名?
A:传统 SNI 在 ClientHello 中可见。支持并启用 ECH 的连接可能保护真实名称,但不是所有连接都有;VPN/代理也只是改变信任边界,不能保证域名绝对保密。
参考资料
本文依据官方资料核对,未进行现场运行测试;代码与配置示例需结合实际版本、权限和环境验证。
- nginx.org:configuring https servers
- nginx.org:ngx http ssl module
- httpd.apache.org:mod ssl
- docs.guance.com:http
- docs.guance.com:ssl
- docs.guance.com:synthetic test detection