Todos os artigos
87 artigos · atualizado semanalmente Veja nossas Ferramentas
Todos os artigos
Tutoriais

chmod, chown e umask no Linux: permissões explicadas com exemplos de servidor

Entenda chmod (octal e simbólico), chown e umask com profundidade suficiente para resolver qualquer Permission denied em servidor — sem adivinhação.

COVER · Tutoriais

Você sobe um deploy novo, o servidor retorna 403 para arquivos que existem e estão no lugar certo. Ou pior: o nginx lê o arquivo mas a aplicação não consegue escrever no diretório de uploads — e o erro no log é um genérico Permission denied que não diz exatamente o quê. Permissões no Linux têm uma lógica interna consistente, mas quando você não domina os três comandos que as controlam, qualquer problema vira adivinhação.

Este post é sobre chmod, chown e umask com profundidade suficiente para que você consiga raciocinar sobre qualquer situação, não só memorizar os valores mais comuns. Se você quer o contexto de administração geral de servidor, o post Comandos Linux essenciais para quem trabalha com servidores cobre o diagnóstico do dia a dia — este aqui foca só no sistema de permissões.


Como o Linux organiza permissões

Antes de falar de comandos, o modelo mental:

Todo arquivo no Linux tem um dono (user), um grupo (group) e permissões para outros (others). Isso é o UGO. Cada uma das três entidades pode ter três permissões: leitura (r = 4), escrita (w = 2), execução (x = 1).

$ ls -l /var/www/html/index.php
-rw-r--r-- 1 www-data www-data 1234 Jun 10 14:32 index.php

A string -rw-r--r-- se lê assim:

  • - → tipo de arquivo (regular; d seria diretório)
  • rw- → dono pode ler e escrever (4+2=6)
  • r-- → grupo pode só ler (4)
  • r-- → outros podem só ler (4)

Isso é 644 em octal. O dono e grupo são www-data.


chmod — alterando permissões

Notação octal

A notação octal define o conjunto completo de permissões de uma vez. Cada dígito é a soma dos bits de uma entidade:

Bits Valor Significado
r-- 4 só leitura
rw- 6 leitura e escrita
rwx 7 leitura, escrita e execução
r-x 5 leitura e execução
--- 0 sem nenhuma permissão
chmod 644 arquivo.php      # dono: rw-, grupo: r--, outros: r--
chmod 755 diretorio/       # dono: rwx, grupo: r-x, outros: r-x
chmod 600 .env             # dono: rw-, grupo: ---, outros: ---
chmod 700 scripts/deploy.sh # só o dono executa e gerencia

A lógica de 755 para diretórios e scripts executáveis e 644 para arquivos estáticos é o padrão em praticamente qualquer servidor web.

Notação simbólica

A notação simbólica é boa para ajustes incrementais — você não precisa saber a permissão atual para aplicar uma mudança:

chmod +x script.sh          # adiciona execução para todos
chmod u+x script.sh         # adiciona execução só para o dono
chmod g-w arquivo.txt       # remove escrita do grupo
chmod o= arquivo.txt        # remove tudo de "others"
chmod u=rw,g=r,o= segredo   # define tudo de uma vez, sem execução para ninguém

A sintaxe é [ugoa][+-=][rwx]. Quando você usa + sem especificar entidade, aplica para todos (equivale a a+).

Recursivo com cautela

chmod -R 755 /var/www/html/

Cuidado aqui. chmod -R 755 em um diretório vai aplicar 755 em todos os arquivos dentro dele — incluindo arquivos de configuração que deveriam ser 600. O padrão mais seguro para aplicar permissões diferentes em arquivos e diretórios separadamente é usar find:

# Diretórios: 755
find /var/www/html -type d -exec chmod 755 {} \;

# Arquivos regulares: 644
find /var/www/html -type f -exec chmod 644 {} \;

# Scripts executáveis: 755 (só os .sh)
find /var/www/html -name "*.sh" -exec chmod 755 {} \;

SUID, SGID e sticky bit

São os três bits especiais, representados pelo quarto dígito octal (ou prefixo):

chmod 4755 programa    # SUID: executa com permissões do dono, não do executor
chmod 2755 diretorio/  # SGID: arquivos novos herdam o grupo do diretório
chmod 1755 /tmp        # Sticky bit: só o dono pode deletar seus arquivos

No sticky bit do /tmp, você já usa sem saber: qualquer usuário pode criar arquivo lá, mas só o dono ou root pode deletá-lo. Sem o sticky bit, qualquer usuário poderia apagar arquivos de outros.

O SUID em binários do sistema é comum (/usr/bin/passwd usa SUID para que um usuário comum possa mudar a própria senha sem ser root). Em arquivos que você controla em produção, evitar SUID — é um vetor de escalonamento de privilégios se houver vulnerabilidade no programa.


chown — alterando dono e grupo

chown usuario arquivo
chown usuario:grupo arquivo
chown :grupo arquivo          # só muda o grupo
chown -R www-data:www-data /var/www/html/

O caso de uso mais comum em servidor web: garantir que o processo do nginx/PHP-FPM consegue ler os arquivos da aplicação.

# Cenário típico: deploy manual
sudo chown -R deploy:www-data /var/www/minha-app/
sudo chmod -R 750 /var/www/minha-app/
sudo chmod -R 644 /var/www/minha-app/public/

O dono deploy tem controle total. O grupo www-data (processo web) pode ler e entrar nos diretórios, mas não modificar. Outros: sem acesso.

chown vs chmod — quando usar cada um

A confusão é comum: chown muda quem é o dono, chmod muda o que pode ser feito. Na prática, você quase sempre usa os dois juntos. O chown resolve o "quem", o chmod resolve o "quanto".

Se um arquivo está com as permissões certas mas o dono errado, o usuário correto não consegue fazer nada. Se o dono está certo mas as permissões são restritivas demais, o resultado é o mesmo.


umask — o que define as permissões padrão

O umask é o menos intuitivo dos três porque opera como máscara de subtração, não como atribuição. Quando você cria um arquivo ou diretório, o sistema parte de uma permissão base e subtrai o umask.

  • Base para arquivos: 666 (sem execução por padrão — execução é adicionada explicitamente)
  • Base para diretórios: 777

Com umask 022 (padrão na maioria das distros):

Criação Base umask Resultado
Arquivo 666 022 644
Diretório 777 022 755
umask           # mostra o valor atual
umask 027       # define para a sessão atual
umask 0027      # com notação de 4 dígitos (o 0 inicial é o bit especial)

Por que umask importa em produção

Em ambientes de servidor, o umask padrão afeta todos os arquivos criados por processos. Se o PHP-FPM ou Node.js criar um arquivo de upload com umask 022, o arquivo fica 644 — legível por todos no sistema. Se você quer uploads legíveis só pelo processo da aplicação, um umask 027 no processo garante arquivos 640 por padrão.

Para um usuário de deploy que só deve criar arquivos legíveis pelo grupo de web:

# No .bashrc ou .profile do usuário de deploy
umask 027

Para persistir em um serviço systemd:

[Service]
UMask=0027

Exemplos práticos de servidor

Configuração típica para aplicação web

# Estrutura padrão para uma app PHP/Python/Node em /var/www
sudo mkdir -p /var/www/minha-app/{public,storage,logs}

# Dono: deploy (usuário de CI/CD), grupo: www-data (processo web)
sudo chown -R deploy:www-data /var/www/minha-app

# Diretórios: deploy pode tudo, www-data pode entrar e ler
sudo chmod 750 /var/www/minha-app
sudo find /var/www/minha-app -type d -exec chmod 750 {} \;

# Arquivos: deploy lê/escreve, www-data só lê
sudo find /var/www/minha-app -type f -exec chmod 640 {} \;

# Diretório de uploads/storage: www-data precisa escrever
sudo chmod 770 /var/www/minha-app/storage
sudo chmod 770 /var/www/minha-app/logs

Protegendo arquivos de configuração

# .env nunca deve ser legível por outros processos
sudo chmod 600 /var/www/minha-app/.env
sudo chown deploy:deploy /var/www/minha-app/.env

Diagnóstico rápido de Permission denied

# Ver as permissões e dono de um arquivo
ls -la /caminho/para/arquivo

# Verificar o usuário do processo web
ps aux | grep nginx
ps aux | grep php-fpm

# Checar de qual usuário/grupo o processo está rodando
sudo -u www-data ls /var/www/minha-app/
# Se esse comando retornar Permission denied, o problema está confirmado

Para calcular a combinação certa de bits sem fazer soma mental, uso o chmod calculator — você marca os bits visualmente e vê o octal resultante ao lado.


Perguntas frequentes

Qual a diferença entre chmod octal e simbólico na prática?

Octal define o conjunto completo de permissões de uma vez — ideal quando você sabe exatamente o que quer (chmod 644 arquivo). Simbólico faz ajustes incrementais sem afetar o que já existe — ideal quando você quer apenas adicionar ou remover um bit específico sem mudar o resto (chmod g+w arquivo). Em scripts de deploy, octal é mais seguro porque o estado final é previsível independente do estado anterior.

Por que chmod 777 é um problema de segurança?

777 significa que qualquer usuário no sistema pode ler, escrever e executar o arquivo. Em um servidor compartilhado ou com múltiplos processos, isso quer dizer que um processo comprometido (ou qualquer usuário com shell access) pode sobrescrever ou executar o arquivo. Para diretórios de upload, 777 permite que qualquer processo deposite e depois execute um arquivo arbitrário — o caminho clássico para escalonamento de privilégios. 770 com o grupo correto resolve o mesmo problema de acesso sem abrir para todos.

Como o umask afeta processos de servidor como PHP-FPM ou Node?

O umask é herdado pelo processo filho a partir do processo pai. Se o PHP-FPM inicia com umask 022, todo arquivo que a aplicação criar via fwrite, file_put_contents ou upload vai ter permissão 644. Se isso é indesejável (uploads que só o processo web deve ler), configure UMask=0027 no arquivo de unit do systemd — arquivos ficam 640, diretórios 750.

sudo chown vs chown — quando cada um é necessário?

chown sem sudo funciona apenas se você é o dono do arquivo e quer mudar o grupo para um grupo do qual você também faz parte. Mudar o dono de um arquivo para outro usuário sempre exige root — isso é uma proteção do kernel, não uma política de distro. Em scripts de deploy automatizados, o padrão é o usuário de deploy já ser dono dos arquivos, evitando a necessidade de sudo chown em cada deploy.


Permissão certa desde o início

O erro mais caro com permissões não é o 403 que aparece imediatamente — é o arquivo criado com umask errado que fica com 644 quando deveria ser 640, e você só descobre quando alguém faz uma auditoria de segurança seis meses depois.

A disciplina é configurar umask, chown e chmod na criação da estrutura de diretórios, validar com ls -la e sudo -u www-data, e documentar. Depois de configurado corretamente uma vez, o sistema mantém a consistência — é a permissão padrão errada que faz o problema aparecer em toda criação de arquivo.

RD
Autor
Rafael Duarte
Desenvolvedor backend com passagem por fintech e SaaS B2B — trabalhou em times que escalaram APIs de zero a milhões de requisições. Carrega cicatrizes de produção suficientes para ter opiniões fortes sobre ferramentas, padrões e decisões de arquitetura. Não é acadêmico: leu a RFC do UUID quando precisou escolher entre v4 e v7 para uma tabela de alta escrita.
Ver perfil