Host virtual Apache baseado em * source * IP

9

É possível configurar o Apache para diferentes hosts virtuais com base no IP de origem ? (ou seja, mesma interface, mesmo nome de host, mas dois hosts virtuais diferentes, com conteúdo diferente, com base no IP de origem .)

A motivação para isso é que meu endereço IP possa acessar o site corretamente, mas que todos os outros obtenham a página de espera. A solução convencional parece usar o mod_rewrite para direcionar os visitantes para uma página separada dentro da mesma docroot, mas eu gostaria de usar uma docroot completamente diferente para a página de espera.

ithinkihaveacat
fonte
BTW, por que você precisa dessa lógica para si mesmo no servidor? Você pode mapear o domínio para o IP de um servidor de teste (ou do seu próprio computador) usando apenas o arquivo hosts.
Dan Grossman
você tem vários nomes para manipular ou apenas um? como você pode trabalhar (defina os Virtualhosts) com nomes ou com IP.
regilero 2/08
alguma razão específica para uma raiz de documento diferente?
Anthonysomerset
A lógica declarada do OP não faz sentido (uma página de retenção funciona muito bem com uma reescrita), mas se você estivesse, digamos, reformulando um site, precisava de uma maneira de hospedar a reformulação e não sabia que existiam subdomínios, talvez decida fazer dessa maneira.
womble
Você pode usar linhas Permitir / Negar para bloquear o acesso a todos, exceto você, e ter um documento de erro personalizado para erros 403 (certifique-se de colocá-lo em um diretório e permitir acesso a esse diretório, caso contrário, o documento de erro 403 também será) ou usar regras de reescrita / reescrever condições, ou mover o pré-lançamento / site testando para um subdomínio como dev.example.com então example.com poderia ter a página de retenção
Smudge

Respostas:

5

Não sei se isso é possível (sem mod_rewrite, enfim) no nível do Apache.

Aqui está outra ideia. E se você configurar dois hosts virtuais Apache e depois usar o iptables para encaminhar de forma transparente o visitante para corrigir o host virtual? Algo como

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 algo parecido. :)

Janne Pikkarainen
fonte
Eu diria que essa será a pior opção.
womble
8

Realmente não seria um host virtual diferente. Mas, usando algo como mod_rewrite ou mod_alias, você pode exibir conteúdo de qualquer pasta para a qual você definiu as permissões apropriadas. Há apenas um docroot, mas você pode efetivamente mudar isso rapidamente.

Uma maneira de fazer isso pode ser:

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

Observe, porém, que provavelmente seria um pouco mais limpo lidar com isso com um subdomínio dev.

Mateus
fonte
4

Apache 2.3 ou posterior

Com o Apache 2.3 ou posterior, você aparentemente pode fazer algo assim (testado):

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

Atualização: Esta não é uma boa solução. Ver abaixo.

Você tem que fazer um hack como este. Observe o [PT]que significa "passagem". Sem ele, um redirecionamento HTTP real é enviado de volta ao cliente, o que provavelmente não é o que você deseja. A [OR]coisa (que significa "ou") mostra como combinar vários endereços.

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]

Você precisa habilitar o mod_rewriteque pode fazer no Debian / Ubuntu com este comando:

sudo a2enmod rewrite

Observe que esse método não impede completamente que outras pessoas acessem seu site de teste; portanto, você provavelmente desejará adicionar alguma segurança ou apenas escolher um prefixo mais obscuro do que next.

Atualização no método mod_rewrite.

Existem alguns problemas com esse método. Primeiro, o Django não funciona com dois sites no mesmo processo como este, você precisa seguir as instruções nesta resposta .

Em segundo lugar, mod_rewrite não funciona com POSTsolicitações ! Todos os POSTs são alterados silenciosamente para GETe os dados da postagem são descartados. Muito frustrante! Portanto, eu recomendo que você use o ...

versão do iptables

Simplesmente execute os servidores em duas portas diferentes. Este inclui o material WSGI para ter dois sites django separados.

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

Então você pode usar este iptablescomando para rotear solicitações do seu endereço IP na porta 80 para a porta 1222:

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

Mude -Apara -Dpara remover a regra.

Observe que os documentos sugerem que você precisa adicionar comandos Listene adicionais NameVirtualHost, mas na verdade descobri que funciona sem eles, e a adição deles fez com que parasse (pelo menos no ubuntu).

Timmmm
fonte
Sua resposta para 2.3+ dá Alias cannot occur within <Directory/Location/Files> sectionalguma correção? Eu realmente preciso disso: $
Gizmo
2

AFAIK, a única maneira de fazer isso é vincular um local dentro da raiz do documento ao seu conteúdo fora da raiz do documento e, em seguida, reescrever a solicitação.

Dan Grossman
fonte
1

Como o @Timmmm disse, mas corrigindo a instrução ipmatch (observe '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...

Porque, caso contrário, ele mostrará o erro:

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