Tutoriais de VPS
Site em VPS retornando 403 Forbidden (2026): checklist de permissões Nginx/Apache, index e SELinux
Quando um site em VPS conecta mas retorna 403 Forbidden, geralmente não é falha de rede, e sim o servidor web recusando o acesso. Este artigo percorre passo a passo Nginx, Apache, permissões de diretório, arquivos index, SELinux, proxy reverso e cenários comuns de WordPress.

Já vi muita gente que, assim que vê um 403, sai mudando DNS, reiniciando o servidor ou até suspeitando que a VPS está bloqueada. Na verdade, 403 Forbidden não é a mesma coisa que "não conecta".
Se o navegador consegue abrir a página mas mostra 403 Forbidden, isso significa que a requisição já chegou à sua VPS e o Nginx ou o Apache a receberam — eles apenas decidiram que esse caminho não pode ser acessado.
As causas mais comuns se dividem em poucas categorias: o diretório não tem arquivo index, as permissões de arquivo estão erradas, o owner do diretório do site está errado, a configuração do Nginx/Apache tem um deny, o SELinux está bloqueando, ou regras do WordPress ou do painel estão barrando a requisição.
A seguir está a ordem real de diagnóstico — não comece mudando permissões de qualquer jeito.
Comece verificando o código de resposta com curl:
curl -I https://example.com
Se aparecer algo como:
HTTP/1.1 403 Forbidden
Server: nginx
isso significa que o serviço web já respondeu — ele só está recusando o acesso.
Se em vez disso aparecer:
404 Not Found: o caminho ou arquivo não existe;502 Bad Gateway: algo atrás do Nginx, como PHP-FPM, Node ou Gunicorn, está com problema;521/522: o Cloudflare não conseguiu conectar à origem ou deu timeout;403 Forbidden: foque em permissões, diretórios, regras e políticas de segurança.
Essa distinção é importante. No 403 não se verifica a rede primeiro, e sim por que o servidor web não permite o acesso.
Nginx:
sudo tail -n 80 /var/log/nginx/error.log
Apache:
sudo tail -n 80 /var/log/apache2/error.log
No CentOS / AlmaLinux / Rocky Linux, o Apache pode ser:
sudo tail -n 80 /var/log/httpd/error_log
Entradas típicas de log se parecem com isto:
directory index of "/var/www/site/" is forbidden
Ou:
open() "/var/www/site/index.html" failed (13: Permission denied)
Essas duas significam coisas completamente diferentes.
A primeira é que o diretório não tem arquivo index e o servidor não permite listar diretórios; a segunda é que o arquivo existe, mas o usuário do servidor web não tem permissão para lê-lo.
Muitos 403 acontecem porque você acessou um diretório que não tem página inicial padrão.
Veja o diretório do site:
ls -lah /var/www/site
Deve haver pelo menos um destes:
index.html
index.htm
index.php
A configuração do Nginx também precisa estar correta:
index index.html index.htm index.php;
No Apache, verifique DirectoryIndex:
DirectoryIndex index.html index.php
Se o diretório realmente não tem arquivo index, o Nginx retornar 403 é normal. Não é que ele não consiga abrir — é que ele não permite exibir a listagem completa do diretório para os outros.
Para um teste temporário, coloque um arquivo:
echo 'ok' | sudo tee /var/www/site/index.html
Depois acesse o site de novo. Se o 403 desaparecer, o problema está no arquivo index ou na configuração da raiz do site.
Muita gente só olha as permissões de index.html e esquece os diretórios superiores.
Para ler um arquivo, o servidor web não precisa apenas ler o arquivo em si, mas também conseguir entrar nos diretórios superiores. Por exemplo, com /var/www/site/index.html, cada nível — /var, /var/www, /var/www/site — precisa ter permissão de execução.
Este comando é o mais direto:
namei -om /var/www/site/index.html
Normalmente fica mais ou menos assim:
drwxr-xr-x root root /
drwxr-xr-x root root var
drwxr-xr-x root root www
drwxr-xr-x www-data www-data site
-rw-r--r-- www-data www-data index.html
Recomendações comuns:
sudo find /var/www/site -type d -exec chmod 755 {} \;
sudo find /var/www/site -type f -exec chmod 644 {} \;
Não saia aplicando chmod -R 777 em tudo. Pode até fazer o 403 sumir, mas também acaba com a segurança.
No Ubuntu / Debian, os usuários comuns do Nginx e do Apache são www-data. Você pode definir o owner assim:
sudo chown -R www-data:www-data /var/www/site
No CentOS / AlmaLinux / Rocky Linux, o usuário comum do Apache é apache, e o do Nginx pode ser nginx:
sudo chown -R nginx:nginx /var/www/site
Se não tiver certeza de quem é o usuário, veja os processos:
ps aux | grep -E 'nginx|apache|httpd'
Muitos 403 do Nginx não são permissões do Linux, mas sim configuração que proíbe o acesso diretamente.
Primeiro teste a configuração:
sudo nginx -t
Depois veja a configuração do site:
sudo nginx -T | grep -nE 'server_name|root|location|deny|allow|try_files|autoindex'
Foque nestes pontos:
location / {
try_files $uri $uri/ =404;
}
Se uma requisição para / casar com um diretório que não tem arquivo index, pode aparecer directory index is forbidden.
Procure também regras como:
deny all;
Ou um location que bloqueia um diretório:
location /uploads/ {
deny all;
}
Se o 403 só acontece em um caminho específico, como /admin/, /uploads/ ou /.well-known/, foque no location correspondente.
Depois de alterar a configuração:
sudo nginx -t
sudo systemctl reload nginx
Os 403 do Apache costumam aparecer nestes pontos.
O diretório do site precisa permitir acesso:
<Directory /var/www/site>
Options FollowSymLinks
AllowOverride All
Require all granted
</Directory>
Se você vir:
Require all denied
fica bem claro: está negando o acesso.
Também tem o .htaccess. Depois de migrar WordPress, Laravel ou um projeto antigo, o .htaccess pode bagunçar facilmente as regras de caminho.
Você pode renomear temporariamente para testar:
sudo mv /var/www/site/.htaccess /var/www/site/.htaccess.bak
sudo systemctl reload apache2
Se o 403 desaparecer, o problema está no .htaccess. Não saia apagando; vá adicionando as regras de volta aos poucos.
Teste de configuração do Apache:
sudo apachectl configtest
Recarregar no Ubuntu / Debian:
sudo systemctl reload apache2
Família CentOS:
sudo systemctl reload httpd
Se você usa Rocky Linux, AlmaLinux ou CentOS Stream, as permissões parecem certas, mas ainda dá 403, é bem provável que seja o SELinux.
Primeiro veja o status:
getenforce
Se retornar:
Enforcing
então verifique o contexto:
ls -Z /var/www/site
Conteúdo web normalmente precisa de um contexto como httpd_sys_content_t.
Correção comum:
sudo restorecon -Rv /var/www/site
Se o diretório do seu site não está em um local padrão — por exemplo, em /home/deploy/site — você precisa definir o contexto separadamente. Não desligue o SELinux como solução permanente. Para verificação temporária, você pode usar:
sudo setenforce 0
Se o 403 sumir imediatamente ao desligar, você está no caminho certo. Lembre-se de restaurar depois de verificar:
sudo setenforce 1
Depois resolva com o contexto ou boolean corretos.
Se você usa WordPress, um 403 também pode vir de plugins, regras de firewall ou permalinks.
Tente nesta ordem:
- Renomear temporariamente o diretório do plugin de segurança;
- Regenerar os permalinks;
- Verificar
.htaccessou as regras de rewrite do Nginx; - Verificar as permissões de
wp-content/uploads; - Olhar o log de erros do servidor web, não só a página do navegador.
Usuários do BT Panel também devem verificar:
- Se o diretório do site foi escolhido errado;
- Se a proteção contra hotlink está bloqueando por engano;
- Se as regras de rewrite de URL estão casando errado;
- Se um WAF ou plugin de segurança está bloqueando;
- Se a raiz do site tem
index.htmlouindex.php.
Painéis reduzem a barreira de operação, mas as causas raiz do 403 continuam sendo as mesmas categorias: diretórios, permissões, regras e políticas de segurança.
| Sintoma | Causa mais provável | O que verificar primeiro |
|---|---|---|
| Página inicial 403, log diz directory index is forbidden | Não há arquivo index | ls -lah, configuração de index do Nginx/Apache |
| Log diz Permission denied | Permissões insuficientes do arquivo ou do diretório superior | namei -om, owner, chmod |
| Só um diretório retorna 403 | Bloqueio por location / .htaccess | Nginx location, Apache Directory, .htaccess |
| No CentOS as permissões estão certas mas ainda dá 403 | Contexto SELinux errado | getenforce, ls -Z, restorecon |
| Painel do WordPress ou diretório de uploads 403 | Plugin/WAF/rewrite/permissões de diretório | Plugins, .htaccess, permissões de uploads |
| 403 exibido atrás do Cloudflare | Bloqueio da origem ou de regras do Cloudflare | Logs da origem, WAF, regras de firewall |
Quando realmente encontro um 403, geralmente não reinstalo o ambiente primeiro, nem mudo para 777 na hora.
Sigo esta ordem:
curl -I https://example.com
sudo tail -n 80 /var/log/nginx/error.log
ls -lah /var/www/site
namei -om /var/www/site/index.html
sudo nginx -T | grep -nE 'root|index|location|deny|try_files'
Se for Apache, troco por:
sudo tail -n 80 /var/log/apache2/error.log
sudo apachectl configtest
grep -R "Require all" /etc/apache2/sites-enabled /etc/apache2/apache2.conf
Na família CentOS, acrescento:
getenforce
ls -Z /var/www/site
Seguindo essa ordem, normalmente consigo identificar em qual camada está o problema em uns dez minutos.
403 Forbidden é facilmente confundido com "o site caiu". Na verdade, muitas vezes é uma boa notícia: a requisição já chegou à VPS, o serviço web está vivo e é só alguma regra ou permissão que não deixa ler o arquivo.
Não reinstale o Nginx, reinicie a VPS ou mude o DNS de imediato. Primeiro olhe o log de erros, depois verifique index, permissões, configuração e SELinux. Basta aparecer directory index is forbidden ou Permission denied no log e a direção fica clara.