Permissões de Arquivo no Linux: chmod e chown Explicados na Prática
Entenda permissões rwx, ownership e como usar chmod e chown no Linux para resolver Permission denied de uma vez por todas em sua VPS.
Você executa um script, deploya uma aplicação ou monta um volume e bate naquele erro:
Permission denied. A primeira reação é jogar chmod 777 em tudo e seguir
em frente. Funciona — e quebra a segurança do servidor no processo.
Permissões no Linux não são um obstáculo arbitrário: são o modelo que separa o
seu Apache do seu MySQL, o seu deploy do seu shell pessoal, e o seu container do
host. Entender isso de verdade leva uns 20 minutos e elimina 90% dos erros de
deploy em VPS.
Este guia é pra desenvolvedor que já usa Linux mas nunca parou pra entender o
que rwxr-xr-x significa, por que chmod 644 é o padrão de arquivo e quando
chown resolve o problema que chmod não resolve. Ao final você vai ler a
saída de ls -l na hora, ajustar permissões com confiança e parar de quebrar
servidor com 777.
Tempo estimado: 20 minutos pra ler e testar os comandos numa VPS de teste.
Pré-requisitos
Qualquer distribuição Linux moderna (Ubuntu 22.04+, Debian 12, Rocky 9, Alma 9)
com acesso SSH e capacidade de criar arquivos no seu home. Não precisa de sudo
pra maior parte dos exemplos — só pra seção de chown. Se está testando numa
VPS Hostini recém-provisionada, conecte como root ou crie um usuário normal
com adduser teste.
Ubuntu 22.04+, Debian 12, Rocky 9 ls, chmod, chown, stat, umask Usuário normal (chown exige root) Lendo a saída de ls -l linha por linha
Toda análise de permissão começa com ls -l. A saída parece criptografada
até você decompor os 10 caracteres da coluna esquerda:
ls -l arquivo.txt
-rw-r--r-- 1 joabe www-data 1248 May 29 14:32 arquivo.txt
Esses 10 caracteres se dividem em quatro grupos. O primeiro caractere indica o
tipo: - é arquivo regular, d é diretório, l é link simbólico, c é
device de caractere, b é device de bloco. Os 9 caracteres seguintes formam
três trincas de rwx: a primeira pro dono (user), a segunda pro grupo,
a terceira pra outros (everyone else).
No exemplo acima, rw- pro dono significa que joabe pode ler e escrever, mas
não executar. r-- pro grupo www-data significa que membros desse grupo só
podem ler. O segundo r-- significa o mesmo pra qualquer outro usuário do
sistema. Os números e nomes depois mostram: contagem de hardlinks (1), dono
(joabe), grupo (www-data), tamanho em bytes (1248) e timestamp.
O que rwx significa em diretório
A pegadinha clássica: r, w e x mudam de significado quando aplicados a
diretórios.
| Bit | Em arquivo | Em diretório |
|---|---|---|
| r | ler conteúdo | listar nomes (ls) |
| w | escrever/modificar | criar/apagar/renomear arquivos dentro |
| x | executar | atravessar (cd, acessar arquivos lá dentro) |
Isso explica o erro mais comum de iniciante: você tem permissão rw- num
arquivo mas não consegue acessá-lo porque o diretório pai está sem x pro seu
usuário. O kernel literalmente não consegue resolver o caminho até o inode.
Notação octal: por que 755 é mais rápido que rwxr-xr-x
Cada trinca rwx é um número de 3 bits. Lendo r=4, w=2, x=1 e somando:
| Decimal | Bits | Significado |
|---|---|---|
| 7 | rwx | leitura + escrita + execução |
| 6 | rw- | leitura + escrita |
| 5 | r-x | leitura + execução |
| 4 | r— | só leitura |
| 0 | --- | nenhum |
chmod 755 script.sh traduz pra rwxr-xr-x: dono pode tudo, grupo e outros
podem ler e executar. chmod 644 config.ini é rw-r--r--: dono escreve,
grupo e outros só leem. chmod 600 chave_privada é rw-------: ninguém
além do dono toca — padrão pra chaves SSH e credenciais.
Decorar essa tabela leva 5 minutos e elimina a necessidade de pensar em
r+w+x toda vez.
Mudando permissões com chmod
O comando chmod aceita dois estilos: octal (chmod 644 arquivo) e
simbólico (chmod u+x script.sh). Octal é melhor pra definir permissões
de forma absoluta; simbólico é melhor pra adicionar ou remover um bit
específico sem mexer no resto.
Crie um arquivo de teste e veja as permissões iniciais:
touch teste.sh
ls -l teste.sh
-rw-rw-r-- 1 joabe joabe 0 May 29 14:40 teste.shO padrão 664 ou 644 vem da umask do seu shell. Voltaremos a isso depois.
Adicione permissão de execução pro dono usando notação simbólica:
chmod u+x teste.sh
ls -l teste.sh
-rwxrw-r-- 1 joabe joabe 0 May 29 14:40 teste.shu+x significa “user, adiciona execute”. Você poderia usar g+x pra grupo,
o+x pra outros, ou a+x pra todos. Pra remover, troque + por -:
chmod o-r arquivo tira leitura de outros.
Defina permissões absolutas usando notação octal:
chmod 755 teste.sh
ls -l teste.sh
-rwxr-xr-x 1 joabe joabe 0 May 29 14:40 teste.sh755 sobrescreve tudo: dono rwx, grupo r-x, outros r-x. Esse é o
padrão pra scripts e binários executáveis públicos.
777 dá escrita pra qualquer usuário do sistema. Em servidor multi-usuário ou
exposto via web, isso permite que qualquer processo (incluindo um script PHP
comprometido) sobrescreva seus arquivos. Use 755 pra diretórios públicos e
644 pra arquivos — quase nunca há motivo legítimo pra 777.
Recursão com -R
Aplicar permissões a uma árvore inteira usa -R:
chmod -R 755 /var/www/meusite
Isso aplica 755 a todo arquivo e diretório dentro. O problema: arquivos de
config geralmente querem 644, não 755. A solução é usar find com -type
pra separar:
find /var/www/meusite -type d -exec chmod 755 {} \;
find /var/www/meusite -type f -exec chmod 644 {} \;
Diretórios recebem 755 (precisam de x pra atravessar), arquivos recebem
644 (não precisam de execução por padrão). Esse é o setup correto pra
quase qualquer site PHP, Node ou static.
Mudando dono com chown
chmod ajusta o que dono/grupo/outros podem fazer. chown muda quem
é o dono e o grupo. Exige sudo ou ser root, porque mudar ownership é uma
operação privilegiada (você poderia “doar” um arquivo seu pra outro usuário
explorá-lo).
Veja o dono atual:
ls -l /var/www/meusite/index.html
-rw-r--r-- 1 root root 1248 May 29 14:50 index.htmlArquivo pertence a root:root — Apache/Nginx rodando como www-data não
consegue escrever (e às vezes nem ler, dependendo do diretório pai).
Mude dono e grupo pra www-data:
sudo chown www-data:www-data /var/www/meusite/index.html
ls -l /var/www/meusite/index.html
-rw-r--r-- 1 www-data www-data 1248 May 29 14:50 index.htmlA sintaxe usuario:grupo muda os dois ao mesmo tempo. Você pode usar só
chown www-data arquivo pra mudar apenas o dono mantendo o grupo, ou
chown :www-data arquivo (com o dois-pontos no início) pra mudar só o grupo.
Aplique recursivamente a um diretório inteiro:
sudo chown -R www-data:www-data /var/www/meusiteEsse é o passo que falta em 70% dos deploys de PHP quebrados — você copia o
projeto como root, esquece o chown, e o Nginx serve 403 porque
www-data não tem permissão de ler nada.
Por padrão, chown -R segue links simbólicos e muda o dono do alvo, o que
pode bagunçar permissões fora da árvore que você queria mudar. Use
chown -RH pra seguir só o link da raiz, ou chown -RP pra não seguir
nenhum link (recomendado em árvores com symlinks).
umask: por que arquivos novos nascem com permissões específicas
Quando você cria um arquivo com touch, ele nasce com permissões 644 ou
664 dependendo da distro. Isso vem da umask — uma máscara que remove
bits do padrão 666 pra arquivos e 777 pra diretórios.
umask
0022
0022 significa: remova 0 do dono, 2 (write) do grupo, 2 (write) de
outros. Resultado: arquivos nascem 644 e diretórios nascem 755. Distros
como Ubuntu desktop usam 0002 (grupo mantém escrita), enquanto servidores
geralmente usam 0022 (grupo só lê).
Pra mudar permanentemente, adicione umask 0027 no .bashrc ou .zshrc —
isso deixa arquivos novos 640 e diretórios 750, escondendo de “outros”
por padrão. Útil em servidor com múltiplos usuários.
Verificação rápida do estado atual
Pra checar o que ficou definido sem decifrar ls -l:
stat -c '%a %U %G %n' arquivo.txt
644 joabe joabe arquivo.txt
Retorna octal, dono, grupo e nome. Em scripts é melhor que parsear ls -l.
Pra ver permissões de uma árvore inteira em octal:
find /var/www/meusite -printf '%m %u:%g %p\n' | head -20
Resolução de problemas
Permission denied mesmo sendo dono
Verifique o diretório pai. Se /home/joabe está 700 (drwx------) mas você
está acessando como outro usuário, ele não consegue nem entrar. Solução: ou
ajusta o pai com chmod 711 (permite traversal sem listing), ou move o
arquivo pra um diretório mais acessível.
chown: operation not permitted
Você esqueceu o sudo. Mudar ownership é privilégio de root, exceto pra
“doar” arquivo seu pra outro usuário em alguns kernels — comportamento que a
maioria das distros desabilita por segurança.
chmod num link simbólico não funciona
chmod em link sempre afeta o alvo, não o link. Permissões do link em si
são sempre lrwxrwxrwx e ignoradas — o sistema usa as permissões do alvo.
Pra “proteger” um link, proteja o diretório que contém ele.
Próximos passos
- Estude
setuid,setgidesticky bit(chmod 4755,2755,1755) — bits especiais usados em/usr/bin/passwde/tmp. - Aprenda ACLs (
setfacl,getfacl) pra controle além do modelo user/group/other tradicional. - Configure
umaskpermanente no/etc/profileou~/.bashrcconforme o perfil do servidor. - Veja como Docker e namespaces mudam o jogo: container rodando como root pode escrever em volumes do host se UIDs colidirem.
Se você está colocando aplicação em produção e quer um ambiente onde
permissões já vêm sãs por padrão — usuário deploy separado, www-data isolado,
sudo limitado — uma VPS Hostini já vem com esse baseline configurado
no provisionamento, sem precisar ajustar chmod em diretório de sistema no
primeiro deploy.
Perguntas frequentes
Qual a diferença entre chmod 755 e chmod 644?
755 dá leitura, escrita e execução pro dono (7) e leitura e execução pro grupo e outros (5+5) — usado em diretórios e binários executáveis. 644 dá leitura e escrita pro dono (6) e só leitura pro grupo e outros (4+4) — padrão pra arquivos de configuração e conteúdo estático.
Por que recebo Permission denied mesmo sendo dono do arquivo?
Ownership do arquivo não basta — o diretório que o contém precisa ter permissão de execução (x) pro seu usuário, senão o kernel nem consegue resolver o inode. Verifique com ls -ld /caminho/do/diretorio e ajuste com chmod +x no diretório.
Quando uso chmod -R e quando isso é perigoso?
Use -R (recursivo) quando quer aplicar a mesma máscara a todos os arquivos e subdiretórios de uma árvore — por exemplo, ao restaurar permissões de um site recém-copiado. Cuidado: chmod -R 777 em um diretório de usuário ou /etc deixa o sistema vulnerável e remove a distinção entre arquivos e diretórios executáveis.
Qual a diferença entre chown e chgrp?
chown muda o dono (user) do arquivo, e opcionalmente também o grupo com a sintaxe chown user:grupo arquivo. chgrp muda só o grupo. Na prática, chown user:grupo cobre os dois casos e quase ninguém usa chgrp em scripts modernos.
O que significa o t no final de drwxrwxrwt do /tmp?
É o sticky bit. Em diretórios com escrita pública (como /tmp), o sticky bit garante que só o dono do arquivo (ou root) pode apagar ou renomear — mesmo que outros usuários tenham permissão de escrita no diretório. Aplicado com chmod +t /caminho.
Como ver as permissões em formato octal sem decorar?
Use stat -c '%a %n' arquivo — retorna 644 nome.txt diretamente. Mais rápido que somar rwx do ls -l. Em scripts, find /caminho -printf '%m %p\n' lista permissões octais de uma árvore inteira.