Entendendo os Hosts Virtuais no Apache

Publicado: 20/10/2013 em Linux, Programação, Serviços IP
Tags:

1. Introdução
Um servidor Web pode dar suporte a vários sites.  Cada um destes sistes é identificado com uma diretiva de container <VirtualHost>.  No Apache existem dois tipos diferentes de host virtual suportados:
a) host virtual baseado em nome    (name-based) – onde mais um host virtual roda no mesmo endereço IP, mas com nomes diferentes;
b) host virtual baseado em IP (IP-based)     –  cada host virtual possui o seu próprio endereço IP.

Em ambos os casos, os endereços IP compartilhados pelos diversos hosts virtuais do Apache precisam ser declarados com uma diretiva NameVirtualHost.

Hosts virtuais name-based é geralmente mais simples, já que você só precisa configurar o servidor DNS para mapear cada nome de host para o endereço IP correto e, em seguida, configurar o Apache HTTP Server para reconhecer os diferentes nomes de host.

2. Diretivas Apache
Uma diretiva é apenas permitida dentro de um contexto designado. Se o usuário tentar usá-la em qualquer outro contexto , será emitida uma mensagem de erro de configuração que evitará o servidor de tratar as requisições naquele contexto , ou até mesmo evitará o servidor de iniciar.  Ou seja, as diretrizes de configuração só adquirem validade dependendo do contexto em que são aplicadas:

a) server config: este contexto são encontrados nos arquivos de configuração do servidor (por exemplo, em /etc/apache2/apache2.conf).  Para ter validade, as diretivas NÃO podem ser utilizadas dentro de qualquer container <VirtualHost> ou <Directory>. Também não pode ser utilizada dentro de arquivos .htaccess. São diretivas que controlam o funcionamento dos processos do servidor Apache como um todo, afetando a operação global do Apache, como o número de solicitações simultâneas que ele pode manipular ou onde ele pode encontrar seus arquivos de configuração. Exemplos destes tipos de diretivas: ServerRoot, LockFile, PidFile, KeepAlive, StartServers, StartServers, etc.

b) virtual host:  este contexto significa que a diretiva pode aparecer dentro de containers <VirtualHost> nos arquivos de configuração do servidor. São diretivas que afetam a configuração de apenas parte do servidor, e que não estão associdas ao escopo de um host virtual em particular.

c) directory: uma diretiva marcada como sendo válida neste contexto deve ser utilizada dentro dos containers <Directory>, <Location>, <Files>, e <Proxy> nos arquivos de configuração do servidor, sujeita as restrições descritas nas Seções de Configuração.

d).htaccess:  se uma diretiva é válida neste contexto, ela significa que pode aparecer dentro de arquivos .htaccess per-directory. Ela pode não ser processada, dependendo das substituições ativas no momento.

A localização válida para a diretiva são resultado de um OR booleano de todos os contextos listados. Em outras palavras, uma diretiva que está marcada para ser válida em “server config” e “.htaccess” pode ser utilizada no arquivo apache2.config e nos arquivos .htaccess, porém não dentro dos containers <Directory> ou <VirtualHost>.

É importante entender que o arquivo de configuração do Apache é lido de cima para baixo.  Arquivos que usam “include” são considerados como aparecendo inteiramente na localidade onde aparece a diretiva Include. Assim, se existir uam mesma diretiva aparecendo duas vezes, mas com valores diferentes, a que vir por último será a que realmente terá efeito. Deve ser considerado também os arquivos .htaccess, os quais são capazes de substituir as configurações do arquivo de configuração principal do servidor Apache. Uma outra situação, é entender como funcionam as diretivas com relação aos subdiretórios.  Por exemplo:

<Directory /www/site1>
    Options ExecCGI
</Directory>
<Directory /www/site1/html>
    Options Includes
</Directory>

No exemplo acima, os arquivos acessados a partir do diretório /www/site1/html/misc/ terão “Options Includes” ativada, mas não “Options ExecCGI”, porque a seção com a especificação mais específica é que se aplica.

2.1 Algumas diretivas especiais
a) NameVirtualHost
Manual: http://httpd.apache.org/docs/2.2/mod/core.html#namevirtualhost
Descrição: designa um endereço IP para name-virtual hosting
Syntaxe:    NameVirtualHost addr[:port]
Contexto:    server config

b) <VirtualHost>
Manual: http://httpd.apache.org/docs/2.2/mod/core.html#virtualhost
Descrição:    contém diretivas que se aplica apenas para um hostname específico ou endereço IP
Syntaxe:    <VirtualHost addr[:port] [addr[:port]] …> … </VirtualHost>
Contexto:    server config


3. Configurar hosts virtuais baseados em nome

Para usar name-based virtual hosting, você deve designar o endereço IP (e possivelmente a porta) no servidor que estará aceitando pedidos para os hosts. Isso é configurado usando a diretiva NameVirtualHost. No caso normal onde deve ser usado todas e quaisquer endereços IP no servidor, você pode usar * como o argumento para NameVirtualHost. Se você estiver planejando usar múltiplas portas (por exemplo, executando SSL), você deve adicionar uma porta para o argumento, como *:80. Note-se que mencionar um endereço IP em uma diretiva NameVirtualHost não faz automaticamente o servidor ouvir o endereço IP. Além disso, qualquer endereço IP especificado aqui deve ser relacionado com uma interface de rede no servidor.

O próximo passo é criar um bloco <VirtualHost> para cada host que você gostaria de servir. O argumento para a diretiva <VirtualHost> deve coincidir com a definida pela diretiva NameVirtualHost. (Neste caso, é habitual usar “*:80” ). Dentro de cada bloco <VirtualHost> , você vai precisar no mínimo de uma directiva ServerName para designar qual é o host servido e uma diretiva DocumentRoot para mostrar onde no sistema de arquivos o conteúdo para aquele host reside.

a) Exemplo de hosts virtuais baseados em nome

ServerName    127.0.0.1
NameVirtualHost    *:80
<VirtualHost    *:80>
    ServerName    sitio1.com.br
    DocumentRoot    /var/www/sitio1
</VirtualHost>
<VirtualHost    *:80>
    ServerName    sitio2.com.br
    DocumentRoot    /var/www/sitio2
</VirtualHost>

Algumas explicações para o exemplo acima:
i)  NameVirtualHost    *:80        – os hosts especificados rodam em todos os endereços, acessados via porta 80
ii) ServerName    127.0.0.1    – os hosts todam também no endereço de loopback (localhost).  Ou seja, se o usuário estiver na própria máquina que está servindo de servidor físico poderá visualizar os sítios.

OBS:
i)  o argumento para a diretiva <VirtualHost> necessita ser idêntico àquele presente na diretiva NameVirtualHost.
ii) atenção: as requisições para as quais não houver um host virtual listado irão para o primeiro vhost listado no arquivo de configuração.  No caso do exemplo acima, as requisições que chegarem ao servidor usando nomes de hosts que não estejam mencionados explicitamente em um dos hosts virtuais serão atendidas pelo host virtual sitio1.com.br
iii) é possível associar vários nomes a um determinado host virtual através da diretiva ServerAlias:

ServerName    sitio2.com.br
ServerAlias    www.sitio2.com.br sitio2.info www.sitio2.info

b) Designando um host visual baseado em nome como padrão
É recomendável que seja direcionado a um host padrão todas aquelas requisições não atendidas independentemente delas especificarem um nome ou usarem um endereço IP.  Esse host padrão poderia mostrar uma página de erro, por exemplo, com uma mensagem de erro “host não encontrado”.

Para isto, adicionar a seguinte seção <VirtualHost> antes de qualquer outro (esta ordem é fundamental!!!):

<VirtualHost    *:80>
    ServerName    default
    DocumentRoot    /var/www/htdocs
    ServerDocument    404    /site_list.html
</VirtualHost>


4. Configurar hosts virtuais baseados em endereço IP

Uma situação comum neste tipo de configuração é ter diversos endereços IP e desejar um site em cada endereço.  Veja o exemplo a seguir:

a) Exemplo de hosts virtuais baseados em IP

ServerName    127.0.0.1
<VirtualHost    10.0.0.1>
    ServerName    sitio3.com
    DocumentRoot    /var/www/sites/sitio3
</VirtualHost>
<VirtualHost    10.0.0.2>
    ServerName    sitio4.com
    DocumentRoot    /var/www/sites/sitio4
</VirtualHost>

Algumas explicações para o exemplo acima:
Os hosts virtuais definidos acima capturam todas as requisições destinadas aos endereços IP especificados, independentemente de qual nome de host esteja sendo usado para se chegar lá.  Requisições destinadas a qualquer outro endereço IP não listado vão para o virtual host incluído no corpo principal do arquivo de configuração (servidor “padrão”).  O ServerName especificado é usado como o nome primário do host virtual, quando necessário, mas não é usado no processo de mapear uma requisição ao host correto.  Apenas o endereço IP (e não o campo Host do cabeçalho) é consultado para se descobrir qual virtual host deve atender à requisição.


5. Misturando hosts virtuais baseados em endereço e baseados em nome

Uma situação que pode acontecer é a existência de vários endereços IP atribuídos ao sistema e se deseja ter mais de um sitio em cada endereço.  Veja o exemplo abaixo:

ServerName    127.0.0.1
NameVirtualHost    10.0.0.1:80
NameVirtualHost    10.0.0.2:80

<VirtualHost    10.0.0.1:80>
    ServerName    sitio5.com
    DocumentRoot    /var/www/sites/sitio5
</VirtualHost>
<VirtualHost    10.0.0.1:80>
    ServerName    sitio6.com
    DocumentRoot    /var/www/sites/sitio6
</VirtualHost>
<VirtualHost    10.0.0.2:80>
    ServerName    sitio7.com
    DocumentRoot    /var/www/sites/sitio7
</VirtualHost>
<VirtualHost    10.0.0.2:80>
    ServerName    sitio8.com
    DocumentRoot    /var/www/sites/sitio8
</VirtualHost>

Algumas explicações para o exemplo acima:
Usar o endereço do servidor em vez do argumento coringa *, faz com que os hosts virtuais atendam somente ao endereço IP especificado.  No entanto, como pode ser observado, o argumento para <VirtualHost> ainda precisará bater com o argumento para o NameVirtualHost com o qual o host virtual está vinculado.

6. Exibindo o mesmo conteúdo em vários endereços
Deseja-se ter o mesmo conteúdo exibido em dois dos seus endereços.  Uma situação que ocorre quando uma máquina possui dois endereços: um referente a rede interna de uma organização e outro para a rede internet. Veja o exemplo abaixo:

NameVirtualHost    192.168.1.10:80
NameVirtualHost    172.20.30.40:80

<VirtualHost    192.168.1.10:80 172.20.30.40:80>
    ServerName    sitio9.com
    DocumentRoot    /var/www/sites/sitio9
    ServerAlias    www.sitio9.com
</VirtualHost>

7. Verificando o entendimento do servidor Apache da configuração dos hosts virtuais
É instrutivo executar o comando apachectl e observar a configuração dos hosts virtuais da forma como o Apache analisou os arquivos de configuração. Um exame cuidadoso dos endereços IP e nomes de servidor pode ajudar a descobrir erros de configuração. O comando abaixo exemplifica o uso deste comando:

# apachectl -S
VirtualHost configuration:
wildcard NameVirtualHosts and _default_ servers:
_default_:8081         server1.meusitio.com.br (/etc/apache2/sites-enabled/000-apps.vhost:10)
*:9000                 is a NameVirtualHost
           default server server1.meusitio.com.br (/etc/apache2/sites-enabled/000-ispconfig.vhost:10)
           port 9000 namevhost server1.meusitio.com.br (/etc/apache2/sites-enabled/000-ispconfig.vhost:10)
*:80                   is a NameVirtualHost
           default server server1.meusitio.com.br (/etc/apache2/sites-enabled/000-default:1)
           port 80 namevhost server1.meusitio.com.br (/etc/apache2/sites-enabled/000-default:1)
           port 80 namevhost enota.meusitio.com (/etc/apache2/sites-enabled/100-enota.meusitio.com.vhost:7)
           port 80 namevhost iss.meusitio.com (/etc/apache2/sites-enabled/100-iss.maeusitio.com.vhost:7)
           port 80 namevhost meusitio.com.br (/etc/apache2/sites-enabled/100-meusitio.com.br.vhost:7)
           port 80 namevhost educar.meusitio.com (/etc/apache2/sites-enabled/900-educar.meusitio.com.vhost:7)
           port 80 namevhost meusitio.com (/etc/apache2/sites-enabled/900-meusitio.com.vhost:7)
Syntax OK

Referências:
1- Apache Virtual Host documentation
2- Configurar domínios virtuais do Apache em máquina Linux/Debian

Anúncios
comentários
  1. Daniel disse:

    Gostaria de saber se existe manipulação para alterar o virtualhost do plano de hospedagem que eu contratei, existe manipulações no apache, mas não sei como alterar o virtualhost pois não contratei vps

  2. Carlos disse:

    Gostaria de saber, se posso configurar 2 apaches usando um mesmo documentroot localizado em um diretório da rede?

Deixe um comentário, pois isto é muito motivante para continuarmos este trabalho

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s