我正在使用 Let's Encrypt ( certonly
) 为托管在 Apache 服务器上的几个网站生成 SSL 证书。这些证书的文件位置在创建之前就已经确定了,因此我提前将它们的路径写入我的虚拟主机配置中。网站运行后,我将使用它certbot
来获取证书文件,然后重新加载 Apache 配置。
我还有一个定义了有效文件的全局 SSL 证书,因此每个 SSL 虚拟主机肯定都会有一个证书。
我遇到的问题是,尽管有全局后备,但如果没有所有证书文件,Apache 也无法运行。我尝试使用 有条件地配置 Let's Encrypt 证书,只有当文件存在时才使用IF
,但 Apache 说SSLCertificateFile not allowed here
。
当新证书文件存在时,我如何才能覆盖全局SSLCertificateFile
?我试图完成所有这些操作,而无需在生成证书之前和之后修改配置。
以下是我尝试过的:
<If "-f '/etc/letsencrypt/live/domain/fullchain.pem'">
SSLCertificateFile /etc/letsencrypt/live/domain/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/domain/privkey.pem
</If>
→ SSLCertificateFile not allowed here
答案1
在这种情况下,我将为每个域创建一个符号链接目录,并对尚未配置的域使用服务器的 snakeoil 证书(或您之前提到的“全局”证书)。例如:
$ ls -1 /etc/ssl/domains
example.com/fullchain.pem -> /etc/letsencrypt/live/example.com/fullchain.pem
example.com/privkey.pem -> /etc/letsencrypt/live/example.com/privkey.pem
second-example.com/fullchain.pem -> /etc/ssl/certs/ssl-cert-snakeoil.pem
second-example.com/privkey.pem -> /etc/ssl/private/ssl-cert-snakeoil.key
然后,您可以设置 Apache 指令以使用符号链接目录:
SSLCertificateFile /etc/ssl/domains/example.com/fullchain.pem
SSLCertificateKeyFile /etc/ssl/domains/example.com/privkey.pem
这样做的好处是,仅在为域生成 Let's Encrypt 证书时才需要替换符号链接,但是在安装完整证书之前访问该域的用户将收到警告,因为 snakeoil 证书是自签名的。
答案2
您可以使用IfFile
:If
<IfFile "/etc/letsencrypt/live/www.example.com/fullchain.pem">
SSLEngine on
...
</IfFile>
这是有效的,因为IfFile
条件是在启动:
Encloses directives that will be processed only if file exists at startup
鉴于If
评估为运行:
Contains directives that apply only if a condition is satisfied by a request at runtime
配置 SSLEngine 必须在启动时完成,不能在运行时完成。
引言来自Apache 2.4 核心功能文档。
答案3
另一个想法:如果我理解正确的话,您有一个全局虚拟主机作为总括,然后是其他虚拟主机,每个网站一个。如果网站尚未关联的 SSL 证书,则根本不应配置它。您可以将每个网站配置放在其自己的文件中,并有 2 个目录:sites-enabled
并sites-waiting
使用 Apache 配置说明包含所有内容sites-enabled
。当您的网站配置完成后(意味着它有 SSL 证书),您只需将其配置从一个目录移动到另一个目录,然后重新加载 Apache。
各种 Linux 发行版均已完成此类设置。
答案4
通过在 apache 的 https .conf 文件中添加 IfFile 指令解决了所有问题:
<IfFile "/etc/dehydrated/certs/hss.yatebts.com/fullchain.pem">
SSLEngine on
SSLCertificateFile /etc/dehydrated/certs/hss.yatebts.com/fullchain.pem
SSLCertificateKeyFile /etc/dehydrated/certs/hss.yatebts.com/privkey.pem
SSLCertificateChainFile /etc/dehydrated/certs/hss.yatebts.com/chain.pem
</IfFile>
另外,为了测试一切正常,请尝试:su - apache -c“/usr/sbin/httpd -t -D DUMP_MODULES”
如果此命令不起作用,将显示哪里出了问题,您可以立即修复它。
PS:在 Apache > 2.4.35 中,IfFile 指令中的双引号中的“file”是允许的