O termo Virtual Host(ou host virtual) refere-se à prática de executar mais de um site, como empresa1.exemplo.com e empresa2.exemplo.com, em uma única máquina(servidor web). Os hosts virtuais podem ser “baseados em IP”, o que significa que você tem um endereço IP diferente para cada site, ou “baseado em nome”, o que significa que você tem vários nomes em execução em cada endereço IP. O fato de estarem sendo executados no mesmo servidor físico não é aparente para o usuário final.
Segundo o site apache:
O Apache foi um dos primeiros servidores a oferecer suporte a hosts virtuais baseados em IP. As versões 1.1 e posteriores do Apache suportam hosts virtuais(vhosts) baseados em IP e baseados em nome. A última variante de hosts virtuais às vezes também é chamada host-based ou non-IP virtual hosts.
apache.org
Antes de iniciarmos é bom atentarmos à relação entre o virtual host e dns:
A criação de configurações de host virtual em seu servidor Apache não faz com que entradas DNS sejam criadas magicamente para esses nomes de host. Você deve ter os nomes no DNS, resolvendo seu endereço IP, ou ninguém poderá acessar seu site. Você pode colocar entradas em seu “arquivo de hosts” para teste local, mas isso funcionará apenas na máquina com essas entradas de hosts.
Os arquivos de hosts que a citação acima fala são:
- no Windows: C:\Windows\System32\Drivers\etc\hosts
- no Linux: /etc/hosts
Se não ter um programa de DNS para criar entradas, podemos usar em nossos testes esses arquivos para falar que quando digitarmos o endereço “meusite.com” seja acessodo, por exemplo, o ip 192.168.1.54.
Exemplos de VirtualHost
Os cenários abaixo são baseados no site apache.org e envolvem vários sites da Web em execução em um único servidor, por meio de hosts virtuais baseados em nome ou em IP.
Executando vários sites baseados em nomes em um único endereço IP
Seu servidor tem vários nomes de host que resolvem para um único endereço e você deseja responder de forma diferente para www.example.com e www.example.org.
# Ensure that Apache listens on port 80 Listen 80 <VirtualHost *:80> DocumentRoot "/www/example1" ServerName www.example.com # Other directives here </VirtualHost> <VirtualHost *:80> DocumentRoot "/www/example2" ServerName www.example.org # Other directives here </VirtualHost>
Os asteriscos(em *:80) correspondem a todos os endereços, portanto, o servidor principal não atende a solicitações. Devido ao fato de que o host virtual com ServerName www.example.com é o primeiro no arquivo de configuração, ele tem a prioridade mais alta e pode ser visto como o servidor padrão ou principal. Isso significa que, se for recebida uma solicitação que não corresponda a uma das diretivas ServerName especificadas, ela será atendida por este primeiro <VirtualHost>.
A configuração acima é o que você deseja usar em quase todas as situações de hospedagem virtual baseada em nome. A única coisa para a qual essa configuração não funcionará, na verdade, é quando você estiver servindo conteúdo diferente com base em diferentes endereços IP ou portas.
Hosts baseados em nome em mais de um endereço IP
Você pode substituir * por um endereço IP específico no sistema. Esses hosts virtuais serão usados apenas para solicitações HTTP recebidas na conexão com o endereço IP especificado.
No entanto, também é útil usar * em sistemas em que o endereço IP não é previsível – por exemplo, se você tiver um endereço IP dinâmico com seu ISP e estiver usando alguma variedade de solução de DNS dinâmico. Como * corresponde a qualquer endereço IP, essa configuração funcionaria sem alterações sempre que seu endereço IP mudasse.
No exemplo a seguir, o servidor tem dois endereços IP. Em um(172.20.30.40), serviremos o servidor “principal”, server.example.com e no outro(172.20.30.50), serviremos dois ou mais hosts virtuais.
Listen 80 # This is the "main" server running on 172.20.30.40 ServerName server.example.com DocumentRoot "/www/mainserver" <VirtualHost 172.20.30.50> DocumentRoot "/www/example1" ServerName www.example.com # Other directives here ... </VirtualHost> <VirtualHost 172.20.30.50> DocumentRoot "/www/example2" ServerName www.example.org # Other directives here ... </VirtualHost>
Qualquer solicitação para um endereço diferente de 172.20.30.50 será atendida pelo servidor principal. Uma solicitação para 172.20.30.50 com um nome de host desconhecido ou sem cabeçalho Host: será atendida em www.example.com.
Servindo o mesmo conteúdo em diferentes endereços IP (como um endereço interno e externo)
Supondo um caso onde a máquina do servidor possui dois endereços IP: 192.168.1.1 e 172.20.30.40. A máquina está entre uma rede interna(intranet) e uma rede externa(internet). Fora da rede, o nome server.example.com resolve para o endereço externo (172.20.30.40), mas dentro da rede, esse mesmo nome resolve para o endereço interno (192.168.1.1).
O servidor pode ser configurado para responder a requisições internas e externas com o mesmo conteúdo, com apenas uma seção <VirtualHost>.
<VirtualHost 192.168.1.1 172.20.30.40> DocumentRoot "/www/server1" ServerName server.example.com ServerAlias server </VirtualHost>
Agora as solicitações de ambas as redes serão atendidas pelo mesmo <VirtualHost>.
Na rede interna, pode-se usar apenas o servidor de nomes em vez do nome de host totalmente qualificado server.example.com. Observe também que, no exemplo acima, você pode substituir a lista de endereços IP por *, o que fará com que o servidor responda da mesma forma em todos os endereços.
Executando sites diferentes em portas diferentes
Você tem vários domínios indo para o mesmo IP e também deseja atender a várias portas. O exemplo abaixo ilustra que a correspondência de nomes ocorre após a determinação da melhor combinação de porta e endereço IP correspondente.
Listen 80 Listen 8080 <VirtualHost 172.20.30.40:80> ServerName www.example.com DocumentRoot "/www/domain-80" </VirtualHost> <VirtualHost 172.20.30.40:8080> ServerName www.example.com DocumentRoot "/www/domain-8080" </VirtualHost> <VirtualHost 172.20.30.40:80> ServerName www.example.org DocumentRoot "/www/otherdomain-80" </VirtualHost> <VirtualHost 172.20.30.40:8080> ServerName www.example.org DocumentRoot "/www/otherdomain-8080" </VirtualHost>
virtual baseado em IP
Outra situação: o servidor tem dois endereços IP (172.20.30.40 e 172.20.30.50) que determinam os nomes www.example.com e www.example.org, respectivamente.
Listen 80 <VirtualHost 172.20.30.40> DocumentRoot "/www/example1" ServerName www.example.com </VirtualHost> <VirtualHost 172.20.30.50> DocumentRoot "/www/example2" ServerName www.example.org </VirtualHost>
Solicitações de qualquer endereço não especificado em uma das diretivas <VirtualHost> (como localhost, por exemplo) irão para o servidor principal, se houver.
Hosts virtuais baseados em porta e IP mistos
A máquina do servidor tem dois endereços IP (172.20.30.40 e 172.20.30.50) que determinam os nomes www.example.com e www.example.org, respectivamente. Em cada caso, queremos executar hosts nas portas 80 e 8080.
Listen 172.20.30.40:80 Listen 172.20.30.40:8080 Listen 172.20.30.50:80 Listen 172.20.30.50:8080 <VirtualHost 172.20.30.40:80> DocumentRoot "/www/example1-80" ServerName www.example.com </VirtualHost> <VirtualHost 172.20.30.40:8080> DocumentRoot "/www/example1-8080" ServerName www.example.com </VirtualHost> <VirtualHost 172.20.30.50:80> DocumentRoot "/www/example2-80" ServerName www.example.org </VirtualHost> <VirtualHost 172.20.30.50:8080> DocumentRoot "/www/example2-8080" ServerName www.example.org </VirtualHost>
Vhosts mistos baseados em nome e baseados em IP
Qualquer endereço mencionado no argumento para um host virtual que nunca aparece em outro host virtual é um host virtual estritamente baseado em IP.
Listen 80 <VirtualHost 172.20.30.40> DocumentRoot "/www/example1" ServerName www.example.com </VirtualHost> <VirtualHost 172.20.30.40> DocumentRoot "/www/example2" ServerName www.example.org </VirtualHost> <VirtualHost 172.20.30.40> DocumentRoot "/www/example3" ServerName www.example.net </VirtualHost> # IP-based <VirtualHost 172.20.30.50> DocumentRoot "/www/example4" ServerName www.example.edu </VirtualHost> <VirtualHost 172.20.30.60> DocumentRoot "/www/example5" ServerName www.example.gov </VirtualHost>
Usando Virtual_host e mod_proxy juntos
O exemplo a seguir permite que uma máquina front-end faça proxy de um host virtual para um servidor em execução em outra máquina. No exemplo, um host virtual com o mesmo nome é configurado em uma máquina em 192.168.111.2. A diretiva ProxyPreserveHost On é usada para que o nome do host desejado seja passado, caso estejamos fazendo proxy de vários nomes de host para uma única máquina.
<VirtualHost *:*> ProxyPreserveHost On ProxyPass "/" "http://192.168.111.2/" ProxyPassReverse "/" "http://192.168.111.2/" ServerName hostname.example.com </VirtualHost>
Usando default vhosts
_default_ vhosts para todas as portas
Capturar todas as solicitações para qualquer endereço IP e porta não especificados, ou seja, uma combinação de endereço/porta que não é usada para nenhum outro host virtual.
<VirtualHost _default_:*> DocumentRoot "/www/default" </VirtualHost>
O uso desse vhost padrão com uma porta curinga evita efetivamente que qualquer solicitação vá para o servidor principal.
Um vhost padrão nunca atende a uma solicitação enviada para um endereço/porta usado para vhosts baseados em nome. Se a solicitação contiver um desconhecido ou nenhum Host: header, ele sempre será servido do vhost baseado em nome primário (o vhost para esse endereço/porta aparecendo primeiro no arquivo de configuração).
Você pode usar AliasMatch ou RewriteRule para reescrever qualquer solicitação para uma única página de informações(ou script).
_default_ vhosts para diferentes portas
Igual à configuração 1, mas o servidor escuta em várias portas e queremos usar um segundo vhost _default_ para a porta 80.
<VirtualHost _default_:80> DocumentRoot "/www/default80" # ... </VirtualHost> <VirtualHost _default_:*> DocumentRoot "/www/default" # ... </VirtualHost>
O vhost padrão para a porta 80, que deve aparecer antes de qualquer vhost padrão com uma porta curinga, captura todas as solicitações enviadas para um endereço IP não especificado. O servidor principal nunca é usado para atender a uma solicitação.
_default_ vhosts para uma porta
Queremos ter um vhost padrão para a porta 80, mas nenhum outro vhost padrão.
<VirtualHost _default_:80> DocumentRoot "/www/default" ... </VirtualHost>
Uma solicitação para um endereço não especificado na porta 80 é atendida pelo vhost padrão. Qualquer outra solicitação para um endereço e porta não especificados é atendida pelo servidor principal.
Qualquer uso de * em uma declaração de host virtual terá precedência maior que _default_.
Migrando um vhost baseado em nome para um vhost baseado em IP
O vhost baseado em nome com o nome de host www.example.org (do nosso exemplo baseado em nome, configuração 2) deve obter seu próprio endereço IP. Para evitar problemas com servidores de nome ou proxies que armazenaram em cache o endereço IP antigo para o vhost baseado em nome, queremos fornecer ambas as variantes durante uma fase de migração.
A solução é fácil, porque podemos simplesmente adicionar o novo endereço IP (172.20.30.50) à diretiva VirtualHost.
Listen 80 ServerName www.example.com DocumentRoot "/www/example1" <VirtualHost 172.20.30.40 172.20.30.50> DocumentRoot "/www/example2" ServerName www.example.org # ... </VirtualHost> <VirtualHost 172.20.30.40> DocumentRoot "/www/example3" ServerName www.example.net ServerAlias *.example.net # ... </VirtualHost>
O vhost agora pode ser acessado por meio do novo endereço (como um vhost baseado em IP) e por meio do endereço antigo (como um vhost baseado em nome).
Usando a diretiva ServerPath
Temos um servidor com dois vhosts baseados em nome. Para corresponder ao host virtual correto, um cliente deve enviar o host correto: cabeçalho. Antigos clientes HTTP/1.0 não enviam tal cabeçalho e o Apache não tem ideia de qual vhost o cliente tentou alcançar (e atende a solicitação do vhost primário). Para fornecer o máximo possível de compatibilidade com versões anteriores, criamos um vhost primário que retorna uma única página contendo links com um prefixo de URL para os hosts virtuais baseados em nome.
<VirtualHost 172.20.30.40> # primary vhost DocumentRoot "/www/subdomain" RewriteEngine On RewriteRule "." "/www/subdomain/index.html" # ... </VirtualHost> <VirtualHost 172.20.30.40> DocumentRoot "/www/subdomain/sub1" ServerName www.sub1.domain.tld ServerPath "/sub1/" RewriteEngine On RewriteRule "^(/sub1/.*)" "/www/subdomain$1" # ... </VirtualHost> <VirtualHost 172.20.30.40> DocumentRoot "/www/subdomain/sub2" ServerName www.sub2.domain.tld ServerPath "/sub2/" RewriteEngine On RewriteRule "^(/sub2/.*)" "/www/subdomain$1" # ... </VirtualHost>
Devido à diretiva ServerPath, uma solicitação para a URL http://www.sub1.domain.tld/sub1/ é sempre atendida pelo sub1-vhost.
Uma solicitação para a URL http://www.sub1.domain.tld/ só é atendida a partir do sub1-vhost se o cliente enviar um host correto: cabeçalho. Se nenhum cabeçalho Host: for enviado, o cliente obtém a página de informações do host principal.
Observe que há uma estranheza: uma solicitação para http://www.sub2.domain.tld/sub1/ também é atendida a partir do sub1-vhost se o cliente não enviou nenhum cabeçalho Host:.
As diretivas RewriteRule são usadas para garantir que um cliente que enviou um host correto: o cabeçalho possa usar ambas as variantes de URL, ou seja, com ou sem prefixo de URL.
Comments on “Apache: Exemplos de Configuração de Virtual Host”