广告位 · 页头(后台-模块管理-新建模块后替换此区域)

phpEnv如何配置多个SSL证书?多站点HTTPS共存配置详解 · 其它

在phpEnv环境中同时运行多个HTTPS站点时,证书配置并不是在某个全局选项里填一次就能生效。无论是Nginx还是Apache模式,都需要为每个虚拟主机明确指定对应的证书文件路径,并确保服务器支持SNI。下面从原理到配置逐步展开。

phpEnv如何配置多个SSL证书?多站点HTTPS共存配置详解

SNI与端口复用的工作原理

HTTPS默认使用443端口。如果一台服务器只监听一个443端口,却要服务多个域名,就依赖SNI(Server Name Indication)扩展。在TLS握手阶段,客户端会把它要访问的域名明文发送给服务器,服务器根据这个域名选择对应的证书返回。phpEnv内置的Nginx和Apache都已经支持SNI,所以只需要让每个虚拟主机同时监听443端口,并配置各自的证书,就能共存。

不过需要注意,SNI在极老的客户端(如Windows XP上的IE6)中不受支持,这类客户端会拿到默认站点的证书。因此如果某些旧客户端还需要访问,最好把最常用的站点设置为默认server。Nginx中通过default_server标记,Apache中则把默认VirtualHost放在最前面或用NameVirtualHost。

还有一个容易忽略的地方是证书与域名的匹配关系。如果你拥有多个子域名,可以使用一张通配符证书,也可以为每个子域名单独签发。但phpEnv配置层面两者没有区别,只是证书文件不同。通配符证书能减少文件数量,但私钥泄露影响面更大;单独证书则更灵活。下面分别说明两种服务器的写法。

Nginx环境配置多站点SSL证书

phpEnv的Nginx模式通常把站点配置放在vhosts或conf/vhost目录下。每个站点一个.conf文件。多证书共存关键是每个server块监听443 ssl,并使用不同的server_name和证书路径。不要在http全局块里配置ssl_certificate,那样所有站点会共用一张证书。

server {
    listen 443 ssl;
    server_name www.a.com;
    ssl_certificate     D:/phpEnv/ssl/a.com/fullchain.pem;
    ssl_certificate_key D:/phpEnv/ssl/a.com/privkey.pem;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;
    root D:/wwwroot/a.com;
    index index.php index.html;
    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }
    location ~ \.php$ {
        fastcgi_pass 127.0.0.1:9000;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }
}

对于第二个站点,再写一个server块,监听同样443端口,指定server_name www.b.com,并指向B.com的证书。两个server块可以放在同一个文件里,也可以分开。推荐分开,便于维护。配置完成后用nginx -t测试语法,再重启服务。

如果所有站点都需要强制HTTPS,不必依赖phpEnv面板的跳转设置,可以在每个server块中添加一个80端口监听并做301跳转。但要注意,如果多个站点的80端口跳转都写在各自的配置文件里,server_name必须精确匹配,否则可能发生跳转串站。下面是一个安全写法。

server {
    listen 80;
    server_name www.b.com;
    return 301 https://www.b.com$request_uri;
}

这段代码中的$request_uri会保留原始路径和查询参数,避免出现所有请求都回到首页。同时,nginx在匹配server_name时会优先选择精确匹配,所以不会影响A站点。

Apache环境配置多站点SSL证书

phpEnv的Apache模式下,虚拟主机通常配置在httpd-vhosts.conf中。Apache的多SSL站点同样基于SNI,需要为每个VirtualHost监听443端口,并加载SSL模块。与Nginx不同的地方在于Apache的证书指令写在VirtualHost内部,并且早期版本对SNI的支持依赖mod_ssl和NameVirtualHost设置。

<VirtualHost *:443>
    ServerName www.a.com
    DocumentRoot "D:/wwwroot/a.com"
    SSLEngine on
    SSLCertificateFile "D:/phpEnv/ssl/a.com/fullchain.pem"
    SSLCertificateKeyFile "D:/phpEnv/ssl/a.com/privkey.pem"
    SSLCertificateChainFile "D:/phpEnv/ssl/a.com/chain.pem"
    <Directory "D:/wwwroot/a.com">
        Options Indexes FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>
</VirtualHost>
<VirtualHost *:443>
    ServerName www.b.com
    DocumentRoot "D:/wwwroot/b.com"
    SSLEngine on
    SSLCertificateFile "D:/phpEnv/ssl/b.com/fullchain.pem"
    SSLCertificateKeyFile "D:/phpEnv/ssl/b.com/privkey.pem"
    SSLCertificateChainFile "D:/phpEnv/ssl/b.com/chain.pem"
    <Directory "D:/wwwroot/b.com">
        Options Indexes FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>
</VirtualHost>

上面两个VirtualHost都使用*:443,Apache会根据SNI中的域名选择对应配置。如果希望第一个作为默认虚拟主机,要让它的定义先于其他站点。对于HTTP跳转HTTPS,可以再添加80端口的VirtualHost,使用Redirect指令。

<VirtualHost *:80>
    ServerName www.b.com
    Redirect permanent / https://www.b.com/
</VirtualHost>

配置完成后先在phpEnv面板中切换或重启Apache,使用apachectl -t检查语法。若启动时报错提示SSLCertificateFile路径不存在,检查反斜杠和盘符是否正确。Windows路径建议使用正斜杠或双反斜杠,但phpEnv通常能识别单反斜杠,只要与配置文件中的引用方式保持一致即可。

证书文件准备与常见问题排查

多站点HTTPS共存最容易出问题的是证书链不完整。很多证书机构签发的证书需要将中间证书与站点证书拼接成一个fullchain文件。如果只填写站点证书,浏览器可以显示证书,但有些客户端会报证书不受信任。Nginx一般推荐使用fullchain.pem,Apache则根据需要分别填写SSLCertificateFile和SSLCertificateChainFile。

另一个高频错误是私钥与证书不匹配。可以用openssl命令快速验证:

openssl x509 -noout -modulus -in fullchain.pem | openssl md5
openssl rsa -noout -modulus -in privkey.pem | openssl md5

如果两个MD5值一致,说明证书和私钥是配对的。不一致则需要重新下载或生成。此外,如果访问B站点时浏览器地址栏出现证书错误提示,且证书显示为A站点的,大概率是SNI没有生效,或者Nginx/Apache版本过低。phpEnv较新的版本默认支持,如果使用老版本需要升级或检查编译参数。

端口冲突也是排查方向之一。如果phpEnv的Nginx启动后自动退出,查看logs/error.log中是否有address in use。多数情况下是其他程序占用了443或80端口,可以用netstat -ano | findstr :443查PID,再在任务管理器中结束对应进程。部分Windows系统上IIS或Remote Desktop可能占用443,需要先停止这些服务。

关于证书文件路径,建议统一放在固定的ssl目录,例如D:\phpEnv\ssl\域名\,每个站点一个子目录。权限方面phpEnv运行用户需要对私钥文件有读取权限。虽然Windows下权限问题较少,但如果使用NTFS的EFS加密或从其他机器复制时继承了受限ACL,可能导致nginx读取失败。

广告位 · 文章底部(后台-模块管理替换此区域)