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

9

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

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

ithinkihaveacat
источник
Кстати, зачем вам эта логика для себя на сервере? Вы можете сопоставить домен с IP-адресом тестового сервера (или вашего собственного компьютера), используя файл hosts.
Дэн Гроссман
У вас есть несколько имен для обработки или только одно? как вы можете работать (определить виртуальных хостов) с именами или с IP.
Regilero
какая-то конкретная причина, почему другой корень документа?
anthonysomerset
Заявленное обоснование OP не имеет смысла (удерживающая страница прекрасно работает с переписыванием), но если вы, скажем, переделываете сайт, вам нужен способ разместить переделку, и вы не знаете, что существуют субдомены, вы можете решите сделать это таким образом.
womble
Вы можете использовать строки Разрешить / Запретить, чтобы заблокировать доступ для всех, кроме вас, и иметь собственный документ об ошибках на 403 ошибки (Убедитесь, что вы поместили его в каталог и разрешите доступ к этому каталогу, в противном случае документ с ошибкой также будет 403), или используйте правила перезаписи / условия перезаписи или переместите свой сайт перед запуском / тестированием на поддомен, такой как dev.example.com, тогда example.com может иметь удерживающую страницу
Smudge

Ответы:

5

Я не знаю, возможно ли это (без 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

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

Янне Пиккарайнен
источник
Я бы сказал, что это будет наименее худший вариант.
womble
8

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

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

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

Мэтью
источник
4

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

Timmmm
источник
Ваш ответ для 2.3+ дает Alias cannot occur within <Directory/Location/Files> sectionкакие-либо исправления? Мне действительно нужно это: $
Gizmo
2

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

Дэн Гроссман
источник
1

Как сказал @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
olivervbk
источник