Hôte virtuel Apache basé sur * source * IP

9

Est-il possible de configurer Apache pour différents hôtes virtuels en fonction de l' IP source ? (c.-à-d. même interface, même nom d'hôte, mais deux hôtes virtuels différents, avec un contenu différent, basé sur l' IP source .)

La motivation est que mon adresse IP puisse accéder au site proprement dit, mais que tout le monde reçoive la page d'accueil. La solution conventionnelle semble être d'utiliser mod_rewrite pour diriger les visiteurs vers une page distincte dans le même docroot, mais j'aimerais utiliser un docroot complètement différent pour la page d'attente à la place.

ithinkihaveacat
la source
BTW, pourquoi avez-vous besoin de cette logique pour vous-même sur le serveur? Vous pouvez mapper le domaine à l'IP d'un serveur de test (ou de votre propre ordinateur) pour vous-même en utilisant votre fichier d'hôtes.
Dan Grossman
avez-vous plusieurs noms à gérer ou un seul? comme vous pouvez travailler (définir les Virtualhosts) avec des noms Ou avec IP.
regilero
une raison particulière pour laquelle une racine de doc différente?
anthonysomerset
La justification énoncée par le PO n'a pas de sens (une page d'attente fonctionne très bien avec une réécriture), mais si vous étiez, par exemple, en train de retravailler un site, vous aviez besoin d'un moyen d'héberger la reprise, et que vous ne saviez pas que des sous-domaines existaient, vous pourriez décidez de le faire de cette façon.
womble
Vous pouvez utiliser les lignes Autoriser / Refuser pour bloquer l'accès à tout le monde sauf vous et avoir un document d'erreur personnalisé pour les erreurs 403 (assurez-vous de le placer dans un répertoire et autorisez l'accès à ce répertoire, sinon le document d'erreur sera également 403), ou utilisez des règles de réécriture / conditions de réécriture, ou déplacez votre site de pré-lancement / test vers un sous-domaine comme dev.example.com puis example.com pourrait avoir la page de
garde

Réponses:

5

Je ne sais pas si c'est possible (sans mod_rewrite, de toute façon) au niveau Apache.

Voici une autre idée. Que faire si vous configurez deux hôtes virtuels Apache, puis utilisez iptables pour transférer de manière transparente le visiteur vers l'hôte virtuel correct? Quelque chose comme

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

Ou quelque chose de similaire. :)

Janne Pikkarainen
la source
Je dirais que ce sera l'option la moins mauvaise.
womble
8

Ce ne serait pas vraiment un hôte virtuel différent. Mais en utilisant quelque chose comme mod_rewrite ou mod_alias, vous pouvez diffuser du contenu à partir de n'importe quel dossier pour lequel vous avez défini les autorisations appropriées. Il n'y a qu'un seul docroot, mais vous pouvez le changer efficacement à la volée.

Une façon de le faire pourrait être:

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

Notez cependant qu'il serait probablement un peu plus propre de gérer cela avec un sous-domaine de développement.

Matthieu
la source
4

Apache 2.3 ou version ultérieure

Avec Apache 2.3 ou version ultérieure, vous pouvez apparemment faire quelque chose comme ça (testé):

<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 ou version antérieure

Mise à jour: ce n'est pas une bonne solution. Voir ci-dessous.

Vous devez faire un hack comme ça. Notez le [PT]qui signifie "passthrough". Sans cela, une redirection HTTP réelle est renvoyée au client, ce qui n'est probablement pas ce que vous voulez. La [OR]chose (qui signifie "ou") montre comment faire correspondre plusieurs adresses.

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]

Vous devez activer mod_rewritece que vous pouvez faire sur Debian / Ubuntu avec cette commande:

sudo a2enmod rewrite

Notez que cette méthode n'interdit pas complètement à d'autres personnes d'accéder à votre site de test, vous voudrez donc probablement ajouter un peu de sécurité, ou simplement choisir un préfixe plus obscur que next.

Mise à jour sur la méthode mod_rewrite.

Il y a quelques problèmes avec cette méthode. Tout d'abord, Django ne fonctionne pas avec deux sites dans le même processus comme celui-ci, vous devez suivre les instructions de cette réponse .

Deuxièmement, mod_rewrite ne fonctionne pas avec les POSTrequêtes ! Tous les POSTs sont modifiés en silence GETet les données de publication sont supprimées. Très frustrant! Par conséquent, je vous recommande d'utiliser le ...

version iptables

Exécutez simplement les serveurs sur deux ports différents. Celui-ci comprend les éléments WSGI pour avoir deux sites django distincts.

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

Ensuite, vous pouvez utiliser cette iptablescommande pour router les demandes de votre adresse IP sur le port 80 vers le port 1222:

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

Passez -Aà -Dpour supprimer la règle.

Notez que les documents suggèrent que vous devez ajouter des commandes supplémentaires Listenet NameVirtualHost, mais j'ai trouvé que cela fonctionne sans eux, et les ajouter l'a fait casser (au moins dans ubuntu).

Timmmm
la source
Votre réponse pour 2.3+ donne Alias cannot occur within <Directory/Location/Files> sectionune solution? J'ai vraiment besoin de ça: $
Gizmo
2

AFAIK, la seule façon de le faire est de créer un lien symbolique entre un emplacement dans la racine du document et votre contenu en dehors de la racine du document, puis de réécrire la demande.

Dan Grossman
la source
1

Comme @Timmmm l'a dit, mais en corrigeant l'instruction ipmatch (notez le '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...

Sinon, il affichera l'erreur:

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