Basicamente, a montagem da unidade de rede se dá através de um comando
mount, de acordo a uma condição de autenticação. Para quem já montou uma pasta compartilhada de um servidor Windows num terminal
GNU/Linux, certamente já utilizou a seguinte sintaxe do comando mount:
# mount -t cifs //FILESERVER/COMPARTILHAMENTO /mnt/PONTO_DE_MONTAGEM -o user=usuário,pass=senha...
Nesta sintaxe, por exemplo, temos sendo especificados:
- O sistema de arquivos cifs;
- O hostname (ou IP) do servidor de arquivos FILESERVER;
- O nome do compartilhamento COMPARTILHAMENTO;
- O diretório na estação onde será montado o compartilhamento /mnt/PONTO_DE_MONTAGEM;
- E as opções (-o) de autenticação e montagem, "usuário" com permissão de acesso ao compartilhamento (definido no servidor), e a respectiva "senha".
Lembrando que quando a senha não é informada na sintaxe, esta é solicitada logo após a confirmação do comando no
bash.
A tag
<volume... />, basicamente, reúne todos esses elementos da sintaxe do comando, porém, a autenticação ocorre de forma automática, sem necessidade de informar a senha do usuário que estará montando o mapeamento.
Isso é possível porque o módulo
pam_mount.so atua no final das pilhas de autenticação (
/etc/pam.d/common-auth), e de sessão (
/etc/pam.d/common-session) do PAM (
Pluggable Authentication Modules), "aproveitando" os "tokens de autenticação" dos módulos anteriores da pilha, como por exemplo,
pam_krb5.so e/ou
pam_winbind.so, para validação do comando de montagem.
Sendo assim, se o usuário que realizar o logon no sistema se encaixar em alguma das "condições de montagem" de alguma das tags
<volume ... /> especificadas no arquivo, o mapeamento será realizado automaticamente.
A seguir, alguns exemplos para entendermos melhor os elementos que compõe essa tag:
Exemplo 1: supondo que numa organização, cada setor ou departamento tenha um diretório exclusivo compartilhado na rede, onde somente os usuários membros do setor específico tenham acesso à respectiva pasta do grupo. Podemos criar então, como exemplo, a seguinte tag:
<volume icase="no" sgrp="DTI" fstype="cifs" server="SRV-FILE" path="DTI$" mountpoint="/home/%(USER)/DTI" options="uid=%(USERUID),gid=%(USERGID),iocharset=utf8,file_mode=0770,dir_mode=0770" />
Entendendo os elementos, temos:
icase=no :: o XML (e o GNU/Linux) é "case sensitive", logo, para que não haja nenhuma confusão para o sistema quanto aos nomes das diversas definições da tag, é recomendado a utilização deste parâmetro com o valor "no" para desconsiderar a propriedade "case sensitive".
sgrg=DTI :: isso significa que, se o usuário pertencer ao grupo DTI, o compartilhamento definido será montado. Ou seja, este elemento é que dará a condição se um determinado compartilhamento será montado, ou não, para o usuário que efetua o logon.
Existem também outras formas de estabelecer essa condição, tais como:
- user :: especifica a nível de usuário. Seu valor pode ser preenchido para o nome de um único usuário específico, ou pelo asterisco (*) que significa qualquer usuário.
- pgrp :: similar ao sgrp, que especifica a nível do grupo ao qual o usuário pertence, porém, este trata-se diretamente do "grupo primário", enquanto o sgrp refere-se a um dos grupos secundários ao qual o usuário possa pertencer, sendo que no domínio, um usuário só pode ter um único grupo primário, e ser membro de diversos grupos secundários simultaneamente. Geralmente por padrão os usuários do AD quando criados são atribuídos ao grupo "usuários do domínio" como grupo primário.
- uid :: especifica o usuário, ou um intervalo de usuários através dos respectivos UID, que nada mais é que o número de identificação do usuário no sistema. Nas configurações do "winbind" dentro do ficheiro /etc/samba/smb.conf, o parâmetro "idmap uid" delimita o range de UIDs que o sistema irá distribuir aos usuários do domínio que se logarem na estação. Esse número pode variar para cada estação Ubuntu da rede a depender da ordem dos usuários que se logarem em cada estação e/ou ordem de criação dos usuários no domínio. Para verificar qual o UID atual do usuário numa determinada estação, basta aplicar em seu terminal o comando id.
- gid :: similar ao UID, sendo que este especifica o id do grupo (ou range) ao qual o usuário pertence. Alinha-se ao parâmetro "idmap gid" do /etc/samba/smb.conf.
fstype=cifs :: especifica o filesystem (sistema de arquivos) referente ao servidor de arquivos. Neste caso, o
cifs, mais comumente usado nas redes de compartilhamentos Windows, mas também suportado pelos servidores Samba.
server=SRV-FILE :: informa o hostname ou IP do servidor que dispõe o compartilhamento desejado.
path=DTI$ :: informa o nome do compartilhamento propriamente dito. Detalhe, é que o cifrão ($) no final do nome é uma característica dos servidores Windows para ocultarem os compartilhamentos na rede. Ou seja, não é obrigatório! É só um exemplo de um compartilhamento com o nome de
DTI$ dentro de um servidor Windows que está oculto ao ambiente de rede, justamente por conta do cifrão no final do nome.
mountpoint=/home/%(USER)/DTI :: Indica onde será montado o compartilhamento, ou seja, o ponto de montagem. Geralmente, como o usuário precisa ter acesso à pasta, esta é montada em alguma pasta dentro do seu diretório
home por questões de permissões de acesso. Portanto, que geralmente é utilizada a variável "%(USER)", que é substituída pelo nome do usuário que está logando, para indicar o seu
home (
/home/%(USER)). Lembrando que os diretórios
home dos usuários do domínio podem não estar exatamente dentro do
/home, isso vai depender de como esteja configurado o parâmetro "template homedir" nas opções do winbind no arquivo
/etc/samba/smb.conf.
Existem outras variáveis de ambiente que podem ser úteis em outros cenários, tais como:
- %(GROUP) :: substituída pelo grupo primário do usuário.
- %(DOMAIN_NAME) :: substituída pelo nome do domínio ao qual o usuário pertence.
- %(USERUID), %(USERGID) :: indicam respectivamente o UID, e o GID principal do usuário.
options=uid=%(USERUID),gid=%(USERGID),iocharset=utf8,file_mode=0770,dir_mode=0770 :: por fim, são estabelecidas de fato as opções de montagem da unidade de rede. Essas opções são variadas, de acordo ao protocolo ou sistema de arquivo utilizado pelo servidor do compartilhamento. No manual do comando
mount (
man mount) é possível ver todas as opções de montagem dentro dos variados protocolos e sistemas de arquivos de ficheiros de rede.
Em nossa tag, não é necessário especificar todas as opções referentes ao
smb/cifs, mas sim as principais, como são utilizadas no exemplo:
uid=%(USERUID) :: o comando
mount, geralmente, só pode ser executado com privilégios de superusuário. Logo após mapeado, as permissões de acesso dos arquivos e subpastas do referente compartilhamento, estarão associadas ao usuário root. Isto é péssimo, principalmente no ponto de vista da auditoria do servidor de arquivo, pois toda e qualquer modificação realizada no compartilhamento será gravada no log do serviço como feito pelo root, não sendo possível identificar exatamente o usuário que de fato a fez.
Sendo assim a especificação do
uid nas opções do comando apontando para variável "%(USERUID)", que terá o seu valor substituído pelo UID do usuário logado, torna-se de suma importância, pois isso garantirá que as manipulações realizadas no diretório mapeado sejam associadas justamente ao usuário logado, e não ao root (quem executa a montagem). Isso garantirá também que as permissões de segurança implementadas ao compartilhamento através do servidor sejam respeitadas.
- gid=%(USERGID) :: seguindo a mesma lógica do uid, porém, a nível de grupo primário do usuário.
- iocharset=utf8 :: grosseiramente, faz com que o mapeamento esteja sob sistema de codificação UTF-8, o que permite a tradução de determinados caracteres em nomes de arquivos e pastas, tais como: ç, ~, etc; bem como arquivos de nomes extensos.
- file_mode=0770 :: define as permissões de acesso dos arquivos no formato octal (ver: man chmod). Estas deverão estar alinhadas as permissões aplicadas no servidor de arquivos.
As permissões mais comuns utilizadas, são:
- 700 :: só o dono (usuário logado) terá permissão total de acesso - compartilhamentos a nível user.
- 770 :: o usuário e o grupo terão permissão total de acesso - compartilhamento a nível pgrp ou sgrp.
- 777 :: permissão total para todos.
- dir_mode=0770 :: define as permissões de acesso dos "DIRETÓRIOS" no formato octal.
* Nota: entende-se como permissão total, o poder de leitura (valor 4), escrita/modificação (valor 2), e execução (valor 1). Os valores somados para cada bit de permissão ativado formam a
umask do arquivo (4+2+1 = 7), sendo que o primeiro número da máscara identifica a permissão do dono do arquivo; o segundo a permissão referente aos demais usuários dos grupos aos quais pertence; e por último as permissões dadas a quaisquer outros usuários. O valor zero, indica nenhuma permissão!
Neste exemplo tivemos então, que todos os membros do grupo DTI (grupo de segurança do domínio no AD), irão mapear o compartilhamento "DTI$", que está sendo disponibilizado pelo servidor "SRV-FILE", dentro do diretório
home do usuário, na pasta
DTI. Lembrando que se a pasta do ponto de montagem especificado não existir, a
tag <mkmountpoint enable=1 ... />, garantirá a criação da pasta para que o ponto seja montado.
É importante observar que a sigla DTI utilizada tanto para o nome do grupo, nome do compartilhamento e o nome da pasta, é somente um exemplo, e não significa que estes elementos tenham que ter a mesma nomenclatura. Isso irá depender do cenário da rede e a forma como os administradores da rede poderão definir.
Então, para podermos assimilar melhor, segue outro exemplo de um mapeamento montado de acordo ao grupo que o usuário pertence:
<volume icase="no" sgrp="DRH" fstype="cifs" server="192.168.1.100" path="RH$" mountpoint="/home/%(USER)/RECURSOS_HUMANOS" options="uid=%(USERUID),gid=%(USERGID),iocharset=utf8,file_mode=0770,dir_mode=0770" />
Neste último exemplo, temos que os usuários do grupo "DRH" irão mapear o compartilhamento "RH$", que fica oculto no servidor cujo IP é
192.168.1.100, em seus diretórios
home, numa pasta chamada "RECURSOS_HUMANOS".
Exemplo 2: neste cenário, gostaria de descrever uma situação que é muito comum em boa parte das organizações, que trata-se do chamado "perfil móvel". Supondo que cada usuário do domínio tenha os arquivos do seu perfil de usuário carregados a partir de um compartilhamento num servidor de arquivos.
Sendo assim, ele poderá ter acesso aos seus arquivos em qualquer estação da rede que se logar. Ainda pensando neste cenário, vamos dizer que os nomes desses compartilhamentos na rede, são exatamente iguais aos nomes dos respectivos usuários. Logo, podemos criar uma única tag
<volume />, que será comum a todos os usuários da seguinte forma:
<volume icase="no" user="*" fstype="cifs" server="192.168.1.100" path="%(USER)" mountpoint="/home/%(USER)/ %(USER)_MÓVEL" options="uid=%(USERUID),gid=%(USERGID),iocharset=utf8,file_mode=0700,dir_mode=0700" />
Percebam que agora, a condição de montagem é definida a nível do usuário (user), onde o asterisco (*) significará "qualquer usuário". A variável
%(USER) substituída pelo nome do usuário, irá indicar que o nome do compartilhamento será igual ao nome do usuário logado (
path=%(USER)), e que será mapeado dentro do seu próprio diretório
home, numa pasta cujo nome será "%(USER)_MÓVEL" (sendo
%(USER), substituído pelo próprio nome do usuário).
Importante também observar as opções de permissão de acesso aos arquivos e pastas do compartilhamento em "file_mode=0700", e "dir_mode=0700", que significa que sendo a pasta exclusiva do usuário, somente o dono (o usuário logado) terá permissão total de acesso, e nem mesmo membros do grupo, nem demais usuários terão qualquer tipo de permissão.
Talvez, alguém possa se perguntar: e por que não montar o compartilhamento no próprio "/home/%(USER)", já que este terá também justamente o mesmo nome do usuário?
Acontece que, quando o mapeamento é montado as propriedades de dono da pasta, são atribuídas ao usuário logado (uid=%(USERUID),gid=%(USERGID)), que por sua vez, não tem permissão de escrever dentro do diretório
/home. Quando o usuário loga-se pela primeira vez no GNU/Linux e o seu perfil de usuário é criado dentro do
/home, o processo do winbind utiliza-se do id do root (0) para poder criar a estrutura de pastas do usuário dentro deste diretório, e em seguida altera as propriedades dos arquivos e pastas para o usuário que está efetuando o logon.
Exemplo 3: por fim, uma última situação também muito comum nos ambientes de rede, que é um compartilhamento público, que pode ser acessado por todos os usuários, independente do grupo de segurança do domínio ao qual seja membro:
<volume icase="no" user="*" fstype="cifs" server="192.168.1.101" path="PUBLICO" mountpoint="/tmp/PUBLICO" options="uid=%(USERUID),gid=%(USERGID),iocharset=utf8,file_mode=0777,dir_mode=0777" />
Neste caso, também é utilizado a condição de montagem a nível do usuário (user), sendo que qualquer usuário que logar-se (representado assim pelo asterisco (*)), irá mapear o compartilhamento "PUBLICO", do servidor
192.168.1.101, na pasta
/tmp/PUBLICO do sistema de arquivos local.
Poderia ter sido utilizado também o
home do usuário, mas preferi usar o
/tmp para mostrar que pode ser também uma opção de ponto de montagem, uma vez que geralmente no sistema de arquivos Linux, este é um diretório com permissão de acesso total para todos os usuários (
drwx-rwx-rwt).
Uma outra observação, é que como foi utilizado o
user="*", indicando que qualquer usuário que se logar poderá mapear o compartilhamento, os usuários locais do sistema também poderão realizar essa operação no logon. Logo, caso deseje-se restringir apenas aos usuários do domínio, é possível utilizar a condição a nível de
uid definindo a range de IDs desses usuários de acordo ao parâmetro "idmap uid" nas configurações do winbind, em
/etc/samba/smb.conf.
A tag então ficaria da seguinte forma:
<volume icase="no" uid="10000-2000000" fstype="cifs" server="192.168.1.101" path="PUBLICO" mountpoint="/tmp/PUBLICO" options="uid=%(USERUID),gid=%(USERGID),iocharset=utf8,file_mode=0777,dir_mode=0777" />
Ou seja, será mapeado para todos os usuários cujo ID esteja dentro do range "10000-2000000".
De acordo ao propósito deste artigo, estas foram as configurações do
pam_mount que nos interessavam.
* Nota: para uma visão mais ampla da solução e todas as suas possibilidades, pode-se acessar o link:
O manual está em inglês, mas o Google Tradutor está aí para isso (fica a dica!).
No entanto, percebemos que o arquivo de configuração do
pam_mount, onde foram definidos os mapeamentos ficam no ficheiro
/etc/security/pam_mount.conf.xml do sistema de arquivos local da estação Ubuntu.
Isto significa que toda essa configuração teria que ser replicada uma a uma, em todas as estações da rede, e toda vez que houvesse uma mudança referente ao esquema de mapeamento, seria necessário alterar esse arquivo em cada máquina novamente. Porém, eu disse "teria", porque é justamente aí onde o CiD entra, com o que podemos chamar de "cereja do bolo".