![如何使用 mod_vhost_alias 配置 apache2/httpd 大规模虚拟主机的 SSL](https://linux22.com/image/584624/%E5%A6%82%E4%BD%95%E4%BD%BF%E7%94%A8%20mod_vhost_alias%20%E9%85%8D%E7%BD%AE%20apache2%2Fhttpd%20%E5%A4%A7%E8%A7%84%E6%A8%A1%E8%99%9A%E6%8B%9F%E4%B8%BB%E6%9C%BA%E7%9A%84%20SSL.png)
我已经搜索了很多次但找不到任何答案。
我正在使用 httpd 2.2.15 和 Centos 6.2。
我已经将 apache 配置为大规模虚拟主机。例如:
UseCanonicalName off
VirtualDocumentRoot /var/www/html/%0
我将拥有相同的“主”域和指向虚拟主机的不同子域。我已创建自签名证书用于测试,通用名称为 *.mydomain.com。整个服务器只有一个 IP。
我该如何配置 apache 以便为我的 vhosts 使用 ssl?
如果可能的话,除了上述内容之外,我还想实现这一点:
我可以定义一个目录,或者最好是一些文件(例如登录页面),将其排除在 SSL 之外吗?所有 vhost 基本上都是同一应用程序的不同实例(除了我在下面 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]
如果这些示例不符合您的需要,请告诉我。