Modelo de configuração do Apache: ServerConfig, VirtualHost e contexto de diretivas

Capítulo 3

Tempo estimado de leitura: 9 minutos

+ Exercício

Como o Apache interpreta a configuração (visão mental do “modelo”)

O Apache processa a configuração como um conjunto de diretivas aplicadas em contextos. Cada diretiva só é válida em certos contextos (por exemplo, algumas só funcionam no contexto global, outras dentro de <VirtualHost>, outras dentro de <Directory> etc.). O comportamento final de uma requisição é o resultado da combinação (e, às vezes, do conflito) entre diretivas aplicadas em camadas.

Uma forma prática de pensar é separar em dois grandes blocos:

  • ServerConfig (global): diretivas fora de qualquer bloco. Afetam o servidor como um todo (ou definem padrões).
  • VirtualHost: diretivas dentro de <VirtualHost>. Afetam apenas aquele host virtual (um site).

Além disso, existem contextos que refinam o comportamento para partes do sistema de arquivos ou da URL:

  • <Directory>: baseado em caminho no sistema de arquivos (ex.: /var/www/site/public).
  • <Files> e <FilesMatch>: baseado no nome do arquivo (ex.: .env, *.php).
  • <Location> e <LocationMatch>: baseado na URL (ex.: /admin), independente de onde isso está no disco.

Ordem de leitura vs. ordem de aplicação

O Apache a configuração na ordem em que os arquivos são incluídos (via Include/IncludeOptional), mas a aplicação das diretivas ocorre conforme o contexto e o tipo de diretiva. Por isso, “estar mais embaixo no arquivo” nem sempre significa “ganhar”. O que manda é: contexto + regras de mesclagem/precedência da diretiva.

Contextos e quando usar cada um

1) ServerConfig (global)

Use para padrões do servidor, módulos, logs globais, e valores que devem valer para todos os sites (a menos que sejam sobrescritos onde permitido).

Continue em nosso aplicativo e ...
  • Ouça o áudio com a tela desligada
  • Ganhe Certificado após a conclusão
  • + de 5000 cursos para você explorar!
ou continue lendo abaixo...
Download App

Baixar o aplicativo

# Contexto global (ServerConfig) — exemplo conceitual, não copie sem adaptar Paths/ports

2) VirtualHost

Use para separar sites. Dentro dele você define ServerName, DocumentRoot, logs do site, e regras específicas daquele domínio.

<VirtualHost *:80>  # contexto VirtualHost (site A)  </VirtualHost> <VirtualHost *:80>  # contexto VirtualHost (site B)  </VirtualHost>

3) Directory (sistema de arquivos)

Use para controlar permissões e opções por diretório real no disco. É o contexto mais comum para Require, Options e AllowOverride.

<Directory "/var/www/site/public">  Require all granted </Directory>

4) Files / FilesMatch (nome do arquivo)

Use para proteger arquivos específicos (por nome ou regex), mesmo que estejam dentro de diretórios liberados.

<Files ".env">  Require all denied </Files>

5) Location / LocationMatch (URL)

Use quando a regra deve seguir a URL, e não o caminho no disco (ex.: endpoints de aplicação, rotas “virtuais”, proxies). Importante: <Location> pode afetar conteúdo que nem existe como arquivo, então use com cuidado.

<Location "/admin">  Require ip 192.0.2.10 </Location>

Como o Apache decide “qual VirtualHost atende”

Quando chega uma requisição, o Apache escolhe o <VirtualHost> com base em:

  • IP:porta que recebeu a conexão (ex.: *:80, 192.0.2.20:80).
  • Host header (ex.: Host: exemplo.com) comparado com ServerName/ServerAlias.

Se não houver correspondência, ele usa o primeiro VirtualHost definido para aquele IP:porta como “default” (comportamento comum em name-based vhosts).

Exemplo progressivo: dois sites na mesma porta

# Arquivo incluído pelo Apache (ordem importa para o “default”) <VirtualHost *:80>  ServerName site-a.local  DocumentRoot "/var/www/site-a/public"  ErrorLog "/var/log/apache2/site-a-error.log"  CustomLog "/var/log/apache2/site-a-access.log" combined </VirtualHost> <VirtualHost *:80>  ServerName site-b.local  DocumentRoot "/var/www/site-b/public"  ErrorLog "/var/log/apache2/site-b-error.log"  CustomLog "/var/log/apache2/site-b-access.log" combined </VirtualHost>

Se uma requisição chegar com Host: site-b.local, o segundo bloco atende. Se chegar com um host desconhecido (ou sem Host em HTTP/1.0), o primeiro tende a ser usado como padrão.

Mesclagem e conflitos: como o resultado final é composto

Nem toda diretiva “sobrescreve” outra do mesmo jeito. Existem diretivas que:

  • Substituem (a última definição aplicável vence).
  • Acumulam (várias entradas se somam, como múltiplos Header add ou múltiplos Alias).
  • Mesclam por regra própria (ex.: controle de acesso com Require pode combinar condições dependendo de como você estrutura os blocos e módulos).

Mesmo sem decorar todas as regras, dá para depurar seguindo um método: (1) identifique o VirtualHost escolhido, (2) identifique o caminho real do arquivo (filesystem) e a URL, (3) liste quais blocos <Directory>, <Files> e <Location> podem se aplicar, (4) verifique se alguma diretiva é “acumulativa” ou “substitutiva”.

Exemplo 1: conflito de DocumentRoot (substituição por contexto)

DocumentRoot é típico de VirtualHost. Um DocumentRoot global pode existir como padrão, mas o do VirtualHost é o que vale para aquele site.

# Global (ServerConfig) DocumentRoot "/var/www/default" <VirtualHost *:80>  ServerName app.local  DocumentRoot "/var/www/app/public" </VirtualHost>

Para Host: app.local, o conteúdo vem de /var/www/app/public, não do global.

Exemplo 2: Directory mais específico tende a refinar o menos específico

É comum ter um bloco amplo e outro mais específico. O mais específico (caminho mais profundo) normalmente refina o comportamento para aquele subdiretório.

<VirtualHost *:80>  ServerName exemplo.local  DocumentRoot "/var/www/exemplo/public"  <Directory "/var/www/exemplo">   Require all denied  </Directory>  <Directory "/var/www/exemplo/public">   Require all granted  </Directory> </VirtualHost>

Resultado esperado: o diretório public fica acessível, enquanto o restante de /var/www/exemplo permanece negado (útil para evitar exposição de diretórios fora do DocumentRoot).

Exemplo 3: Files pode “fechar” um arquivo dentro de um diretório liberado

<VirtualHost *:80>  ServerName exemplo.local  DocumentRoot "/var/www/exemplo/public"  <Directory "/var/www/exemplo/public">   Require all granted  </Directory>  <Files ".env">   Require all denied  </Files> </VirtualHost>

Resultado esperado: o site funciona, mas uma tentativa de acessar /.env deve ser negada (se o arquivo estiver sob o escopo atendido).

Exemplo 4: Location atua pela URL (e pode divergir do Directory)

Compare: <Directory> olha para o caminho no disco; <Location> olha para a URL. Se sua aplicação mapeia /admin para um front controller (ex.: index.php), o arquivo real pode ser sempre o mesmo, mas a URL muda.

<VirtualHost *:80>  ServerName exemplo.local  DocumentRoot "/var/www/exemplo/public"  <Directory "/var/www/exemplo/public">   Require all granted  </Directory>  <Location "/admin">   Require ip 192.0.2.10  </Location> </VirtualHost>

Resultado esperado: qualquer URL começa liberada, mas /admin exige IP permitido, mesmo que o arquivo servido seja o mesmo do restante do site.

Passo a passo prático: depurar “por que esta URL está/ não está acessível?”

Passo 1 — Descobrir qual VirtualHost está atendendo

Verifique a combinação de IP:porta e o Host da requisição. Em seguida, localize o bloco <VirtualHost ...> com ServerName/ServerAlias correspondente. Se não houver, o primeiro VirtualHost daquele IP:porta tende a ser o default.

Passo 2 — Mapear URL para caminho (quando aplicável)

Para conteúdo estático, a URL geralmente mapeia para DocumentRoot + caminho. Para aplicações, pode haver reescritas internas, mas ainda assim você consegue identificar o diretório base e quais blocos <Directory> podem atingir o caminho físico final.

Passo 3 — Listar blocos que podem se aplicar

  • Directory: quais blocos cobrem o caminho? (ex.: /var/www/exemplo e /var/www/exemplo/public).
  • Files: existe algum bloco para o nome do arquivo requisitado?
  • Location: a URL bate em algum <Location>?

Passo 4 — Procurar diretivas “decisivas”

Para acesso, procure principalmente por Require (e blocos onde ele aparece). Para comportamento de diretório, procure Options e AllowOverride. Para logs, procure ErrorLog/CustomLog no VirtualHost.

Atividade: “prever o resultado” antes de testar

Leia cada configuração e responda: (1) qual VirtualHost atende Host: ..., (2) a URL será permitida ou negada, (3) qual regra foi determinante. Só depois compare com o comportamento real no seu ambiente.

Cenário A

<VirtualHost *:80>  ServerName loja.local  DocumentRoot "/var/www/loja/public"  <Directory "/var/www/loja">   Require all denied  </Directory>  <Directory "/var/www/loja/public">   Require all granted  </Directory> </VirtualHost>
  • Preveja: acessar http://loja.local/ é permitido ou negado?
  • Preveja: acessar um arquivo em /var/www/loja/segredo.txt (fora do public) via URL seria possível?

Cenário B

<VirtualHost *:80>  ServerName intranet.local  DocumentRoot "/var/www/intra/public"  <Directory "/var/www/intra/public">   Require all granted  </Directory>  <Location "/admin">   Require all denied  </Location> </VirtualHost>
  • Preveja: http://intranet.local/ funciona?
  • Preveja: http://intranet.local/admin retorna qual tipo de resultado (permitido/negado)?

Cenário C

<VirtualHost *:80>  ServerName app.local  DocumentRoot "/var/www/app/public"  <Directory "/var/www/app/public">   Require all granted  </Directory>  <FilesMatch "\.(bak|old)$">   Require all denied  </FilesMatch> </VirtualHost>
  • Preveja: /index.html é permitido?
  • Preveja: /config.php.bak é permitido?

Cenário D (VirtualHost default)

<VirtualHost *:80>  ServerName primeiro.local  DocumentRoot "/var/www/primeiro" </VirtualHost> <VirtualHost *:80>  ServerName segundo.local  DocumentRoot "/var/www/segundo" </VirtualHost>
  • Preveja: se chegar uma requisição com Host: desconhecido.local, qual DocumentRoot tende a ser usado?

Exemplos curtos de “armadilhas” comuns de contexto

1) Tentar controlar URL com Directory

<Directory> não casa com URL, casa com caminho no disco. Se você escrever <Directory "/admin">, isso não protege http://site/admin (a menos que exista um diretório real /admin no filesystem e ele seja o caminho atendido).

2) Proteger por Location e esquecer que a aplicação reescreve tudo

Se sua aplicação reescreve rotas (ex.: tudo cai em index.php), proteger apenas um arquivo específico com <Files> pode não surtir efeito para uma rota. Nesses casos, <Location> costuma ser mais adequado para rotas.

3) Conflitos por múltiplos Includes

Se o mesmo VirtualHost ou diretiva aparece em mais de um arquivo incluído, você pode ter comportamento inesperado. Uma técnica de depuração é procurar definições duplicadas e garantir que cada site tenha um único bloco <VirtualHost> bem definido.

Tabela rápida: qual contexto escolher?

ObjetivoContexto recomendadoBase de correspondência
Configurar um site/domínio<VirtualHost>Host/IP:porta
Permitir/negar acesso a uma pasta real<Directory>Filesystem
Bloquear arquivos sensíveis por nome/extensão<Files>/<FilesMatch>Nome do arquivo
Restringir uma rota/endpoint<Location>/<LocationMatch>URL
Definir padrões globaisServerConfigServidor inteiro

Agora responda o exercício sobre o conteúdo:

Ao tentar restringir o acesso a uma rota como /admin, qual contexto é o mais adequado no Apache, considerando que a regra deve seguir a URL e não o caminho no disco?

Você acertou! Parabéns, agora siga para a próxima página

Você errou! Tente novamente.

<Location>/<LocationMatch> avaliam a URL, não o filesystem. Isso permite restringir rotas como /admin mesmo quando a aplicação reescreve URLs ou serve tudo por um único arquivo.

Próximo capitúlo

Diretivas essenciais do Apache para iniciantes: ServerName, DocumentRoot, DirectoryIndex e Options

Arrow Right Icon
Capa do Ebook gratuito Apache para Iniciantes: Configuração Essencial, Virtual Hosts e Segurança Básica
19%

Apache para Iniciantes: Configuração Essencial, Virtual Hosts e Segurança Básica

Novo curso

16 páginas

Baixe o app para ganhar Certificação grátis e ouvir os cursos em background, mesmo com a tela desligada.