Como o Apache acessa o sistema de arquivos
Quando o Apache atende uma requisição (por exemplo, GET /index.html), ele precisa ler arquivos e atravessar diretórios no sistema de arquivos até chegar ao conteúdo final. Para isso, o processo que serve as requisições roda com um usuário e grupo específicos (o “usuário do serviço”). Esse usuário/grupo determina o que o Apache consegue ou não acessar.
Usuário e grupo do processo
Em distribuições Linux, é comum o Apache rodar como:
- Debian/Ubuntu: usuário/grupo
www-data - RHEL/CentOS/Fedora: usuário
apachee grupoapache(ouwww, dependendo do sistema)
O processo principal geralmente inicia como root para abrir portas privilegiadas (como 80/443) e depois cria processos/threads de trabalho que rodam com o usuário do serviço. Na prática, quem precisa ter permissão de leitura/execução nos arquivos do site é o usuário/grupo efetivo dos processos de trabalho.
Como descobrir com qual usuário o Apache está rodando
Use um destes métodos (dependendo do seu sistema):
- Ver diretivas User/Group (se aplicável):
grep -R "^User\|^Group" /etc/apache2/ /etc/httpd/ 2>/dev/null - Ver processos em execução:
ps -eo user,group,pid,cmd | egrep "(apache2|httpd)" - Ver o usuário do serviço via systemd (quando definido no unit):
systemctl cat apache2 2>/dev/null | sed -n '1,120p'systemctl cat httpd 2>/dev/null | sed -n '1,120p'
Permissões necessárias para servir arquivos
Para o Apache servir um arquivo, ele precisa de permissões em toda a cadeia de diretórios até o arquivo e no próprio arquivo.
- Ouça o áudio com a tela desligada
- Ganhe Certificado após a conclusão
- + de 5000 cursos para você explorar!
Baixar o aplicativo
Regra prática: diretórios precisam de “x”, arquivos precisam de “r”
- Diretórios: o Apache precisa de permissão de execução (
x) para atravessar o diretório (acessar itens dentro dele). Semx, mesmo que existar, o acesso falha. - Arquivos: o Apache precisa de permissão de leitura (
r) para enviar o conteúdo ao cliente.
Exemplo: para servir /var/www/site/public/index.html, o usuário do Apache precisa de x em /var, /var/www, /var/www/site, /var/www/site/public e de r no arquivo index.html.
Entendendo o “x” em diretórios (o ponto que mais causa 403)
Em diretórios, x significa “pode entrar e acessar itens se souber o nome”. Já r significa “pode listar o conteúdo”. Para servir arquivos, normalmente não é necessário listar diretórios, então é comum usar --x (sem r) para o Apache atravessar, mas não listar.
Permissões recomendadas (padrão seguro)
- Diretórios:
755(dono: rwx, grupo: r-x, outros: r-x) ou mais restrito conforme o caso - Arquivos:
644(dono: rw-, grupo: r--, outros: r--)
Evite 777 em diretórios e 666/777 em arquivos: isso dá escrita a qualquer usuário do sistema e aumenta muito o risco de comprometimento.
Erros comuns: 403 vs 404 (e como diferenciar)
403 Forbidden por permissão
Ocorre quando o Apache encontra o caminho, mas não tem permissão para atravessar algum diretório ou ler o arquivo. Causas típicas:
- Falta de
xem algum diretório do caminho (muito comum em/home/usuariocom700) - Arquivo sem
rpara o usuário/grupo do Apache - Diretório do DocumentRoot sem permissões adequadas
Exemplo típico: site em /home/alice/site/public e /home/alice está com 700. O Apache não consegue atravessar /home/alice e retorna 403.
404 Not Found por caminho incorreto
Ocorre quando o Apache não encontra o arquivo no caminho mapeado. Causas típicas:
- O arquivo realmente não existe
- DocumentRoot aponta para o diretório errado
- Diferença de maiúsculas/minúsculas no nome do arquivo (Linux é case-sensitive)
- Deploy incompleto (arquivo não foi copiado)
Um 404 pode enganar quando você “tem certeza” que o arquivo existe, mas ele está em outro diretório do que o Apache está usando como raiz.
Diagnóstico prático: logs e comandos
1) Verifique os logs do Apache
Os logs costumam indicar se foi “permission denied” (403) ou “file does not exist” (404). Use:
# Debian/Ubuntu (comum): acesso e erro em /var/log/apache2/ ou via journalctl tail -n 200 /var/log/apache2/error.log# RHEL/CentOS/Fedora (comum): /var/log/httpd/ tail -n 200 /var/log/httpd/error_log# Em sistemas com systemd/journald: journalctl -u apache2 -n 200 --no-pagerjournalctl -u httpd -n 200 --no-pagerMensagens típicas:
(13)Permission deniedouAH00035: access to ... denied→ forte indício de permissãoFile does not exist→ forte indício de caminho/arquivo inexistente
2) Inspecione permissões com ls -l
Verifique dono/grupo e permissões do arquivo e diretórios:
ls -ld /var/www /var/www/site /var/www/site/publicls -l /var/www/site/public/index.htmlO que observar:
- O usuário do Apache (ex.:
www-data) precisa conseguir atravessar os diretórios (terxvia “outros” ou via grupo) - O arquivo precisa ser legível (ter
rvia “outros” ou via grupo)
3) Ache exatamente onde falta permissão com namei -l
namei -l mostra cada componente do caminho com permissões e donos, facilitando achar o “elo fraco”:
namei -l /var/www/site/public/index.htmlExemplo de leitura: se algum diretório no meio aparecer sem x para o usuário/grupo aplicável, o Apache não atravessa e você terá 403.
4) Valide se o arquivo existe no caminho esperado
Para investigar 404, confirme o caminho real e o nome exato:
test -f /var/www/site/public/index.html && echo OK || echo NAO_EXISTEfind /var/www/site -maxdepth 3 -name "index.html" -printPasso a passo: corrigindo um 403 por permissão (cenário comum)
Cenário: DocumentRoot em /var/www/site/public, mas o Apache retorna 403 ao acessar /.
Passo 1: descubra o usuário do Apache
ps -eo user,group,cmd | egrep "(apache2|httpd)"Suponha que seja www-data.
Passo 2: verifique a cadeia de diretórios e o arquivo
namei -l /var/www/site/public/index.htmlProcure por diretórios sem x para “group/other” quando o Apache não é o dono.
Passo 3: aplique permissões mínimas (sem exagerar)
Uma base segura e comum para conteúdo estático:
# Diretórios: 755, Arquivos: 644 (ajuste conforme necessidade de grupo) find /var/www/site/public -type d -exec chmod 755 {} \; find /var/www/site/public -type f -exec chmod 644 {} \;Se você quer restringir mais e usar grupo para acesso (recomendado quando há equipe/deploy), use grupo dedicado e “outros” sem acesso:
# Exemplo: grupo 'web' e Apache no grupo 'web' (ajuste nomes conforme seu sistema) chgrp -R web /var/www/site/public chmod -R g+rX /var/www/site/public chmod -R o-rwx /var/www/site/publicObservação: g+rX aplica X (execução) apenas em diretórios e em arquivos que já tenham execução, evitando tornar arquivos comuns executáveis.
Passo 4: recarregue e teste
apachectl -tsystemctl reload apache2 2>/dev/null || systemctl reload httpdcurl -I http://localhost/Passo a passo: corrigindo um 404 por caminho incorreto
Cenário: você acessa / e recebe 404, mas acredita que existe um index.html.
Passo 1: confirme o DocumentRoot efetivo
Verifique o arquivo do VirtualHost correspondente e confirme o caminho configurado. Em seguida, valide no sistema de arquivos se o conteúdo está lá.
ls -la /caminho/do/documentrootPasso 2: confirme o arquivo e o case do nome
ls -la /caminho/do/documentroot/index.htmlls -la /caminho/do/documentroot/index.phpSe o arquivo for Index.html e você espera index.html, no Linux isso é diferente e pode resultar em 404 dependendo do que está sendo requisitado.
Passo 3: procure no log por “File does not exist”
grep -R "File does not exist" /var/log/apache2/ /var/log/httpd/ 2>/dev/null | tail -n 20Como evitar permissões excessivas (o que NÃO fazer)
- Não use 777 para “resolver rápido”. Isso permite que qualquer usuário no servidor altere o conteúdo servido.
- Evite deixar o Apache como dono do código do site quando não é necessário. Se o processo web puder escrever no próprio código, um ataque que consiga escrita via aplicação pode alterar arquivos servidos.
- Separe escrita de leitura: se a aplicação precisa escrever em algum lugar (uploads, cache), isole em diretórios específicos com permissões controladas, em vez de abrir permissões no DocumentRoot inteiro.
Boas práticas mínimas para DocumentRoot e pastas de aplicação
1) DocumentRoot com leitura e travessia, sem escrita para o usuário do Apache
- Diretórios do DocumentRoot: tipicamente
755ou750(quando usando grupo) - Arquivos do DocumentRoot: tipicamente
644ou640 - Preferência: Apache não deve ter permissão de escrita no DocumentRoot
2) Use grupo para controlar acesso (modelo comum de deploy)
Modelo simples:
- Dono: usuário de deploy (ex.:
deploy) - Grupo: grupo compartilhado (ex.:
web) - Apache incluído no grupo
web - Permissões:
750em diretórios e640em arquivos (sem acesso para “outros”)
# Exemplo (ajuste usuário/grupo) chown -R deploy:web /var/www/site/public find /var/www/site/public -type d -exec chmod 750 {} \; find /var/www/site/public -type f -exec chmod 640 {} \;3) Diretórios de escrita separados (uploads/cache/logs da aplicação)
Se a aplicação precisa escrever, crie diretórios específicos fora do DocumentRoot quando possível, ou pelo menos separados e com escopo mínimo:
/var/www/site/storage(fora depublic)/var/www/site/cache/var/www/site/uploads(se inevitável, com regras de segurança adicionais no Apache)
Permissões típicas para diretório de escrita controlada (exemplo usando grupo):
chown -R deploy:web /var/www/site/storage chmod -R 770 /var/www/site/storageAssim, o Apache escreve apenas onde precisa, e o restante do conteúdo permanece somente leitura.
4) Verificação rápida antes de colocar no ar
- Confirme cadeia de permissões com
namei -lpara um arquivo real servido - Confirme que o usuário do Apache consegue ler o arquivo sem precisar de permissões “abertas”
- Revise logs após o reload para identificar 403/404 imediatamente