Apache2 VirtualHost IfPort?

我想做一个这样的虚拟主机

<VirtualHost *:80 *:443> <IfPort 443> SSLEngine On ... </IfPort> ... </VirtualHost> 

所以,如果主机已经通过端口443访问,我想添加一些额外的function。 我可以做到这一点,或者我必须将其分成2个虚拟主机?

我使用mod_macro来解决这个问题,在一个服务器上承载大量不同的域…安装模块(不同的操作系统/发行版),然后configuration这样的事情:

 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 

超级容易添加一个新的域名; 任何特定于域的configuration都会被包含在包含文件中。

避免重复的另一个select是将虚拟主机的configuration保存在一个特定的文件中,并使用include:

/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> 

使用约翰的解决scheme,我得到这个

 Apache 2 is starting ... AH00526: Syntax error on line 53 of .../httpd-vhosts.conf: SSLEngine not allowed here 

正如约翰所说,最好的办法是有2个虚拟主机,但我的虚拟主机代码超过150行(大量的反向代理),因为我不想每个代码(和一个非常长的configuration文件)我结束了这个工作:

1.为非SSL虚拟主机创build一个虚拟主机。

2.创build另一个虚拟主机,并向第一个虚拟主机反向代理

 <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> 

这不是一个好的或性能友好的解决scheme,但如果不想要2个虚拟主机背后的原因是为了防止有2个所有虚拟主机configuration(这意味着每次你想改变一些东西改变2行)这个作品。

看看Apache的If结构,并操纵请求。 查看If的核心文档以及可用的expression式列表 。 你可以做这样的事情:

 <If "%{SERVER_PORT} == '443'"> # Do stuff </If> 

关于你的VirtualHost标签,我没有在Apache2文档中看到这样的解决scheme。 请参阅http://httpd.apache.org/docs/2.2/en/vhosts/examples.html#port并尝试您的select:Apache2对不同的IP使用类似的IP而不是不同的端口&#xFF08; http://httpd.apache。 org / docs / 2.2 / en / vhosts / examples.html#intraextra )。

我仍然build议使用2个不同的虚拟主机,更清晰。 无论如何,您需要在您的apache2.conf文件中使用两个NameVirtualHostListen

编辑

我没有意识到这个解决scheme实际上抛出了一个错误,但是让我们回到这个概念本身…实际上听80或443没有问题。 Apache2很乐意提供一个优雅的解决scheme,如果它不是…encryption。 Apache2是用C语言开发的,除了线程和分支之外,它使用套接字。 在C中,使用SSL需要对OpenSSL组件进行初始化,并且一些解决基本套接字来实现整个SSL的事情。 你正在寻找一个简单的解决scheme,但后面的整个机制是棘手的…这就是为什么你不能在一个基本的虚拟主机启用SSL:HTTP和HTTPs是不同的组件,以Apache2的方式,恐怕有第一和第二之间没有inheritance的概念。