Host wirtualny Apache na podstawie * źródła * IP

9

Czy można skonfigurować Apache dla różnych hostów wirtualnych w oparciu o źródłowy adres IP? (tj. ten sam interfejs, ta sama nazwa hosta, ale dwa różne hosty wirtualne, o różnej zawartości, w oparciu o źródłowy adres IP).

Motywacja jest taka, że ​​mój adres IP może uzyskać dostęp do właściwej witryny, ale wszyscy inni otrzymują stronę wstrzymującą. Konwencjonalnym rozwiązaniem wydaje się być użycie mod_rewrite do przekierowania odwiedzających na osobną stronę w tym samym dokumencie docroot, ale zamiast tego chciałbym użyć zupełnie innego dokumentu docroot dla strony trzymającej.

ithinkihaveacat
źródło
BTW, dlaczego trzeba tę logikę dla siebie na serwerze? Możesz zmapować domenę na adres IP serwera testowego (lub własnego komputera) tylko dla siebie, korzystając z pliku hosts.
Dan Grossman
czy masz kilka nazw do obsłużenia, czy tylko jedno? jak możesz pracować (zdefiniuj Virtualhosts) z nazwami lub z IP.
regilero
jakiś konkretny powód, dla którego inny katalog główny dokumentu?
anthonysomerset
Podane uzasadnienie PO nie ma sensu (strona trzymająca świetnie działa z przepisywaniem), ale jeśli, powiedzmy, przerabiasz witrynę, potrzebujesz sposobu na hostowanie przeróbki i nie wiesz, że istnieją subdomeny, możesz zdecyduj się to zrobić w ten sposób.
womble
Możesz użyć linii Zezwalaj / Odmów, aby zablokować dostęp wszystkim oprócz ciebie i mieć niestandardowy dokument błędu 403 (upewnij się, że umieściłeś go w katalogu i zezwalasz na dostęp do tego katalogu, w przeciwnym razie dokument błędu również 403), lub użyj reguł przepisywania / warunków przepisywania lub przenieś witrynę przed uruchomieniem / testowania do subdomeny, takiej jak dev.example.com, a następnie example.com może mieć stronę wstrzymującą
Smudge

Odpowiedzi:

5

Nie wiem, czy to możliwe (w każdym razie bez mod_rewrite) na poziomie Apache.

Oto inny pomysł. Co się stanie, jeśli skonfigurujesz dwa wirtualne hosty Apache, a następnie użyjesz iptables, aby transparentnie przekierować gościa do poprawienia wirtualnego hosta? Coś jak

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

Lub coś podobnego. :)

Janne Pikkarainen
źródło
Powiedziałbym, że będzie to najgorsza opcja.
womble
8

To naprawdę nie byłby inny wirtualny host. Ale używając czegoś takiego jak mod_rewrite lub mod_alias możesz wyświetlać zawartość z dowolnego folderu, dla którego ustawiłeś odpowiednie uprawnienia. Jest tylko jeden docroot, ale możesz go skutecznie zmienić w locie.

Jednym ze sposobów na to może być:

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

Zauważ jednak, że prawdopodobnie byłoby to trochę czystsze, aby poradzić sobie z tym z subdomeną deweloperów.

Mateusz
źródło
4

Apache 2.3 lub nowszy

Z Apache 2.3 lub nowszym możesz najwyraźniej zrobić coś takiego (przetestowane):

<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 lub wcześniejszy

Aktualizacja: To nie jest dobre rozwiązanie. Patrz poniżej.

Musisz zrobić taki hack. Zwróć uwagę na [PT]skrót „passsthrough”. Bez tego rzeczywiste przekierowanie HTTP jest wysyłane z powrotem do klienta, co prawdopodobnie nie jest tym, czego chcesz. [OR]Rzeczą (co oznacza „lub”) pokazuje, jak dopasować wiele adresów.

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]

Musisz włączyć to, mod_rewriteco możesz zrobić na Debian / Ubuntu za pomocą tego polecenia:

sudo a2enmod rewrite

Pamiętaj, że ta metoda nie całkowicie blokuje dostęp do Twojej witryny testowej innym osobom, więc prawdopodobnie będziesz chciał dodać pewne zabezpieczenia lub po prostu wybrać bardziej niejasny przedrostek niż next.

Zaktualizuj metodę mod_rewrite.

Istnieje kilka problemów z tą metodą. Po pierwsze, Django nie działa z dwiema stronami w tym samym procesie jak ten, musisz postępować zgodnie z instrukcjami w tej odpowiedzi .

Po drugie mod_rewrite nie działa z POSTżądaniami ! Wszystkie POSTs są dyskretnie zmieniane na, GETa dane wpisu są odrzucane. Bardzo frustrujące! Dlatego polecam użyć ...

wersja iptables

Po prostu uruchom serwery na dwóch różnych portach. Ten zawiera WSGI, aby mieć dwie osobne strony 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 [email protected]

    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 [email protected]

    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>

Następnie możesz użyć tego iptablespolecenia, aby skierować żądania z adresu IP na porcie 80 do portu 1222:

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

Zmień, -Aaby -Dusunąć regułę.

Zauważ, że dokumenty sugerują, że musisz dodać dodatkowe polecenia Listeni NameVirtualHostpolecenia, ale faktycznie odkryłem, że działa bez nich, a dodanie ich spowodowało, że się zepsuł (przynajmniej w Ubuntu).

Timmmm
źródło
Twoja odpowiedź na 2.3+ daje Alias cannot occur within <Directory/Location/Files> sectionjakieś poprawki? Naprawdę potrzebuję tego: $
Gizmo
2

AFAIK, jedynym sposobem na zrobienie tego jest dowiązanie symboliczne lokalizacji w katalogu głównym dokumentu do treści poza katalogiem głównym dokumentu, a następnie przepisanie żądania do tego.

Dan Grossman
źródło
1

Jak powiedział @ Timmmm, ale poprawienie instrukcji ipmatch (zwróć uwagę na „10 .10.10.10”): nazwa_serwera 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...

Ponieważ w przeciwnym razie wyświetli się błąd:

Cannot parse condition clause: -ipmatch requires subnet/netmask as constant argument
olivervbk
źródło