同一 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/代理也只是改变信任边界,不能保证域名绝对保密。


参考资料

本文依据官方资料核对,未进行现场运行测试;代码与配置示例需结合实际版本、权限和环境验证。

延伸阅读

获取专属方案

联系我们

加入社区

微信扫码
加入官方交流群

立即体验

在线开通,按量计费,真正的云服务!

立即开始

选择观测云版本

代码托管平台