Listas de Controle de Acesso POSIX
O tradicional mecanismo de permissões de arquivos UNIX tem sido utilizados há dezenas de anos para implementar-se controle de acesso. Com a crescente evolução dos modelos de controle de acesso, e necessidade de maior facilidade na gerência de permissões nos sistemas de arquivos UNIX, o comitê de padronização POSIX inicio o desenvolvimento de uma especificação de listas de controle de acesso, também conhecidas por ACLs (Access Control Lists).
Os padrões POSIX 1003.1e e 1003.2c, curiosamente, não foram finalizados, atingindo apenas o status de "rascunhos de padrões". Na verdade, virtualmente todas as implementações UNIX de listas de controle de acesso baseiam-se nestes documentos, tornando o rascunho por direito um padrão.
Sistemas de arquivos compatíveis
Os seguintes sistemas de arquivos sofreram modificações e atualmente suportam a utilização de ACLs POSIX:
- Ext2
- Ext3
- ReiserFS
- JFS
- XFS
Exemplo de cenário
Em que situações sua política de controle de acesso pode vir a exigir mais que os tradicionais conceitos de permissões de arquivos UNIX? É bem provável que sua implementação de controle de acesso tem mapeado grupos de usuários (UNIX) a departamentos ou funções em sua instituição.
Imagine o seguinte cenário:
- Departamento de Marketing
- Diretor de Marketing e Vendas:
Um modelo de controle de acesso deve ser implementado nos diretórios de ambos os grupos, de maneira que apenas usuários dos respectivos grupos tenham acesso (com permissões que lhe possibilitem executar leitura, modificação e exclusão de arquivos).
Este problema pode ser facilmente resolvido com o modelos de permissão de arquivos UNIX. A solução seria a seguinte:
- Departamento de Marketing
- Criação do grupo UNIX marketing
- Diretório padrão de arquivos: /arquivos/marketing
- Inclusão dos membros do grupo:
- Departamento Comercial
- Criação do grupo UNIX comercial
- Diretório padrão de arquivos: /arquivos/comercial
- Inclusão dos membros do grupo:
- Diretor de Marketing e Vendas:
- Inclusão do Sr. Mark Sales nos grupos marketing e comercial

Segue a seqüencia de comandos que criariam toda esta estrutura:
[root@localhost:~]# groupadd marketing
[root@localhost:~]# groupadd comercial
[root@localhost:~]# useradd -G marketing jose
[root@localhost:~]# useradd -G marketing maria
[root@localhost:~]# useradd -G marketing joao
[root@localhost:~]# useradd -G comercial fulano
[root@localhost:~]# useradd -G comercial sicrano
[root@localhost:~]# useradd -G comercial beltrano
[root@localhost:~]# useradd -G marketing,comercial mark
[root@localhost:~]# mkdir /arquivos/marketing
[root@localhost:~]# chgrp marketing /arquivos/marketing
[root@localhost:~]# chmod 2770 /arquivos/marketing
[root@localhost:~]# mkdir /arquivos/comercial
[root@localhost:~]# chgrp marketing /arquivos/comercial
[root@localhost:~]# chmod 2770 /arquivos/comercial
Até aqui, tudo na mais tranqüila paz, e os recursos de permissões de arquivos UNIX tradicionais nos serviram bem.
Imagine agora, que uma novo projeto foi lançada em sua instituição, projeto este que requer trabalho conjunto dos departamentos de Marketing e Comercial. Para acomodar os arquivos compartilhados entre os ambos os departamentos neste novo projeto, o diretório
/arquivos/novoprojeto será criado.
Para o funcionamento ideal do mecanismo de controle de acesso, o diretório
/arquivos/novoprojeto, precisa conter permissões para os membros do grupo marketing (jose, maria e joao), do grupo comercial (fulano, sicrano, beltrano) bem como do diretor dos departamentos (mark).
A única implementação possível desta política de controle de acesso, dentro dos recursos tradicionais de permissões de arquivos UNIX, seria a criação de um novo grupo, possivelmente de novo
novoprojeto, contendo como membros todos os 7 usuários listados acima. Neste ponto começamos a ver limitações do simples e tradicional modelo UNIX.

De qualquer forma, estes seriam os comandos necessários para implementarmos este novo grupo:
[root@localhost:~]# groupadd novoprojeto
[root@localhost:~]# usermod -G marketing,novoprojeto jose
[root@localhost:~]# usermod -G marketing,novoprojeto maria
[root@localhost:~]# usermod -G marketing,novoprojeto joao
[root@localhost:~]# usermod -G comercial,novoprojeto fulano
[root@localhost:~]# usermod -G comercial,novoprojeto sicrano
[root@localhost:~]# usermod -G comercial,novoprojeto beltrano
[root@localhost:~]# useradd -G marketing,comercial,novoprojeto mark
[root@localhost:~]# mkdir /arquivos/novoprojeto
[root@localhost:~]# chgrp novoprojeto /arquivos/novoprojeto
[root@localhost:~]# chmod 2770 /arquivos/novoprojeto
Suponha agora que um novo departamento seja convidado a fazer parte deste novo projeto. O problema desta vez é que este departamento conta com certa de 300 usuários. O trabalho manual e repetitivo nos indica que uma melhor solução deve ser buscada para este problema.
Requerimentos básicos e instalação
A maioria das distribuições atuais tornam fácil a utilização de ACLs POSIX. Bem como o suporte presente no Kernel, a presença das ferramentas de manipulação de ACLs como parte do sistema padrão tornam imediata a utilização deste recurso.
Caso ainda assim você precise certificar-se da presença de suporte em seu sistema, seguem os passos a se seguir.
Suporte a ACLs no Kernel:

Digite o seguinte comando para verificar a presença de ACLs POSIX em seu kernel:
[root@localhost:~]# grep POSIX_ACL /boot/config-$(uname -r)
CONFIG_EXT2_FS_POSIX_ACL=y
CONFIG_EXT3_FS_POSIX_ACL=y
CONFIG_JFS_POSIX_ACL=y
CONFIG_FS_POSIX_ACL=y
CONFIG_XFS_POSIX_ACL=y
Ferramentas de manipulação de ACLs POSIX
As ferramentas
setfacl e
getfacl geralmente estão disponíveis nas distribuições modernas.

Teste a preseça destas simplesmente tentando executá-las:
[root@localhost:~]# setfacl --version
setfacl 2.2.23
[root@localhost:~]# getfacl --version
setfacl 2.2.23
Estas ferramentas geralmente fazem parte do pacote de nome
acl.
Opção de montagem do sistema de arquivos
Apesar do suporte a ACLs estar presente em seu Kernel, seu sistema de arquivos deve ser montado com opções que habilitem esse suporte.

Para simplesmente ativar este suporte, e assumindo que seu diretório
/arquivos é uma partição/sistema de arquivos independente, execute o comando:
[root@localhost:~]# mount -o remount,acl /arquivos

Para constatar o sucesso do comando anterior, entre com o comando:
[root@localhost:~]# mount | grep home
/dev/hda5 on /arquivos type ext3 (rw,acl)
Caso seu computador não possua uma partição separada para o diretório
/arquivos, há uma maneira fácil de criar um novo sistema de arquivos.

Primeiro, criaremos um arquivo com 20MB (cheio de zeros):
[root@localhost:~]# dd if=/dev/zero of=fs.img bs=1M count=20
20+0 records in
20+0 records out
20971520 bytes transferred in 0.072008 seconds (291238919 bytes/sec)

Em seguida, criaremos um sistema de arquivos EXT3 neste arquivo:
[root@localhost:~]# mkfs.ext3 fs.img
fs.img is not a block special device.
Proceed anyway? (y,n) y
Filesystem label=
OS type: Linux
Block size=1024 (log=0)
Fragment size=1024 (log=0)
5136 inodes, 20480 blocks
1024 blocks (5.00%) reserved for the super user
First data block=1
...

Crie agora um diretório para ser usado como ponto de montagem:
[root@localhost:~]# mkdir /arquivos

Por fim, monte este sistema de arquivos, habilitando as opções loopback (sistema de arquivos dentro de arquivos), e acl:
[root@localhost:~]# mount -t ext3 -o loop,acl fs.img /arquivos
Introdução as ACLs POSIX: ACLs Mínimas

Para começarmos a experimentar com as ACLs POSIX, iremos criar um diretório temporário:
[root@localhost:~]# mkdir /arquivos/temp
[root@localhost:~]# ls -ld /arquivos/temp
drwxr-xr-x 2 root root 4096 Aug 22 06:51 /arquivos/temp

Agora, nosso primeiro contato com a ferramenta
getfacl:
[root@localhost:~]# cd /arquivos/
[root@localhost:~]# getfacl temp
# file: temp
# owner: root
# group: root
user::rwx
group::r-x
other::r-x
A ferramenta
getfacl nos mostra nas duas primeiras linhas, informações sobre o diretório (nome, dono e grupo). Esta seção é chamada pela ferramenta de
header, ou cabeçalho. As três linhas que seguem, contéem as reais permissões setadas para este diretório. No exemplo acima, não configuramos nenhuma ACL no diretório
/arquivos/temp, ainda assim temos permissões para
user (dono, rwx), para
group (grupo, r-x) e
other (outros, r-x).
Isso mostra que as ACLs posix interagem com as permissões tradicionais UNIX. Podemos então manipulá-las através do comando
setafcl.

Exemplo:
[root@localhost:~]# cd /arquivos/
[root@localhost:~]# setfacl -m user::rw temp
[root@localhost:~]# ls -ld temp
drw-r-xr-x 2 root root 1024 Aug 24 06:43 temp
Podemos ver aqui que as permissões para o dono do arquivo foi configurada para
rw, conforme especificado no comando
setfacl.

: O resultado do que fizemos também é visível através do comando
getfacl:
[root@localhost:~]# getfacl temp
# file: temp
# owner: root
# group: root
user::rw-
group::r-x
other::r-x
Este exemplo demonstra o primeiro tipo de ACLs, chamadas de ACLs Mínimas, pois apresentam o conjunto mínimo de permissões exigido por um sistema de arquivos UNIX.
ACLs Extendidas
Quando modificamos as ACLs de um diretório ou arquivo através da ferramenta
setfacl, e adicionamos permissões para outros usuário ou grupos, estamos criando ACLs Extendidas.

Um exemplo:
[root@localhost:/arquivos]# setfacl -m user:joao:r-x temp
[root@localhost:/arquivos]# getfacl temp
# file: temp
# owner: root
# group: root
user::rw-
user:joao:r-x
group::r-x
mask::r-x
other::r-x
Note que uma nova ACL, relacionada ao usuário
joao, foi adicionada, permitindo a este usuário ler (listar o conteúdo) e executar (acessar) o diretório temp. Note também que a ACL
mask::r-x foi criada automaticamente, e tem um significado especial descrito a seguir.
Para simplificar a discussão, iremos nos referir as seguintes ACL pelos reespectivos nomes:
- user:: : ACL do dono
- group:: : ACL do grupo
- other:: : ACL de outros
- mask:: : ACL de máscara
- user:joao: : ACL de usuário (usuário joao neste caso)
- group:gnu: : ACL de grupo (grupo gnu neste caso)
Note a diferença entre ACL
do grupo, e ACL
de grupo, a primeira represetando a ACL do grupo do arquivo, e a segunda representando uma ACL de um grupo manualmente especificado.
Também para simplificar a discussão, iremos nos referir a arquivos ou diretórios como
objetos.
ACLs de máscara
Quando criamos uma nova ACL de usuário ou de grupo, a ACL de máscara é ajustada para permitir as permissões descritas nas ACLs de usuários e nas ACLs de grupos. Exemplo:
Sempre que criamos novas ACLs de usuários ou ACLs de grupos, a ACL de máscara segue o padrão de adaptar-se as ACLs criadas.

Exemplo:
[root@localhost:/arquivos]# setfacl -m user:maria:rwx temp
[root@localhost:/arquivos]# getfacl temp
# file: temp
# owner: root
# group: root
user::rw-
user:joao:r-x
user:maria:rwx
group::r-x
mask::rwx
other::r-x
Uma maneira mais visual de ver o ocorrido:
A ACL de máscara tem a função de configurar o nível efetivo de privilégio que ACLs de grupos e de usuários terão sobre o arquivo ou diretório. Ao fazer julgamento sobre o privilégio de um usuário para executar um operação sobre um arquivo ou usuário, suas permissões de usuário são "filtradas" pela máscara. Um operação lógica
AND é executada com sua ACL de usuário e a ACL de máscara do objeto.

Exemplo:
[root@localhost:/arquivos]# setfacl -m user:joao:rwx temp
[root@localhost:/arquivos]# getfacl temp | egrep 'user:joao|mask'
user:joao:rwx
mask::rwx
Note que a máscara seguiu a permissão dada ao usuário
joao, da mesma forma que aconteceu com a ACL da
maria no exemplo anterior. A seguir, modificaremos a ACL de máscara:
[root@localhost:/arquivos]# setfacl -m mask::r-- temp
[root@localhost:/arquivos]# getfacl temp | egrep 'user:joao|mask'
user:joao:rwx #effective:r--
mask::r--
A versão gráfica da operação:
A ACL de usuário
joao, continua sendo
rwx, entretanto, a máscara reduz suas permissões reais para
r--.
Para excluir ACLs, utilize a opção
-x da ferramenta
setfacl.

Exemplo:
[root@localhost:/arquivos]# setfacl -x user:joao,user:maria,mask:: temp
[root@localhost:/arquivos]# getfacl temp
# file: temp
# owner: root
# group: root
user::rw-
group::r-x
other::r-x
Veremos agora como incluir ACLs, sem modificar automaticamente a ACL de máscara, através da opção
-n da ferramenta
setfacl.

Exemplo:
[root@localhost:/arquivos]# setfacl -m user:joao:r-- temp
[root@localhost:/arquivos]# getfacl temp
# file: temp
# owner: root
# group: root
user::rw-
user:joao:r--
group::r-x
mask::r-x
other::r-x
Note que a ACL de máscara foi setada conforme o valor da ACL do grupo, que é a mais permissiva (excluindo-se a ACL do dono e ACL dos outros usuários). Agora utilizaremos a opção
-n.
[root@localhost:/arquivos]# setfacl -n -m user:maria:rwx temp
[root@localhost:/arquivos]# getfacl temp
# file: temp
# owner: root
# group: root
user::rw-
user:joao:r--
user:maria:rwx #effective:r-x
group::r-x
mask::r-x
other::r-x
Mapeamento de ACLs de máscara
Ao criarmos ACLs extendidas, as permissões de grupos UNIX passam a ser mapeadas para a ACL de máscara. A razão para tal é o aumento de compatibilidade com programas que não entendem ACLs, e utilizam as permissões tradicionais UNIX.
Imagine que ao diminui as permissões do grupo de um objeto, sua intenção é limitar acesso aos usuários que não são donos e aos demais usuários. Ao mapear a permissão de grupo para a ACL de máscara, este efeito é atingido, mesmo que o objeto possua inúmeras ACLs de usuários e de grupos.

Um exemplo:
[root@localhost:/arquivos]# chmod g-rwx temp
[root@localhost:/arquivos]# ls -ld temp
drw----r-x+ 3 root root 1024 Aug 28 05:53 temp
[root@localhost:/arquivos]# getfacl temp
# file: temp
# owner: root
# group: root
user::rw-
user:joao:r-- #effective:---
user:maria:rwx #effective:---
group::r-x #effective:---
mask::---
other::r-x
Note que o efeito do comando chmod nas permissões de grupo é respeitada, seu mapeamento é feito para a ACL de máscara, e seu efeito nas permissões efetivas das demais ACLs extendidas.
ACLs Padrões
Em diretórios, podemos usar um recuso conhecido como
ACLs Padrões. Estas geram o seguinte efeito sobre objetos criados:
- Diretórios herdam as ACLs padrões configuradas no diretório imediatamente acima; ou seja, as ACLs padrões de seu diretório pai passa a ser também sua ACL padrão.
- Diretórios herdam as ACLs configuradas como ACLs padrões no diretório imediatamente acima;
- Arquivos herdam as ACLs configuradas como ACLs padrões no diretório imediatamente acima;
No primeiro exemplo, configuraremos uma ACL padrão para o diretório
temp, de maneira que novos objetos criados dentro deste implementarão uma determinada política de controle de acesso. A opção
-d deve ser incluída ao utilizarmos a ferramenta
setfacl para configurar uma ACL como ACL padrão.

Exemplo:
[root@localhost:/arquivos]# setfacl -d -m user:joao:r-- temp
[root@localhost:/arquivos]# getfacl temp
# file: temp
# owner: root
# group: root
user::rw-
user:joao:r--
user:maria:rwx
group::r-x
mask::rwx
other::r-x
default:user::rw-
default:user:joao:r--
default:group::r-x
default:mask::r-x
default:other::r-x
As ACLs de nome precedido por
default: são as ACLs padrões de um diretório. Note que apesar especificarmos apenas uma ACL padrão (para o usuário
joao), outras quatro foram criadas automaticamente. Estas definem as ACLs padrões de usuário, grupo, outros usuários e máscara que serão repassados para novos objetos criados dentro deste diretório.
Faremos agora um segundo teste, criando objetos dentro deste diretório para comprovar o funcionamento das ACLs padrões:

Criaremos um primeiramente um subdiretório:
[root@localhost:/arquivos]# mkdir temp/sub1
[root@localhost:/arquivos]# getfacl temp/sub1
# file: temp/sub1
# owner: root
# group: root
user::rw-
user:joao:r--
group::r-x
mask::r-x
other::r-x
default:user::rw-
default:user:joao:r--
default:group::r-x
default:mask::r-x
default:other::r-x
Note que o diretório herdou
dois conjuntos de ACLs do seu diretório pai:
- As ACL padrões de seu diretório pai passaram a ser suas ACLs
- As ACL padrões de seu diretório pai passaram a ser suas ACLs padrões
A figura abaixo ilustra este processo:

Arquivos herdam as ACLs apenas como ACLs não-padrões:
[root@localhost:/arquivos]# touch temp/arq1
[root@localhost:/arquivos]# getfacl temp/arq1
# file: temp/arq1
# owner: root
# group: root
user::rw-
user:joao:r--
group::r-x #effective:r--
mask::r--
other::r--
Note que a ACL do usuário
joao, bem como as demais, foram herdadas das ACLs padrões do diretório
temp.
Note também que a ACL de grupo teve seu valor efetivo reduzido pela ACL de máscara, que de
r-x passou a ser apenas
r--. A explicação para este fenômeno é a seguinte: As chamadas de sistema do kernel que criam objetos no sistema de arquivos provêem um número com as permissões deste novo objeto. No caso do touch, ele utiliza
666, dando permissão total para usuário, grupo e outros. Em seguida, um dos dois processos seguintes ocorre:
- Caso o diretório pai possua uma ACL padrão, este valor é "fitrado" com o valor da ACL padrão.
- Caso o diretório pai não possua uma ACL padrão, este valor é "fitrado" com o valor da umask atual.

Para remover ACLs padrões, use a opção '-k', por exemplo:
[root@localhost:/arquivos]# setfacl --k -m user:joao:r-- temp
Ordem de checagem das permissões
Ao implementarmos uma política de controle de acesso através das ACLs Posix, é necessário entender o algorítimo usado para determinar a presência ou ausência de permissão de acesso. Esta questão é geralmente resolvida ao examinarmos a ordem que o sistema checa as ACLs.
A ordem usada pelo sistema é:
- ACL do dono (user::)
- ACL de um usuário (por exemplo user:joao:)
- ACL do grupo (group::)
- ACL de um grupo (por exemplo group:gnu:)
- ACL de outros (other::)
Exemplo de utilização
Iremos agora aplicar toda a teoria que aprendemos para solucionar o problema apresentado no início deste material.
Os seguintes passos serão tomados:
- Criação dos grupos
- Criação dos usuários
- Criação dos diretórios de cada grupo
- Configuração das permissões em cada diretório
Criação dos grupos

Utilizaremos o comando
groupadd para a criação dos grupos:
[root@localhost:~]# groupadd marketing
[root@localhost:~]# groupadd comercial
Criação dos usuários

Utilizaremos o comando
useradd para a criação dos usuários. A opção
-G já inclui os usuário em seus respectivos grupos.
[root@localhost:~]# useradd -G marketing jose
[root@localhost:~]# useradd -G marketing maria
[root@localhost:~]# useradd -G marketing joao
[root@localhost:~]# useradd -G comercial fulano
[root@localhost:~]# useradd -G comercial sicrano
[root@localhost:~]# useradd -G comercial beltrano
[root@localhost:~]# useradd -G marketing,comercial mark
Criação dos diretórios de cada grupo

Criaremos agora os diretórios de cada departamento. Um diretório para o
novoprojeto, que será utilizado por todos os membros dos grupos
marketing e
comercial também será criado neste passo.
[root@localhost:~]# mkdir /arquivos/marketing
[root@localhost:~]# chgrp marketing /arquivos/marketing
[root@localhost:~]# mkdir /arquivos/comercial
[root@localhost:~]# chgrp marketing /arquivos/comercial
[root@localhost:~]# mkdir /arquivos/novoprojeto
Configuração das permissões em cada diretório
Agora a parte mais interessante. Usando a ferramenta
setfacl, iremos configurar o diretório
/arquivos/marketing para ter acesso completo aos membros de seu grupo (grupo
marketing, configurado no passo anterior). O mesmo será feito com o diretório
/arquivos/comercial.
[root@localhost:~]# setfacl -m user::rwx,group::rwx,other::--- /arquivos/marketing
[root@localhost:~]# setfacl -m user::rwx,group::rwx,other::--- /arquivos/comercial

Agora, o toque final que demonstra a facilidade da configuração de políticas de controle de acesso com a utilização das ACLs Posix:
[root@localhost:~]# setfacl -m user::rwx,group::rwx,other::--- /arquivos/novoprojeto
[root@localhost:~]# setfacl -m group:marketing:rwx /arquivos/novoprojeto
[root@localhost:~]# setfacl -m group:comercial:rwx /arquivos/novoprojeto
Conclusão
A modernização das ferramentas de controle de acesso de arquivo da plataforma GNU/Linux permite uma administração mais efetiva. Note que serviços importantes como o
Samba provêem acesso transparente a utilização das ACLs Posix, tornando toda a política de controle de acesso efetiva não apenas para usuários GNU/Linux mas também para usuários Windows.