用户在  Apache  上配置基于域名的国密  SSL证书虚拟主机,关键是从  `NameVirtualHost`  指令入手,结合  SNI  技术实现多站点共享端口,并通过  `GmSSL`  编译版  Apache  和特定模块来支持国密算法。下面是具体的配置方案:

1.  环境前提

配置前,Apache  版本必须在  2.2.12  以上,并且编译时需支持  SNI(这是多域名  SSL  虚拟主机的基础)。由于  原生  Apache  系列并不支持国密算法,你需要先完成以下两步:

      安装  GmSSL:下载并安装  `GmSSL`(一个支持国密算法(SM2/SM3/SM4)的  OpenSSL  分支)。

      重新编译  Apache:将  Apache  与  `GmSSL`  库链接,进行重新编译。编译时,`./configure`  参数中要包含  `--with-ssl=/path/to/gmssl`,以指向你的  `GmSSL`  安装路径。

2.  双证书配置示例

当前,很多浏览器还不原生支持国密算法,为保证网站对所有访客都可访问,最佳实践是采用  SM2  国密证书与  RSA  证书并存的**双证书部署方案。这能确保国密浏览器使用  SM2  证书,而普通浏览器则回退到  RSA  证书。

下面是一个完整的  Apache  虚拟主机  `ssl.conf`  配置示例,它通过  **NameVirtualHost**  和  SNI  技术,将两个不同域名的  HTTPS  站点部署在同一个  IP  地址上。

apache

#  1.  启用虚拟主机并监听443端口

Listen  443

#  核心指令:声明监听443端口的基于域名的虚拟主机

NameVirtualHost  *:443

#  2.  为第一个域名  (example1.com)  启用双证书

<VirtualHost  *:443>

        ServerName  example1.com

        DocumentRoot  "/var/www/html/example1"

        #  启用SSL引擎

        SSLEngine  on

        #  ---  RSA证书配置  ---

        SSLCertificateFile  "/etc/ssl/rsa/example1.com.crt"

        SSLCertificateKeyFile  "/etc/ssl/rsa/example1.com.key"

        SSLCertificateChainFile  "/etc/ssl/rsa/ca_bundle.crt"

        #  ---  国密  SM2  证书配置  (通过  GmSSL  模块启用)  ---

        #  注意:此处参数因  GmSSL  模块实现而异,请查阅相关文档

        GMSSLCertificateFile  "/etc/ssl/sm2/example1.com.sm2.crt"

        GMSSLCertificateKeyFile  "/etc/ssl/sm2/example1.com.sm2.key"

                #  配置国密专用的加密套件

        SSLCipherSuite  "ECDHE-SM2-WITH-SM4-GCM-SM3:HIGH:!aNULL"

          #  可选配置:优先使用服务器端推荐的加密套件顺序

        SSLHonorCipherOrder  on

        <Directory  "/var/www/html/example1">

                Options  Indexes  FollowSymLinks

                AllowOverride  All

                Require  all  granted

        </Directory>

</VirtualHost>

#  3.  为第二个域名  (example2.com)  启用双证书

<VirtualHost  *:443>

        ServerName  example2.com

        DocumentRoot  "/var/www/html/example2"

      SSLEngine  on

        #  ---  RSA证书配置  ---

        SSLCertificateFile  "/etc/ssl/rsa/example2.com.crt"

        SSLCertificateKeyFile  "/etc/ssl/rsa/example2.com.key"

        SSLCertificateChainFile  "/etc/ssl/rsa/ca_bundle.crt"

        #  ---  国密  SM2  证书配置  ---

        GMSSLCertificateFile  "/etc/ssl/sm2/example2.com.sm2.crt"

        GMSSLCertificateKeyFile  "/etc/ssl/sm2/example2.com.sm2.key"

                #  配置国密专用的加密套件,与上例保持一致

        SSLCipherSuite  "ECDHE-SM2-WITH-SM4-GCM-SM3:HIGH:!aNULL"

        SSLHonorCipherOrder  on

        <Directory  "/var/www/html/example2">

                Options  Indexes  FollowSymLinks

                AllowOverride  All

                Require  all  granted

        </Directory>

</VirtualHost>

配置指令说明

      `Listen  443`  与  `NameVirtualHost  *:443`:这是实现单  IP  多  HTTPS  站点的核心。`Listen`  指令通知  Apache  在  443  端口监听,而  `NameVirtualHost`  指令则声明了所有来自  443  端口的请求将使用基于域名的虚拟主机进行分发。

      `<VirtualHost  *:443>`:配置块中的  `*`  代表任意  IP  地址,这使其能够与  `NameVirtualHost`  声明相匹配。

      `GMSSLCertificateFile`  等:这是启用国密算法的关键,需要通过  `GmSSL`  模块加载并配置  SM2  证书和对应的  SM4  加密算法套件。

      `SSLHonorCipherOrder  on`:该指令指示  Apache  优先使用服务器端配置的加密套件顺序,而非客户端的偏好,建议开启以提高安全性。

3.  配置验证

  1.    重启  Apache:完成配置后,重启  Apache  服务使改动生效。

  2.    验证国密通道(使用国密浏览器)**:在支持国密算法的浏览器(如密信浏览器、红莲花浏览器)中访问  `https://example1.com`,检查地址栏是否出现安全锁标识。

  3.    验证  RSA  通道(使用普通浏览器):在  Chrome、Firefox  等常用浏览器中访问相同域名,也应能正常打开  HTTPS  页面,这表明  RSA  回退配置成功。

4.  常见问题排查

      Apache  启动报错  "Cannot  define  multiple  Listeners  on  the  same  IP:port"

        最常见的原因是  SSL  配置文件(如  `ssl.conf`)被重复加载了多次。请检查  Apache  的主配置文件(如  `httpd.conf`),确保  `ssl.conf`  没有被重复引用多次。

              Apache  启动时报错  "name-based  virtual  host  in  conjunction  with  SSL!!"

        这个警告信息意味着你的  Apache  没有正确启用或识别  SNI  支持。请先确认你的  Apache  版本在  2.2.12  以上,并检查编译时是否对  OpenSSL  启用了  TLS  扩展支持。可以通过  `httpd  -V`  查看  Apache  版本和编译参数。

      配置验证报错  "The  GMSSLCertificateFile  directive  is  not  recognized"

        这个错误是因为缺少国密模块支持,说明当前的  Apache  是官方版本,没有被重新编译或没有链接到  `GmSSL`  库。你需要重新根据  `GmSSL`  文档编译部署。

      浏览器(或代理)不支持,应如何处理?

        部分老旧或特定配置的客户端可能不支持  SNI。在这种情况下,如果必须保证服务可用,可以为需要单独证书的域名配置独立的  IP  地址或端口,或使用一张包含所有域名的多域名(SAN)证书。