假设我有一个域名,里面有很多子域名。比如说example.com
,,,,等等。a.example.com
b.example.com
c.example.com
我想从具有相同 IP 地址的同一台服务器托管它们。
我有通配符证书和我的基本域认证,star_example_com.crt
并且example_com.crt
。
我正在尝试设置我的 Apache 服务器以支持域和子域上的 SSL,但似乎无法使其正常工作。域没有问题,但子域却不行。
这是我的配置:
NameVirtualHost *:443 # To support SNI, although, apparently, this directive is deprecated
SSLStrictSNIVHostCheck off
<VirtualHost example.com:443>
SSLEngine On
SSLCertificateFile /etc/apache2/ssl/example_com.crt
SSLCertificateKeyFile /etc/apache2/ssl/example_com.key
SetEnvIf User-Agent ".*MSIE.*" nokeepalive ssl-unclean-shutdown
DocumentRoot /var/www/html
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
<Directory /var/www/>
Options Indexes FollowSymLinks MultiViews
AllowOverride All
Order allow,deny
allow from all
</Directory>
</VirtualHost>
<VirtualHost *:443>
ServerAlias *.example.com
SSLEngine On
SSLCertificateFile /etc/apache2/ssl/star_example_com.crt
SSLCertificateKeyFile /etc/apache2/ssl/star_example_com.key
SetEnvIf User-Agent ".*MSIE.*" nokeepalive ssl-unclean-shutdown
DocumentRoot /var/www/html
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
<Directory /var/www/>
Options Indexes FollowSymLinks MultiViews
AllowOverride All
Order allow,deny
allow from all
</Directory>
</VirtualHost>
我是不是忽略了某些显而易见的东西?我只想确保域和子域使用了正确的 SSL 证书...其他一切都一样(这是一个 WordPress 多站点,所以最终一切都会转到同一个地方。
需要明确的是,当我访问子域时会出现错误,因为我没有获得通配符证书。
更清楚的是,我有 80 多个子域。如果可能的话,我想避免为每个子域创建一个 VirtualHost。
有什么指点吗?
答案1
我的声誉不足以发表评论。所以我会发布答案。首先,您应该有子域,然后是域。这取决于顺序,因此首先应该配置子域,最后是整个根域。我向您展示了我的配置,它运行完美:
/etc/apache2/sites-available/example.conf:
# ====================SSL========================
<IfModule mod_ssl.c>
## a.example.com
<VirtualHost *:443>
ServerAdmin [email protected]
ServerName a.example.com
ServerAlias *.a.example.com
DocumentRoot /home/a.example.com/www/public_html
ErrorLog /home/a.example.com/www/logs/ssl_error.log
CustomLog /home/a.example.com/www/logs/ssl_access.log combined
SSLEngine on
SSLCertificateFile /home/a.example.com/www/ssl/a.example.com.crt
SSLCertificateKeyFile /home/a.example.com/www/ssl/a.example.com.key
SSLCertificateChainFile /home/a.example.com/www/ssl/a.example.com.ca-bundle.crt
<Directory /home/a.example.com/www/public_html>
Options FollowSymLinks -MultiViews
AllowOverride All
Order allow,deny
Allow from all
Satisfy Any
</Directory>
</VirtualHost>
## /a.example.com
## example.com
<VirtualHost *:443>
ServerAdmin [email protected]
ServerName example.com
ServerAlias *.example.com
DocumentRoot /home/example.com/www/public_html/
<Directory /home/example.com/www/public_html/>
Options FollowSymLinks MultiViews
AllowOverride None
Order allow,deny
allow from all
</Directory>
ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
<Directory "/usr/lib/cgi-bin">
AllowOverride None
Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
Order allow,deny
Allow from all
</Directory>
ErrorLog /home/example.com/www/logs/ssl_error.log
# Possible values include: debug, info, notice, warn, error, crit,
# alert, emerg.
LogLevel warn
CustomLog /home/example.com/www/logs/ssl_access.log combined
# SSL Engine Switch:
# Enable/Disable SSL for this virtual host.
SSLEngine on
SSLCertificateFile /home/example.com/www/ssl/example.com.crt
SSLCertificateKeyFile /home/example.com/www/ssl/example.com.key
SSLCertificateChainFile /home/example.com/www/ssl/example.com.ca-bundle.crt
# SSL Engine Options:
<FilesMatch "\.(cgi|shtml|phtml|php)$">
SSLOptions +StdEnvVars
</FilesMatch>
<Directory /usr/lib/cgi-bin>
SSLOptions +StdEnvVars
</Directory>
# SSL Protocol Adjustments:
BrowserMatch "MSIE [2-6]" \
nokeepalive ssl-unclean-shutdown \
downgrade-1.0 force-response-1.0
# MSIE 7 and newer should be able to use keepalive
BrowserMatch "MSIE [17-9]" ssl-unclean-shutdown
</VirtualHost>
## /example.com
</IfModule>
# ====================/SSL========================
请记住,您应该将配置与您的环境进行比较,因此请在 example.com 之前添加更多域名,例如 a.example.com。希望我的回答对您有所帮助。
答案2
我的答案太长,无法评论,所以这就是我发布新答案的原因。您可以只添加 ServerAlias,而不是整个 VirtualHost,您可以指定更多 ServerAliases。但我明白你想要什么,所以如果你不想每次添加新的 wp-site 时都触碰 apache 配置 ServerAlias 文件,那么你可以尝试 VirtualDocumentRoot。我不太了解 wordpress 多站点结构是什么样的。例如,你有这样的结构:
/var/www/html/ = main WP site example.com
/var/www/html/site1/ = site1.example.com
/var/www/html/a/ = a.example.com
等等。我假设你想要翻译这样的请求:
site1.example.com > example.com/site1/
a.example.com > example.com/a/
如果您的情况类似,您应该尝试用 VirtualDocumentRoot 替换 DocumentRoot:
ServerName example.com
ServerAlias *.example.com
VirtualDocumentRoot /var/www/html/%0
您需要启用vhost_alias:
a2enmod vhost_alias
%0 将文件夹的整个名称设为“ServerAlias”,如果 wordpress 将名称设为 /var/www/html/site1.example.com/ 那么您必须将 %0 替换为 %1,下面是规则表(您也可以将它们组合起来):
0 the whole name
1 the first part
2 the second part
-1 the last part
-2 the penultimate part
2+ the second and all subsequent parts
-2+ the penultimate and all preceding parts
1+ and -1+ the same as 0
如果你尝试 VirtualDocumentRoot 记得注释掉 DocumentRoot 否则 Apache 可能无法启动。以下是虚拟主机别名。
答案3
我最终通过使用 SubjectAltName (SAN) 证书创建证书解决了这个问题。
创建 CSR 稍微复杂一些。您必须创建一个如下配置文件:
[req]
distinguished_name = req_distinguished_name
x509_extensions = v3_req
prompt = no
[req_distinguished_name]
C = US
ST = <your state>
L = <your city>
O = <your company>
CN = <your IP address>
[v3_req]
keyUsage = keyEncipherment, dataEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
[alt_names]
DNS.1 = example.com
DNS.2 = *.example.com
然后将其与您的 CSR 请求一起传递,例如:
openssl req -new -out san_example_com.csr -key san_example_com.key -config san_req.cnf