我想创建一个这样的虚拟主机:
<VirtualHost *:80 *:443>
<IfPort 443>
SSLEngine On
...
</IfPort>
...
</VirtualHost>
因此,如果主机已通过端口 443 访问,我想添加一些附加功能。我可以通过某种方式实现这一点吗?还是必须将其分成 2 个虚拟主机?
答案1
我使用mod_macro
在托管大量不同域的服务器上解决此问题...安装模块(每个操作系统/发行版不同),然后配置如下内容:
LoadModule macro_module libexec/apache22/mod_macro.so
<Macro VHost $host>
<VirtualHost *:80>
DocumentRoot /usr/local/www/$host/data
ServerName $host
ServerAlias *.$host
ScriptAlias /cgi-bin/ "/usr/local/www/$host/cgi-bin/"
IncludeOptional etc/apache22/vhosts/$host
</VirtualHost>
</Macro>
<Macro VHostSSL $host>
<VirtualHost *:80>
DocumentRoot /usr/local/www/$host/data
ServerName $host
ServerAlias *.$host
ScriptAlias /cgi-bin/ "/usr/local/www/$host/cgi-bin/"
IncludeOptional etc/apache22/vhosts/$host
</VirtualHost>
<VirtualHost *:443>
DocumentRoot /usr/local/www/$host/data
ServerName $host
ServerAlias *.$host
SSLEngine on
SSLCertificateFile /usr/local/www/$host/ssl/$host.crt
SSLCertificateKeyFile /usr/local/www/$host/ssl/$host.key
ScriptAlias /cgi-bin/ "/usr/local/www/$host/cgi-bin/"
IncludeOptional etc/apache22/vhosts/$host
</VirtualHost>
</Macro>
Use VHostSSL example.com
Use VHost example.net
添加新域非常容易;任何特定于域的配置都会被放入包含文件中。
答案2
使用约翰的解决方案我得到了这个
Apache 2 is starting ...
AH00526: Syntax error on line 53 of .../httpd-vhosts.conf:
SSLEngine not allowed here
正如约翰所说,最好的方法是拥有 2 个虚拟主机;但是我的虚拟主机代码超过 150 行(很多反向代理),因为我不想有 2 个代码(和一个很长的配置文件)我最终这样做了,它有效:
1.为非ssl虚拟主机创建虚拟主机。
2.创建另一个虚拟主机并反向代理到第一个虚拟主机
<VirtualHost *:443>
SSLEngine on
SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL
SSLCertificateFile "...cert.crt"
SSLCertificateKeyFile "...server.ssl.key"
... (any ssl specific config)
ProxyPreserveHost On
ProxyPass / http://localhost:80/
ProxyPassReverse http://localhost:80/ http://yourdomain.com/
</VirtualHost>
这根本不是一个好的或性能友好的解决方案,但是如果不希望有 2 个虚拟主机的原因是为了防止所有虚拟主机配置都有 2 个版本(这意味着每次想要更改某些内容时都要更改 2 行),那么这是可行的。
答案3
避免重复的另一种选择是将虚拟主机配置保存在特定文件中,然后使用包含文件将其拉入:
/etc/path/to/config/example.com.conf
:
ServerName example.com.conf
DocumentRoot /var/www/something
# Any other config you want to apply to both vhosts
您的虚拟主机文件:
<VirtualHost *:443>
SSLEngine on
# Other SSL directives
Include /etc/path/to/config/example.com.conf
</VirtualHost>
<VirtualHost *:80>
Include /etc/path/to/config/example.com.conf
</VirtualHost>
答案4
查看 ApacheIf
结构并操作请求。请参阅If
s的核心文档和可用表达式列表。你可以这样做:
<If "%{SERVER_PORT} == '443'">
# Do stuff
</If>
关于您的VirtualHost
标签,我在 Apache2 文档中没有看到这样的解决方案。请参阅http://httpd.apache.org/docs/2.2/en/vhosts/examples.html#port并尝试您的选择:Apache2 对不同的 IP 使用类似的方法,而不是不同的端口(http://httpd.apache.org/docs/2.2/en/vhosts/examples.html#intraextra)。
我还是建议使用 2 个不同的虚拟主机,这样更清楚。无论如何,您的文件中都需要NameVirtualHost
两个。Listen
apache2.conf
编辑
我没有意识到这个解决方案实际上会引发错误,但让我们回到概念本身......实际上,在 80 或 443 上监听没有问题。如果不是因为......加密,Apache2 很乐意为此提供一个优雅的解决方案。Apache2 是用 C 开发的,除了线程和分叉之外,它还使用套接字。在 C 中,使用 SSL 需要初始化 OpenSSL 组件,并围绕基本套接字进行一些工作以实现整个 SSL。您正在寻找一个简单的解决方案,但背后的整个机制却很棘手......这就是为什么您无法在基本虚拟主机中启用 SSL:HTTP 和 HTTPs 是不同的组件,在 Apache2 方式中,恐怕第一个和第二个之间没有继承的概念。