Apache2 VirtualHost IfPort?

Apache2 VirtualHost IfPort?

我想创建一个这样的虚拟主机:

<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结构并操作请求。请参阅Ifs的核心文档可用表达式列表。你可以这样做:

<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两个。Listenapache2.conf

编辑

我没有意识到这个解决方案实际上会引发错误,但让我们回到概念本身......实际上,在 80 或 443 上监听没有问题。如果不是因为......加密,Apache2 很乐意为此提供一个优雅的解决方案。Apache2 是用 C 开发的,除了线程和分叉之外,它还使用套接字。在 C 中,使用 SSL 需要初始化 OpenSSL 组件,并围绕基本套接字进行一些工作以实现整个 SSL。您正在寻找一个简单的解决方案,但背后的整个机制却很棘手......这就是为什么您无法在基本虚拟主机中启用 SSL:HTTP 和 HTTPs 是不同的组件,在 Apache2 方式中,恐怕第一个和第二个之间没有继承的概念。

相关内容