Nesse desenho confundem-se duas permissões distintas: quem pode usar um diretório e quais endereços podem sequer conectar. Escrever uma lista de contas ao lado de uma lista de origens parece um emparelhamento, mas o Samba avalia as duas listas como predicados independentes. Qualquer um que satisfaça ambas é admitido, e isso é uma regra mais ampla do que a maioria dos administradores pretende. A correção é um layout de compartilhamento diferente ou uma camada de política capaz de expressar o par.

O mito: duas listas fazem uma regra

A referência do smb.conf define valid users e hosts allow como dois parâmetros não relacionados, e é ao definir ambos em um mesmo compartilhamento que a confusão começa. Defina valid users = mira, tomas e hosts allow = 10.77.0.21, 10.77.0.22 e quatro combinações são admitidas: Mira de qualquer um dos dois endereços e Tomás de qualquer um dos dois endereços. Nada na configuração liga o primeiro nome ao primeiro endereço, e a ordem em que os nomes aparecem não tem significado. Reordená-los, acrescentar uma segunda linha hosts allow ou colocar um nome por linha não muda nada. O resultado é o produto de duas listas, não um mapeamento entre elas.

O que a maioria quer de fato é mais estreito: Mira só de um endereço e Tomás só de outro. Uma única definição de compartilhamento não tem sintaxe para essa vinculação, e nenhuma ordenação engenhosa a cria. Essa é uma forma de política que o Samba não expressa dentro de um compartilhamento, e é aí que o mito sobrevive.

O que o Samba avalia, e em que ordem

As etapas seguem uma ordem fixa, e errar a ordem produz o diagnóstico errado. Um cliente abre uma conexão; uma verificação global de host é executada se houver uma configurada; a configuração da sessão autentica a conta; em seguida o cliente se conecta a um compartilhamento, onde são aplicados a própria lista de hosts dele, valid users e o ajuste de somente leitura; e só quando um arquivo é aberto decidem as permissões do sistema de arquivos da identidade autenticada. Cada etapa pode recusar a requisição sozinha, e passar por uma não diz nada sobre a próxima. A consequência importante é que a conta já é conhecida quando a lista de hosts do compartilhamento é avaliada, e a lista de hosts continua sem meio de nomear essa conta.

Por isso um compartilhamento não pode vincular um usuário a um endereço: hosts allow e valid users são predicados separados aplicados no mesmo estágio de conexão da árvore, e cada um responde à sua própria pergunta. O predicado de host nunca toma o nome da conta como entrada, então não pode ser escrito por usuário. Só um segundo compartilhamento, ou uma camada de política fora do Samba, pode expressar o par.

Os valores globais importam por causa de como são herdados. Um compartilhamento que omite hosts allow herda o valor global, e um compartilhamento que define o seu usa esse valor no lugar do global, não além dele. Assim, uma lista global ampla amplia os compartilhamentos que nunca definem o parâmetro e não faz nada a um compartilhamento que define o seu. Execute testparm -s e leia os valores por compartilhamento que ele imprime, porque essa saída é a política efetiva e o arquivo no disco não é.

Restringir um compartilhamento também não faz nada pelo resto do servidor. Os demais compartilhamentos, as filas de impressão e a conexão IPC mantêm suas próprias regras, então um desenho que se apoia na lista de endereços de um só compartilhamento protege um caminho e não o host.

Dois nomes de compartilhamento sobre um diretório

Quando o mesmo diretório precisa ser alcançável por duas pessoas a partir de dois endereços, exponha-o duas vezes com nomes diferentes. Cada bloco carrega uma conta e uma origem, o que transforma o par em algo que a configuração pode impor. O custo é que cada pessoa usa um nome de compartilhamento diferente para alcançar os mesmos arquivos, e isso precisa ser uma mudança deliberada no lado do cliente.

[shared-mira]
    path = /srv/shared
    guest ok = no
    read only = yes
    valid users = mira
    hosts allow = 10.77.0.21
    hosts deny = ALL

[shared-tomas]
    path = /srv/shared
    guest ok = no
    read only = yes
    valid users = tomas
    hosts allow = 10.77.0.22
    hosts deny = ALL

Um portão de compartilhamento não é uma permissão do sistema de arquivos. As duas identidades ainda precisam de acesso ao diretório pela ACL subjacente, e o ajuste de somente leitura é uma segunda camada e não a única. Conceda acesso de escrita apenas se o fluxo de trabalho exigir, e depois verifique se os arquivos criados por uma identidade continuam utilizáveis pela outra.

Os dois blocos apontam para um único caminho, então uma mudança no diretório afeta os dois compartilhamentos. Normalmente é esse o objetivo, mas também significa que um erro de permissões fica visível para os dois usuários ao mesmo tempo.

O que o endereço de origem pode provar

O endereço que o Samba vê é o endereço que chegou ao servidor, não o que o cliente pensa ter. Um gateway VPN que traduz cada cliente para um único endereço de origem elimina a distinção: todos os clientes chegam como o mesmo host e a lista de origens já não consegue distingui-los. Alocação estável por cliente e um gateway que preserve a origem são pré-requisitos para usar endereços como política. Sem ambos, a restrição mede o gateway e não o usuário.

Mesmo assim, um endereço não é um dispositivo. Dois notebooks atrás de um endereço de túnel, uma concessão reatribuída e uma estação de trabalho compartilhada desmentem a suposição de que uma origem identifica uma pessoa. Trate a restrição como âmbito de rede e mantenha as contas SMB autenticadas como a camada de identidade, com uma credencial de dispositivo como um certificado se precisar de autorização de dispositivo.

É também por isso que o desenho fecha compartilhamentos e não o servidor. Um par recusado ainda pode abrir uma sessão, alcançar outro compartilhamento ou listar o servidor, o que é um resultado diferente de uma falha de autenticação na conexão. Se o requisito é a recusa antes da autenticação, os parâmetros de compartilhamento do Samba são a ferramenta errada.

Prove com pares cruzados

Valide a configuração e depois teste as quatro combinações com conexões novas em vez de uma sessão reutilizada. O par pretendido deve alcançar o diretório, e os dois pares cruzados devem falhar. Uma sessão em cache de um teste anterior responderá de bom grado pela combinação errada e fará uma regra quebrada parecer correta.

testparm -s
smbclient //fileserver/shared-mira -U mira -c 'ls'
smbclient //fileserver/shared-tomas -U tomas -c 'ls'
smbstatus --shares

Uma verificação de sintaxe só prova que o arquivo é analisado. Credenciais, ACLs e a decisão de host são exercitadas por uma conexão real, então execute o comando do cliente a partir do endereço que você quer testar e observe qual etapa o recusa. Se um par cruzado tiver sucesso, a lista efetiva de hosts é mais ampla do que o bloco sugere, e testparm -s é a primeira coisa a ler. Se um par cruzado falhar pelo motivo errado, a conta ou a ACL são os suspeitos.

Monitorar sessões com smbstatus e encerrá-las é uma ação de resposta depois do início do acesso, não um controle de admissão. Bloquear um endereço inteiro observado também pode desconectar usuários não relacionados atrás do mesmo NAT, e por isso a decisão pertence à definição do compartilhamento e o monitoramento ao processo de resposta. Mantenha os dois separados e o desenho continua honesto sobre o que impõe.

Artigos relacionados