Como resolver o erro 'opendir() failed (13: permission denied)' no Nginx proxy cache
Voltar para blog

Como resolver o erro 'opendir() failed (13: permission denied)' no Nginx proxy cache

05/09/2026 · 3 min · Servidores

Ao gerenciar camadas de cache e proxy reverso no Nginx, é possível deparar-se com erros críticos recorrentes no error.log:

2026/04/02 15:56:14 [crit] 34814#0: opendir() "/www/server/nginx/proxy_cache_dir/f" failed (13: Permission denied)
2026/04/02 15:56:14 [crit] 34814#0: opendir() "/www/server/nginx/proxy_cache_dir/c" failed (13: Permission denied)
2026/04/02 15:56:14 [crit] 34814#0: opendir() "/www/server/nginx/proxy_cache_dir/d" failed (13: Permission denied)

Neste artigo, compartilho o que ocorre por baixo do capô entre os processos do Nginx e o kernel Linux, como rastrear a causa raiz com ferramentas de diagnóstico e o passo a passo para corrigir as permissões definitivamente.

1. O que acontece por baixo dos panos?#

Quando o Nginx utiliza a diretiva proxy_cache_path, ele particiona as chaves de cache em subdiretórios baseados em hashes (como /f, /c, /d).

O ciclo de vida desses arquivos é gerenciado por processos auxiliares: o Cache Manager (responsável por purgar itens antigos ao atingir limites de disco) e os Workers de requisição. Para varrer a árvore de diretórios, o Nginx invoca a função opendir().

A nível de kernel, a biblioteca dispara a syscall openat() com a flag O_DIRECTORY. Para ter sucesso no controle de acesso discricionário (DAC) do Linux:

  1. Permissão de Execução (+x) nos diretórios pai: Sem o bit x, o processo é impedido de atravessar a árvore até a pasta de cache.
  2. Permissão de Leitura (+r) no subdiretório: Sem o bit r, a chamada getdents64 é bloqueada, gerando o erro de kernel EACCES (código 13: Permission denied).

O modelo de processos do Nginx#

O Nginx inicializa um processo Master (executando como root), mas os processos Worker e o Cache Manager rodam com privilégios rebaixados (geralmente sob o usuário www, nginx ou nobody, definido na diretiva user do nginx.conf).

Se o diretório de cache foi criado manualmente pelo root ou se houve alteração no usuário do webserver, os workers perdem o acesso de leitura e escrita.

2. Roteiro de diagnóstico via terminal#

Para validar exatamente o que o sistema operacional está bloqueando:

1. Inspecionar o UID/GID do worker#

Com base no PID indicado no log de erro (34814):

grep -E '^Uid|^Gid' /proc/34814/status

Ou listando os descritores de arquivo abertos:

lsof -p 34814 | grep proxy_cache_dir

2. Rastrear chamadas de sistema com strace#

Para capturar o momento exato em que a chamada openat recebe a negação de permissão:

strace -p 34814 -e trace=openat,getdents64 2>&1 | grep EACCES

3. Verificar atributos estendidos do sistema de arquivos#

Para garantir que o diretório não possui atributos de imutabilidade ativos:

lsattr -d /www/server/nginx/proxy_cache_dir/

3. Passo a passo para correção definitiva#

Passo 1: Ajustar a propriedade recursiva#

Identifique o usuário configurado no Nginx e atribua a titularidade correta de toda a árvore de cache:

# Captura o usuário definido no nginx.conf
NGINX_USER=$(grep -P '^user\s+\K[^;]+' /www/server/nginx/conf/nginx.conf | awk '{print $1}')

# Aplica o dono correto recursivamente
sudo chown -R $NGINX_USER:$NGINX_USER /www/server/nginx/proxy_cache_dir

Passo 2: Garantir permissão de travessia (+x)#

Garanta que os subdiretórios possuam permissão de execução para travessia:

sudo find /www/server/nginx/proxy_cache_dir -type d -exec chmod 700 {} +

Passo 3: Ajuste de contexto SELinux (se aplicável)#

Em distribuições como RHEL, CentOS ou Rocky Linux com SELinux habilitado, o contexto do diretório precisa permitir leitura e escrita pelo domínio web (httpd_sys_rw_content_t):

sudo semanage fcontext -a -t httpd_sys_rw_content_t "/www/server/nginx/proxy_cache_dir(/.*)?"
sudo restorecon -Rv /www/server/nginx/proxy_cache_dir

Passo 4: Verificar ponto de montagem#

Se o cache estiver armazenado em um disco ou partição dedicada (ex: NVMe/SSD à parte), confirme se o volume não foi montado em modo somente leitura (ro):

mount | grep proxy_cache_dir

Boas práticas para permissões no Nginx#

  1. Evite criar pastas de cache manualmente como root: Deixe o Nginx criar os subdiretórios automaticamente ou aplique chown imediatamente após a criação.
  2. Audite permissões após atualizações do nginx.conf: Se a diretiva user for alterada, atualize a propriedade dos diretórios temporários (client_body_temp, proxy_temp_dir e proxy_cache_dir).
  3. Monitore logs após recargas: Após rodar nginx -s reload, acompanhe o error.log para confirmar que o Cache Manager inicializou sem registrar eventos críticos.

Este artigo foi útil?

Deixe uma reação rápida para apoiar o conteúdo:

CC BY-NC

Este post está licenciado sob CC BY-NC.

Comentários

Participe da discussão abaixo.

0 comentários