有没有办法为一个域及其所有子域设置 SSL?

有没有办法为一个域及其所有子域设置 SSL?

假设我有一个域名,里面有很多子域名。比如说example.com,,,,等等。a.example.comb.example.comc.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 

相关内容