Dia 4: Permissões Avançadas em Linux — ACLs, SUID e SGID
As permissões básicas (rwx para dono/grupo/outros) cobrem 90% dos cenários — mas há casos onde não chegam: precisas de dar acesso a um ficheiro a um utilizador que não é o dono nem pertence ao grupo. Ou precisas que um binário execute com os privilégios do root. Ou queres que todos os ficheiros criados numa partilha herdem o grupo do directório pai. Para estes cenários, o Linux oferece ACLs (Access Control Lists), SUID/SGID (set-user-id / set-group-id), sticky bit e umask.
Este artigo cobre os quatro mecanismos avançados de permissões em Linux, com comandos testados em Debian/Ubuntu e RHEL/Rocky/Alma. No fim saberás quando usar setfacl em vez de chmod, como o SUID permite ao passwd mudar a password sem ser root, e porque é que /tmp tem o sticky bit activado.
Neste artigo
- ACLs — Access Control Lists (Permissões por Utilizador)
- setfacl e getfacl — Gerir e Consultar ACLs
- ACLs por Defeito — Herança em Directórios
- SUID e SGID — Executar com Privilégios de Outro Utilizador/Grupo
- Sticky Bit — Proteger Ficheiros em Directórios Partilhados
- Umask — Máscara de Permissões por Defeito
- Encontrar Ficheiros SUID/SGID e Sticky Bit
- Erros Comuns
- Checklist Rápido
ACLs — Access Control Lists (Permissões por Utilizador)
As permissões standard Unix têm três conjuntos: dono (owner), grupo (group) e outros (others). Isto significa que só podes dar acesso rwx a três categorias de utilizadores. Se precisares de dar acesso de leitura a um utilizador específico que não é o dono e não está no grupo, as permissões básicas não chegam — terias de criar um grupo só para ele, adicionar o utilizador ao grupo, e mudar o grupo do ficheiro.
ACLs resolvem isto: permitem definir permissões por utilizador individual ou por grupo individual, sem alterar o dono ou o grupo do ficheiro. Uma ACL é uma lista de entradas (entries), cada uma especificando um utilizador ou grupo e as permissões rwx que lhe aplicam. O kernel Linux suporta ACLs desde 2.6 nos sistemas de ficheiros ext2/ext3/ext4, XFS, Btrfs e outros — mas precisam de ser activadas no mount (na maioria das distribuições modernas já vêm activas por defeito).
Quando usar ACLs? Quando as permissões básicas não chegam: múltiplos utilizadores com níveis de acesso diferentes ao mesmo ficheiro, partilhas de ficheiros entre equipas, directórios de projectos onde cada membro precisa de permissões diferentes. Em ambientes enterprise, as ACLs são a norma — não a excepção.
Antes de usar ACLs, confirma que o sistema de ficheiros as suporta. Em ext4, por exemplo, as ACLs precisam da option acl no mount — mas nas distribuições modernas (Debian 12+, Ubuntu 22.04+, RHEL 9+, Rocky 9+) já vem activo por defeito. Podes verificar:
# Verificar se ACLs estão activas no sistema de ficheiros raiz
mount | grep "on / "
# Output típico: /dev/sda1 on / type ext4 (rw,relatime,acl)
# Se não estiverem, activar temporariamente (ext4):
sudo mount -o remount,acl /
# Para persistir, adicionar "acl" às options no /etc/fstab:
# /dev/sda1 / ext4 defaults,acl 0 1
Em XFS (padrão em RHEL/Rocky/Alma), as ACLs são sempre suportadas — não precisam de ser activadas. Em Btrfs, também suportadas por defeito. A documentação do Arch Linux sobre ACLs tem uma boa referência rápida.
setfacl e getfacl — Gerir e Consultar ACLs
O getfacl mostra as ACLs de um ficheiro. O setfacl define-as. Ambos fazem parte do pacote acl em Debian/Ubuntu e do acl em RHEL/Rocky/Alma.
# Instalar as ferramentas ACL (se ainda não estiverem)
# Debian/Ubuntu:
sudo apt install acl
# RHEL/Rocky/Alma:
sudo dnf install acl
# Criar um ficheiro de teste
echo "dados do projecto" > /tmp/projecto.txt
chmod 644 /tmp/projecto.txt
ls -l /tmp/projecto.txt
# -rw-r--r-- 1 user user 19 Jul 21 08:00 /tmp/projecto.txt
# Consultar ACLs (inicialmente, só as permissões básicas)
getfacl /tmp/projecto.txt
# # file: tmp/projecto.txt
# # owner: user
# # group: user
# user::rw-
# group::r--
# other::r--
# Dar permissão de leitura-escrita ao utilizador "maria"
sudo setfacl -m u:maria:rw /tmp/projecto.txt
# Dar permissão de leitura ao grupo "marketing"
sudo setfacl -m g:marketing:r /tmp/projecto.txt
# Verificar — nota o "+" no ls -l, indica que há ACLs
ls -l /tmp/projecto.txt
# -rw-r--r--+ 1 user user 19 Jul 21 08:00 /tmp/projecto.txt
getfacl /tmp/projecto.txt
# # file: tmp/projecto.txt
# # owner: user
# # group: user
# user::rw-
# user:maria:rw-
# group::r--
# group:marketing:r--
# mask::rw-
# other::r--
A sintaxe do setfacl -m é tipo:nome:permissões:
| Tipo | Significado | Exemplo |
|---|---|---|
u:nome:rwx |
Permissões para o utilizador “nome” | u:maria:rw |
g:nome:rwx |
Permissões para o grupo “nome” | g:marketing:r |
m::rwx |
Máscara (limite máximo de permissões efectivas) | m::r (restringe a read-only) |
o::rwx |
Permissões para “others” (equivale ao chmod o) | o::r |
Atenção à máscara (mask): Quando adicionas uma ACL, o Linux cria automaticamente uma mask que define o limite máximo de permissões efectivas para todas as entradas ACL (utilizadores e grupos nomeados, e o grupo base). Se definires setfacl -m u:maria:rw mas a mask for r, a maria só terá leitura efectiva. Para ajustar a mask: setfacl -m m::rw ficheiro.
# Remover uma entrada ACL específica
sudo setfacl -x u:maria /tmp/projecto.txt
# Remover todas as ACLs (reverter a só permissões básicas)
sudo setfacl -b /tmp/projecto.txt
ls -l /tmp/projecto.txt
# -rw-r--r-- 1 user user 19 Jul 21 08:00 /tmp/projecto.txt (sem "+")
# Aplicar recursivamente a um directório
sudo setfacl -R -m g:marketing:rx /opt/projecto/
# Copiar ACLs de um ficheiro para outro
getfacl ficheiro-modelo | setfacl --set-file=- ficheiro-novo
ACLs por Defeito — Herança em Directórios
Uma das funcionalidades mais úteis das ACLs são as ACLs por defeito (default ACLs): aplicadas a um directório, definem as permissões que todos os ficheiros e subdirectórios criados dentro dele herdam automaticamente. Isto resolve um problema clássico: numa partilha de equipa, cada novo ficheiro deveria ter o grupo da equipa com acesso — mas com chmod normal, o grupo do ficheiro é sempre o grupo primário do utilizador que o criou.
# Criar directório de projecto partilhado
sudo mkdir -p /opt/projecto-x
sudo chgrp marketing /opt/projecto-x
sudo chmod 770 /opt/projecto-x
# Definir ACL por defeito: grupo marketing com rwx em todos os
# ficheiros novos criados dentro do directório
sudo setfacl -d -m g:marketing:rwx /opt/projecto-x
# Verificar
getfacl /opt/projecto-x
# # file: opt/projecto-x
# # owner: root
# # group: marketing
# user::rwx
# group::rwx
# other::---
# default:user::rwx
# default:group::rwx
# default:group:marketing:rwx
# default:mask::rwx
# default:other::---
# Criar um ficheiro dentro e verificar que herda a ACL
touch /opt/projecto-x/nota.txt
getfacl /opt/projecto-x/nota.txt
# # file: opt/projecto-x/nota.txt
# # owner: user
# # group: user
# user::rw-
# group::r-- # group base (restringido pela umask)
# group:marketing:rwx # herança da default ACL!
# mask::rwx
# other::r--
Caso prático: Imagina um directório /srv/relatorios onde três equipas (marketing, vendas, financeiro) precisam de acesso. Com permissões básicas, terias de criar um grupo único e meter lá todos. Com ACLs por defeito, defines uma default ACL por equipa e cada ficheiro novo herda as três — sem qualquer acção manual.
SUID e SGID — Executar com Privilégios de Outro Utilizador/Grupo
O SUID (Set User ID) e SGID (Set Group ID) são bits especiais que alteram o comportamento de um binário executável. Quando um binário com SUID é executado, o processo corre com os privilégios do dono do ficheiro — não com os privilégios do utilizador que o invocou. O exemplo clássico é o passwd:
ls -l /usr/bin/passwd
# -rwsr-xr-x 1 root root 59976 Feb 6 09:24 /usr/bin/passwd
# ^
# O "s" no lugar do "x" do dono indica SUID
# Quando um utilizador normal executa passwd, o processo
# corre com UID=0 (root) — caso contrário não podia escrever
# em /etc/shadow, que só root pode ler/escrever.
O SGID funciona de forma análoga, mas com grupos. Aplicado a um executável, o processo corre com o GID do grupo do ficheiro. Aplicado a um directório, tem um comportamento diferente e muito útil: todos os ficheiros criados dentro desse directório herdam o grupo do directório (em vez do grupo primário do utilizador que os cria).
# SGID num executável:
ls -l /usr/bin/crontab
# -rwxr-sr-x 1 root crontab 43864 Jan 9 10:12 /usr/bin/crontab
# ^
# "s" no lugar do "x" do grupo indica SGID
# SGID num directório (caso mais comum):
sudo mkdir /srv/partilha
sudo chgrp marketing /srv/partilha
sudo chmod 2770 /srv/partilha # 2 = SGID
# Equivalente em simbólico:
sudo chmod g+s /srv/partilha
ls -ld /srv/partilha
# drwxrws--- 2 root marketing 4096 Jul 21 08:30 /srv/partilha
# ^
# "s" no lugar do "x" do grupo = SGID activo
# Agora, qualquer ficheiro criado dentro herda o grupo "marketing"
# mesmo que o utilizador que o cria tenha outro grupo primário:
touch /srv/partilha/ficheiro-novo.txt
ls -l /srv/partilha/ficheiro-novo.txt
# -rw-r--r-- 1 user marketing 0 Jul 21 08:31 /srv/partilha/ficheiro-novo.txt
# ^^^^^^^^
# grupo herdado do directório, não do utilizador
Os bits SUID/SGID têm representação numérica no chmod:
| Bit | Valor numérico | Simbólico | Efeito |
|---|---|---|---|
| SUID | 4xxx |
u+s |
Executável corre com UID do dono do ficheiro |
| SGID | 2xxx |
g+s |
Executável: corre com GID do grupo. Directório: novos ficheiros herdam o grupo |
| Sticky | 1xxx |
+t |
Directório: só o dono do ficheiro (ou root) pode apagar ficheiros |
| Combinações | 7xxx=todos |
— | 4+2+1=7 (SUID+SGID+Sticky, raro) |
Segurança: SUID root é um risco. Um binário com SUID root e uma vulnerabilidade permite escalada de privilégios — qualquer utilizador pode executá-lo como root. Por isso, só deve existir SUID root em binários de sistema validados (passwd, sudo, su, mount, etc.). Nunca aplicar SUID root a scripts shell — scripts podem ser manipulados. Em ambientes hardened, audita regularmente os binários SUID (ver secção “Encontrar Ficheiros SUID/SGID”).
Sticky Bit — Proteger Ficheiros em Directórios Partilhados
O sticky bit aplicado a um directório garante que, dentro desse directório, só o dono do ficheiro (ou o dono do directório, ou root) pode apagar ou renomear ficheiros — mesmo que outros utilizadores tenham permissão de escrita no directório. O exemplo universal é /tmp:
ls -ld /tmp
# drwxrwxrwt 8 root root 4096 Jul 21 08:00 /tmp
# ^
# "t" no lugar do "x" de outros = sticky bit activo
# Sem sticky bit, qualquer utilizador com permissão "w"
# no directório poderia apagar ficheiros de outros.
# Com sticky bit, o utilizador "maria" não pode apagar
# ficheiros do utilizador "joao" em /tmp, mesmo que
# ambos tenham acesso de escrita ao directório.
Para activar o sticky bit:
# Activar sticky bit num directório partilhado
sudo chmod 1777 /srv/partilha-publica
# Ou em simbólico:
sudo chmod +t /srv/partilha-publica
ls -ld /srv/partilha-publica
# drwxrwxrwt 2 root root 4096 Jul 21 08:35 /srv/partilha-publica
Quando usar sticky bit? Em qualquer directório onde múltiplos utilizadores têm permissão de escrita: /tmp (universal), directórios de upload de SFTP, partilhas de equipas, spools de impressão. Regra: se um directório tem chmod 777 ou o+w, deve quase sempre ter sticky bit.
Umask — Máscara de Permissões por Defeito
A umask (user file-creation mode mask) define as permissões que são removidas quando um ficheiro ou directório é criado. Não é uma permissão — é uma máscara: as permissões finais = permissões base − umask.
As permissões base são:
- Ficheiros: 666 (rw-rw-rw-) — os ficheiros nunca são executáveis por defeito
- Directórios: 777 (rwxrwxrwx) — directórios precisam de “x” para serem atravessados
A umask é subtraída (em modo octal, bit a bit) desses valores base:
| umask | Ficheiro (666) | Directório (777) | Uso típico |
|---|---|---|---|
022 |
644 (rw-r–r–) | 755 (rwxr-xr-x) | Padrão na maioria das distribuições |
027 |
640 (rw-r—–) | 750 (rwxr-x—) | Servidores — “others” sem acesso |
077 |
600 (rw——-) | 700 (rwx——) | Servidores hardened — só o dono |
002 |
664 (rw-rw-r–) | 775 (rwxrwxr-x) | Colaboração — grupo com escrita |
# Verificar a umask actual
umask
# 0022 (mostra 4 dígitos; o primeiro é para bits especiais)
# Alterar temporariamente (só para a sessão actual)
umask 027
# Verificar o efeito: criar um ficheiro e um directório
touch teste-umask.txt
mkdir teste-umask-dir
ls -l teste-umask.txt
# -rw-r----- 1 user user 0 Jul 21 08:40 teste-umask.txt
# 640 = 666 - 027
ls -ld teste-umask-dir
# drwxr-x--- 2 user user 4096 Jul 21 08:40 teste-umask-dir
# 750 = 777 - 027
Para tornar a umask permanente, tens de a definir no perfil do shell:
# Para um utilizador individual — adicionar ao ~/.bashrc ou ~/.profile
echo "umask 027" >> ~/.bashrc
# Para todos os utilizadores (system-wide):
# Debian/Ubuntu: adicionar a /etc/profile ou /etc/bash.bashrc
echo "umask 027" | sudo tee -a /etc/profile.d/umask.sh
sudo chmod 644 /etc/profile.d/umask.sh
# RHEL/Rocky/Alma: mesmo abordagem, /etc/profile.d/ é lido por defeito
echo "umask 027" | sudo tee -a /etc/profile.d/umask.sh
# Para serviços systemd (não usam /etc/profile):
# Definir no service file:
# [Service]
# UMask=0027
Subtração vs operação bit: Tecnicamente, a umask não é uma subtracção simples — é uma operação de NAND bit a bit: permissões_finais = base & ~umask. Para a maioria dos casos práticos (umask com dígitos ≤ 7), o resultado é o mesmo que subtracção. Mas casos edge como umask 033 com ficheiro base 666 dão 644 (não 633) porque 666 & ~033 = 644. A man page do umask (POSIX) explica o detalhe técnico.
Encontrar Ficheiros SUID/SGID e Sticky Bit
Em auditorias de segurança, é essencial saber que ficheiros têm SUID/SGID — qualquer binário SUID root é um potencial vector de escalada de privilégios. O find com a flag -perm procura-os:
# Encontrar todos os ficheiros SUID no sistema
sudo find / -perm -4000 -type f 2>/dev/null
# Encontrar todos os ficheiros SGID no sistema
sudo find / -perm -2000 -type f 2>/dev/null
# Encontrar ambos (SUID ou SGID) — usando perm /mode (OR)
sudo find / -perm /6000 -type f 2>/dev/null
# Encontrar directórios com sticky bit
sudo find / -perm -1000 -type d 2>/dev/null
# Listar SUID com detalhe (para auditoria)
sudo find / -perm -4000 -type f -exec ls -l {} \; 2>/dev/null
# Output típico:
# -rwsr-xr-x 1 root root 59976 Feb 6 09:24 /usr/bin/passwd
# -rwsr-xr-x 1 root root 72704 Jan 9 10:12 /usr/bin/chsh
# -rwsr-xr-x 1 root root 47552 Jan 9 10:12 /usr/bin/newgrp
# -rwsr-xr-x 1 root root 35160 Jan 9 10:12 /usr/bin/su
# ...
Auditoria recomendada: Guarda um snapshot dos binários SUID/SGID num sistema recém-instalado e compara periodicamente. Num servidor de produção, se aparecer um binário SUID root que não estava no snapshot, é sinal de alerta — pode indicar comprometimento. Ferramentas como AIDE ou tripwire automatizam esta verificação.
Para remover SUID/SGID de um binário (quando já não é necessário):
# Remover SUID
sudo chmod u-s /caminho/para/binario
# Ou em numérico: sudo chmod 0755 /caminho/para/binario
# Remover SGID
sudo chmod g-s /caminho/para/binario
# Remover ambos
sudo chmod 0755 /caminho/para/binario
# (0755 = sem bits especiais, dono rwx, grupo rx, outros rx)
Erros Comuns
| Erro | Causa | Solução |
|---|---|---|
setfacl: command not found |
Pacote acl não instalado |
sudo apt install acl (Debian/Ubuntu) ou sudo dnf install acl (RHEL/Rocky) |
Operation not supported ao aplicar ACL |
Sistema de ficheiros montado sem option acl (ext4 antigo) |
sudo mount -o remount,acl / e adicionar acl ao /etc/fstab |
| ACL aplicada mas utilizador não consegue escrever | A mask restringe as permissões efectivas | Verificar com getfacl; ajustar mask: setfacl -m m::rw ficheiro |
| Sticky bit aparece como “T” (maiúscula) em vez de “t” | O bit de execute para “others” não está activo | chmod o+x dir primeiro, depois chmod +t dir. “t” = sticky + x; “T” = sticky sem x |
| SUID aparece como “S” (maiúscula) em vez de “s” | O bit de execute do dono não está activo | chmod u+x binario primeiro. “s” = SUID + x; “S” = SUID sem x (raramente útil) |
| Umask alterada mas não persiste após reboot | Definida só na sessão actual (umask 027 na shell) |
Adicionar a ~/.bashrc, /etc/profile.d/umask.sh ou UMask= no service file do systemd |
| SGID no directório mas novos ficheiros não herdam o grupo | Alguns programas (e.g. cp -a, rsync sem flags) preservam o grupo original |
Usar cp sem -a, ou chgrp manual após copiar |
Checklist Rápido
No fim do Dia 4, deves conseguir:
- Verificar se as ACLs estão activas no sistema de ficheiros com
mount | grep acle instalar o pacoteacl - Dar permissão a um utilizador individual com
setfacl -m u:nome:rw ficheiroe consultar comgetfacl - Definir uma ACL por defeito num directório para que novos ficheiros herdem permissões automaticamente (
setfacl -d -m g:grupo:rwx dir) - Explicar porque é que o
passwdtem SUID e activar SGID num directório comchmod 2770 dirouchmod g+s dir - Explicar o que faz o sticky bit em
/tmpe activá-lo noutro directório comchmod +t dir - Calcular as permissões resultantes de uma umask 027 (ficheiro: 640, directório: 750) e torná-la permanente em
/etc/profile.d/ - Listar todos os binários SUID/SGID no sistema com
find / -perm /6000 -type fe remover SUID desnecessário comchmod u-s - Saber distinguir
s(SUID+x) deS(SUID sem x) et(sticky+x) deT(sticky sem x) nols -l
Artigos Relacionados
- Dia 1: Terminal, Shell e Comandos Essenciais — introdução às permissões básicas (rwx) que este artigo expande
- Dia 2: Sistema de Ficheiros Linux — FHS, Mounts e Links — mount options (incluindo
acl) e sistemas de ficheiros que suportam ACLs - Sistemas Operativos no kbase.pt — mais artigos Linux e administração de sistemas