ProtectHome contra uma semente TOTP: por que o login VPN falha
Um código correto não ajuda um módulo PAM que não consegue abrir a semente. Escolha entre um drop-in e um caminho de estado gravável, e depois verifique a unidade.
O autenticador mostra um novo código de seis dígitos, a VPN o rejeita, e o mesmo código é verificado sem problemas quando você o testa no seu próprio shell. Essa diferença é toda a história. Um módulo PAM que não consegue abrir o segredo de registro retorna uma falha que parece idêntica a um código errado, e o ambiente do serviço que oculta os diretórios pessoais é uma causa comum. Antes de relaxar qualquer permissão, decida em qual das três situações você está.
Qual dos três problemas é este?
O primeiro é um segredo que o módulo não consegue ler de forma alguma. O segundo é um segredo que ele consegue ler mas não atualizar. O terceiro é um código que realmente está errado, normalmente por desvio do relógio ou um valor reutilizado.
Separe-os lendo o diário do serviço e o registro de autenticação do sistema para uma tentativa falha, e então confirme qual serviço PAM o plug-in carrega e qual linha de módulo esse serviço usa. Uma mensagem genérica de falha de autenticação não os distingue, e um teste manual bem-sucedido também não, porque seu shell não é o ambiente do serviço.
A visão do sistema de arquivos da unidade é o culpado habitual quando somente o serviço falha.
systemctl show -p ProtectHome -p ProtectSystem -p ReadWritePaths [email protected]
ls -l /var/lib/vpn-otp/*/.google_authenticator 2>/dev/null | head -n 20Opção A: retirar o segredo do diretório pessoal
Quando o serviço oculta /home e você prefere manter essa proteção, armazene o segredo onde ele possa vê-lo. O módulo aceita um caminho secret= e uma conta user= que executa as operações de arquivo, o que permite a um armazenamento central atender muitas identidades.
Esta é a opção organizada, e é a que exige mais cuidado, porque um armazenamento compartilhado faz de um único diretório a fronteira de segurança de cada conta.
auth required pam_google_authenticator.so secret=/var/lib/vpn-otp/${USER}/.google_authenticator user=vpn-otpVerifique três coisas antes de confiar nele: a conta existe, o processo de trabalho do módulo consegue mudar para ela, e os arquivos pertencem a ela com modos restritivos. Não use ~ nem um caminho com variável pessoal junto com user=, e não desative as verificações de propriedade do módulo para fazer um caminho funcionar. Mantenha o estágio da senha e o restante da pilha intactos.
Opção B: deixar o arquivo e abrir um caminho
Se o segredo deve permanecer no diretório pessoal do usuário, a unidade precisa de uma visão que inclua esse único diretório sem expor todos os diretórios pessoais no host. Um drop-in pode adicionar uma montagem de ligação bem restrita sob um diretório pessoal isolado.
Isso mantém a propriedade por usuário como modelo, ao custo de uma alteração na unidade que deve ser revisada sempre que o ambiente isolado mudar.
Dois limites são fáceis de esquecer. Um caminho somente leitura adicionado sob um diretório que o ambiente isolado oculta não o expõe, porque o pai simplesmente não está lá. E a montagem precisa ser gravável se o módulo tiver de atualizar o estado, o que traz a próxima opção. Escreva o drop-in como um arquivo separado em vez de editar a unidade empacotada em /usr/lib, para que uma atualização do pacote não o desfaça silenciosamente.
Opção C: manter o ambiente isolado e corrigir as gravações de estado
Ler o segredo é apenas metade da autenticação. O módulo pode reescrever informações de desvio de tempo, proteção contra repetição ou um contador, e um arquivo que passa na verificação de leitura ainda pode falhar na gravação.
Essa falha parece um código errado na próxima tentativa e não nesta, por isso é confundida com desvio do relógio.
Dê a ele um diretório gravável próprio e aponte o caminho do segredo para lá, em vez de tornar gravável todo o diretório pessoal. Confirme o proprietário do diretório, o espaço livre do sistema de arquivos e se a unidade restringe gravações em outros lugares. Depois teste dois logins consecutivos, porque o segundo comprova o caminho de gravação e o primeiro apenas a leitura.
Verifique como o serviço, não como você mesmo
Toda verificação que importa deve ser executada dentro do ambiente isolado da unidade com a identidade da unidade.
Um comando que tem sucesso como root informa que o arquivo existe e nada mais. Um login pelo serviço real informa se o módulo consegue ler o segredo, usá-lo e gravar de volta o que precisa.
Por fim, mantenha o requisito intacto. Adicionar uma opção de senha nula, aceitar falhas de somente leitura ou remover o ambiente isolado fariam o sintoma desaparecer mudando a política. Um usuário obrigado a apresentar um código ainda deve ser rejeitado quando o segredo está inacessível.