如何使用 mod_vhost_alias 配置 apache2/httpd 大规模虚拟主机的 SSL

如何使用 mod_vhost_alias 配置 apache2/httpd 大规模虚拟主机的 SSL

我已经搜索了很多次但找不到任何答案。

我正在使用 httpd 2.2.15 和 Centos 6.2。

我已经将 apache 配置为大规模虚拟主机。例如:

UseCanonicalName off
VirtualDocumentRoot /var/www/html/%0

我将拥有相同的“主”域和指向虚拟主机的不同子域。我已创建自签名证书用于测试,通用名称为 *.mydomain.com。整个服务器只有一个 IP。

我该如何配置 apache 以便为我的 vhosts 使用 ssl?

如果可能的话,除了上述内容之外,我还想实现这一点:

  1. 我可以定义一个目录,或者最好是一些文件(例如登录页面),将其排除在 SSL 之外吗?所有 vhost 基本上都是同一应用程序的不同实例(除了我在下面 2 中提到的那些)。

  2. 我可以定义一些不应使用 SSL 的虚拟主机吗(我对这些虚拟主机的子域名有完全控制权)。这将是两个应用程序,我的主页 (www) 和一些管理应用程序。如果无法做出例外,我想我会将它们放在另一台服务器上。

除了我在上面第 2 点中提到的以外,所有虚拟主机都将根据用户请求自动创建。

根据@Shanes 的评论,我更新:如果用户在不应该使用 https:// 时使用了它,最好将他们重定向到 http://。如果这不可能,我猜他们收到错误消息也没关系。当然,如果 http 和 https 都可以工作,那就没问题了,只要 http 适用于不受保护的文件(实际上这可能是首选)。

我可以找到如何使用 mod-rewrite 执行此操作的示例,但它不适用于海量域名(即使用了 <VirtualHost>)。

实现这一目标的技巧是什么?

如果不可能的话,我会非常高兴得到一些关于如何做到这一点的提示。

答案1

首先,您需要确保您当前的配置已准备好添加 SSL 侦听器。您尚未指定是使用主服务器还是<VirtualHost>,但如果您使用主服务器,则需要切换到<VirtualHost>

<VirtualHost *:80>
    ServerName everything.example.com
    ServerAlias *.example.com
    VirtualDocumentRoot /var/www/html/%0
    # insert logging config, anything else you need..
    <Directory /var/www/html/>
        Order Allow,Deny
        Allow from all
        # Get rid of this if you need to allow htaccess files:
        AllowOverride None
    </Directory>
    RewriteEngine On
    # We're going to insert some Rewrite configuration here in a minute.
</VirtualHost>

然后,我们将为您添加一个运行 SSL 的新 VirtualHost。

# Add this if you don't already have it:
Listen 443

<VirtualHost *:443>
    ServerName everything.example.com
    ServerAlias *.example.com
    VirtualDocumentRoot /var/www/html/%0

    SSLEngine On
    SSLCertificateFile /path/to/cert.pem
    SSLCertificateKeyFile /path/to/private.key

    # insert logging config, anything else you need..
    <Directory /var/www/html/>
        Order Allow,Deny
        Allow from all
        # Get rid of this if you need to allow htaccess files:
        AllowOverride None
    </Directory>
    # if you want to kick someone back to HTTP if they're using HTTPS,
    # do that with Rewrite configuration here.  For example:
    #RewriteRule ^/(non/sensitive/content.*\.html)$ http://%{HTTP_HOST}/$1 [R=301,L]
</VirtualHost>

因此,我们已将所有内容通过 HTTP 和 HTTPS 提供。现在,为了强制某些域使用 HTTPS,我们可以使用 mod_rewrite。

重要安全信息! 从安全角度来看,您需要非常小心。如果您只是将 HTTP 上的所有内容重定向到 HTTPS 等效协议,那么您可能会“隐藏”由于硬编码的资源位置而通过 HTTP 而不是 HTTPS 发送请求的情况 - 如果该请求中包含敏感数据,那么它只是通过互联网发送的,未加密。您需要权衡这种风险与您发现和纠正此类问题的能力、如果出现问题,错误页面对用户的不友好程度以及数据的敏感性。

要强制某些位置使用 SSL,您需要将 mod_rewrite 配置插入端口 80 虚拟主机(我已在上面的配置中进行了注释)。您可以构建几乎任何类型的行为,只要目录或域除外;我将提供一些示例:

# Exclude the domain "static.example.com"
RewriteCond %{HTTP_HOST} !^static\.example\.com$
# Exclude the directory /images
RewriteCond %{REQUEST_URI} !^/images/
# Exclude requests to .css files
RewriteCond %{REQUEST_URI} !\.css$
# This is the more secure but less user friendly version - block requests to the non-secured port.
RewriteRule ^ - [F,L]
# This is the user friendly version, where you need to be especially careful that
# your site never sends sensitive data to http accidentally:
#RewriteRule ^/(.*)$ https://%{HTTP_HOST}/$1 [R=301,L]

或者,如果您只想对到基目录的请求执行友好重定向,而对其他请求执行错误行为:

# Exclude the domain "static.example.com"
RewriteCond %{HTTP_HOST} !^static\.example\.com$
# ..insert other exclusion conditions here..
RewriteRule ^/$ https://%{HTTP_HOST}/ [R=301,L]

# Exclude the domain "static.example.com"
RewriteCond %{HTTP_HOST} !^static\.example\.com$
# ..insert other exclusion conditions here..
RewriteRule ^ - [F,L]

如果这些示例不符合您的需要,请告诉我。

相关内容