Назад | Перейти на главную страницу

Виртуальный хост Apache на основе * исходного * IP

Можно ли настроить Apache для разных виртуальных хостов на основе источник IP? (т.е. один и тот же интерфейс, одно и то же имя хоста, но два разных виртуальных хоста с разным содержимым на основе источник IP.)

Мотивация для этого заключается в том, чтобы мой IP-адрес мог получить доступ к собственно сайту, но чтобы все остальные получили страницу хранения. Обычным решением, похоже, является использование mod_rewrite для направления посетителей на отдельную страницу в том же корневом каталоге, но вместо этого я хотел бы использовать совершенно другой корневой каталог для страницы хранения.

На самом деле это не был бы другой виртуальный хост. Но используя что-то вроде mod_rewrite или mod_alias вы можете обслуживать контент из любой папки, для которой вы установили соответствующие разрешения. Есть только один docroot, но вы можете изменить его на лету.

Один из способов сделать это:

<VirtualHost *.80>
    ServerName example.com
    ...
    DocumentRoot "/path/to/root"
    <Directory "/path/to/root">
       ...
    </Directory>
    <Directory "/path/to/not/root">
       Order allow,deny
       #replace with your IP
       Allow from 192.168.0.100 
       ...
    </Directory>
    RewriteEngine On
    #Rewrite to alternate path if IP address matches
    RewriteCond %{REMOTE_ADDR} ^192\.168\.0\.100$
    RewriteRule ^/(.*)$ /path/to/not/root/$1
<VirtualHost>

Обратите внимание, что, вероятно, было бы немного чище справиться с этим с помощью поддомена dev.

Я не знаю, возможно ли это (по крайней мере, без mod_rewrite) на уровне Apache.

Вот еще одна идея. Что если вы настроите два виртуальных хоста Apache, а затем используете iptables для прозрачного перенаправления посетителей на правильный виртуальный хост? Что-то вроде

iptables -A PREROUTING -t nat -i eth0 -p tcp -s your.ip.address -d your.server --dport 80 -j DNAT --to-destination your.actual.site:someport
iptables -A PREROUTING -t nat -i eth0 -p tcp ! -s your.ip.address -d your.server --dport 80 -j DNAT --to-destination your.holding.site:someport

Или что-то подобное. :)

Apache 2.3 или новее

С Apache 2.3 или новее вы, по-видимому, можете сделать что-то вроде этого (проверено):

<VirtualHost *:80>
    ServerName www.example.com

    <If "-R '10.10.10.10'">
        # The next version of the website...
        Alias /favicon.ico /home/ubuntu/website-new/favicon.ico
        Alias /static/ /home/ubuntu/static/
        WSGIScriptAlias / /home/ubuntu/website-new/main/wsgi.py
    </If>
    <Else>
        # The standard version (e.g. holding page).
        Alias /favicon.ico /home/ubuntu/website/favicon.ico
        Alias /static/ /home/ubuntu/static/
        WSGIScriptAlias / /home/ubuntu/website/main/wsgi.py
    </Else>

    # and so on...

</VirtualHost>

Apache 2.2 или более ранней версии

Обновление: это не лучшее решение. Увидеть ниже.

Вы должны сделать такой хакер. Обратите внимание [PT] что означает «сквозной». Без этого фактическое перенаправление HTTP отправляется обратно клиенту, что, вероятно, не то, что вам нужно. В [OR] вещь (обозначающая «или») показывает, как сопоставить несколько адресов.

Alias /next/favicon.ico /home/ubuntu/website-new/favicon.ico
Alias /next/static/ /home/ubuntu/static/
WSGIScriptAlias /next /home/ubuntu/website-new/main/wsgi.py

Alias /favicon.ico /home/ubuntu/website/favicon.ico
Alias /static/ /home/ubuntu/static/
WSGIScriptAlias / /home/ubuntu/website/main/wsgi.py

# Rewrite for our IP.
RewriteEngine On
RewriteCond %{REMOTE_ADDR} ^80\.4\.170\.209$ [OR]
RewriteCond %{REMOTE_ADDR} ^94\.193\.52\.157$
RewriteRule ^/(.*) /next/$1 [PT]

Вам нужно включить mod_rewrite что вы можете сделать в Debian / Ubuntu с помощью этой команды:

sudo a2enmod rewrite

Обратите внимание, что этот метод не запрещает полностью другим людям доступ к вашему тестовому сайту, поэтому вы, вероятно, захотите добавить немного безопасности или просто выбрать более неясный префикс, чем next.

Обновление метода mod_rewrite.

У этого метода есть пара проблем. Во-первых, Django не работает с двумя сайтами в одном процессе, как этот, вам нужно следовать инструкциям в этот ответ.

Во-вторых mod_rewrite не работает с POST Запросы! Все POSTs молча меняются на GET и данные сообщения удаляются. Очень неприятно! Поэтому я рекомендую вам использовать ...

версия iptables

Просто запустите серверы на двух разных портах. Этот включает в себя материал WSGI, чтобы иметь два отдельных сайта django.

<VirtualHost *:80>
    ServerName www.example.com

    Alias /favicon.ico /home/ubuntu/alpha/favicon.ico
    Alias /static/ /home/ubuntu/alpha/static/

    WSGIDaemonProcess alpha_wsgi user=www-data group=www-data
    WSGIScriptAlias / /home/ubuntu/alpha/alpha/wsgi.py
    WSGIProcessGroup alpha_wsgi

    ServerAdmin info@example.com

    ErrorLog ${APACHE_LOG_DIR}/error.log

    # Possible values include: debug, info, notice, warn, error, crit, alert, emerg.
    LogLevel warn

    CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
<VirtualHost *:1222>
    ServerName www.example.com

    Alias /favicon.ico /home/ubuntu/main/favicon.ico
    Alias /static/ /home/ubuntu/main/static/

    WSGIDaemonProcess main_wsgi user=www-data group=www-data
    WSGIScriptAlias / /home/ubuntu/main/main/wsgi.py
    WSGIProcessGroup main_wsgi

    ServerAdmin info@example.com

    ErrorLog ${APACHE_LOG_DIR}/error.log

    # Possible values include: debug, info, notice, warn, error, crit, alert, emerg.
    LogLevel warn

    CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

Тогда вы можете использовать это iptables команда для маршрутизации запросов с вашего IP-адреса на порт 80 на порт 1222:

sudo iptables -A PREROUTING -t nat -p tcp -s your.ip.address --dport 80 -j DNAT --to-destination :1222

+ Изменить -A к -D чтобы удалить правило.

Обратите внимание, что в документации предлагается добавить дополнительные Listen и NameVirtualHost команд, но я действительно обнаружил, что он работает без них, и их добавление заставило его сломаться (по крайней мере, в ubuntu).

AFAIK, единственный способ сделать это - символически связать местоположение в корне документа с вашим контентом за пределами корня документа, а затем переписать запрос на это.

Как сказал @Timmmm, но исправляя оператор ipmatch (обратите внимание на '10 .10.10.10 '): ServerName www.example.com

<If "%{REMOTE_ADDR} -ipmatch '10.10.10.10'">
    # The next version of the website...
    Alias /favicon.ico /home/ubuntu/website-new/favicon.ico
    Alias /static/ /home/ubuntu/static/
    WSGIScriptAlias / /home/ubuntu/website-new/main/wsgi.py
</If>
<Else>
    # The standard version (e.g. holding page).
    Alias /favicon.ico /home/ubuntu/website/favicon.ico
    Alias /static/ /home/ubuntu/static/
    WSGIScriptAlias / /home/ubuntu/website/main/wsgi.py
</Else>

# and so on...

Потому что иначе он покажет ошибку:

Cannot parse condition clause: -ipmatch requires subnet/netmask as constant argument