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

Другой вариант избежать дублирования — сохранить конфигурацию виртуального хоста в отдельном файле и подключить ее с помощью 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>

решение4

Посмотрите на Ifструктуру Apache и измените запрос. Смотретьосновная документация для 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и Listenв вашем apache2.confфайле.

Редактировать

Я не осознавал, что это решение на самом деле выдает ошибку, но давайте вернемся к самой концепции... Прослушивание 80 или 443 на самом деле не проблема. Apache2 с радостью предоставил бы элегантное решение для этого, если бы не... шифрование. Apache2 был разработан на языке C, и помимо потоков и ветвей, он использует сокеты. В C использование SSL требует инициализации компонентов OpenSSL и некоторой работы вокруг базового сокета для реализации всего SSL. Вы ищете простое решение, но весь механизм за ним сложен... Вот почему вы не можете включить SSL в базовом виртуальном хосте: HTTP и HTTPs — это разные компоненты, и в Apache2, боюсь, нет концепции наследования между первым и вторым.

Связанный контент