Estou tentando implementar a autenticação de dois fatores para OpenSSH. O ambiente é Centos 7 (kernel: 3.10.0-229.1.2.el7.x86_64) com OpenSSH_6.6.1p1, OpenSSL 1.0.1e-fips 11 de fevereiro de 2013. Temos Active Directory (LDAP) + Kerberos implantados. A especificação é a seguinte:
- Um usuário com um ticket Kerberos válido e existente deve ser solicitado apenas para o segundo fator
- Um usuário sem um ticket Kerberos válido e existente deve ser solicitado a fornecer sua senha e um segundo fator
- Os usuários locais (sem conta LDAP) devem ser capazes de se autenticar com suas senhas locais
- O segundo fator não deve ser oferecido antes do primeiro
- Além do Kerberos, a autenticação de chave pública também deve ser aceita como primeiro fator, se disponível
- O recurso deve ser limitado a um conjunto de usuários - outros apenas podem entrar com suas senhas
Para realizar o processo de autenticação do segundo fator, está disponível um módulo PAM de terceiros que nada sabe sobre Kerberos. Então aqui está o que eu fiz:
Coloque estas linhas em /etc/ssh/sshd_config:
# To enable PAM - this will make sshd use PAM with configuration /etc/pam.d/sshd
UsePam yes
ChallengeResponseAuthentication yes
# To enable Kerberos and public key authentication - it will let sshd use existing Kerberos tickets
GSSAPIAuthentication yes
# Enable public key authentication
PubkeyAuthentication yes
# Password validation should be done via the KDC
PasswordAuthentication yes
KerberosAuthentication yes
KerberosOrLocalPasswd yes
# Kerberos / Public Key + PAM
AuthenticationMethods gssapi-with-mic,keyboard-interactive:pam publickey,keyboard-interactive:pam password,keyboard-interactive:pam
# (only supported for OpenSSH 6.2 or higher)
A seção de autenticação da configuração do PAM para sshd (/etc/pam.d/sshd)
auth [success=ignore default=1] pam_localuser.so
auth substack password-auth
auth [success=1 default=ignore] pam_localuser.so
auth required pam_2fa.so [...some arguments...]
auth include postlogin
O módulo pam_2fa.so é responsável por solicitar e validar o segundo fator.
Agora, para Kerberos, isso faz quase tudo que eu queria alcançar. No entanto, para contas locais, isso resulta em duas solicitações de senha subsequentes. Este é o meu principal problema aqui. Isso ocorre porque neste caso o caminho "password,keyboard-interactive:pam" é usado, conforme o esperado. (Eu preciso deste caminho de autenticação para que alguém com uma conta Kerberos, mas sem um ticket válido, possa obter um ticket digitando a senha e depois o OTP.) Se eu remover completamente a subpilha de autenticação de senha da configuração do PAM, as contas Kerberos permanecerão funcionando e as contas locais continuam sem funcionar. Para mim, parece que a instrução KerberosOrLocalPasswd yes foi ignorada, porque UsePAM yes também está presente. No entanto, o sshd continua usando o KDC para validação de senha, caso contrário também não funcionaria para contas LDAP.
Então, novamente, para esclarecer melhor o que desejo implementar aqui é o pseudocódigo que descreve a lógica de autenticação desejada:
if gssapi_auth_ok(principal) or pubkey_auth_ok(pubkey):
return second_factor_auth(user, read_otp())
else:
if is_local_account(user):
if local_passwd_auth(user, read_password()):
return second_factor_auth(user, read_otp())
else:
return AUTH_ERR
else:
if krb5_auth(principal, read_password()):
return second_factor_auth(user, read_otp())
return AUTH_ERR
Portanto, acho que meu cenário não é muito complexo ou ambicioso, mas ainda não consegui encontrar uma maneira clara de implementá-lo, apesar de ter passado dias pesquisando e experimentando. Você poderia me ajudar a encontrar uma solução?
Muito obrigado antecipadamente!
Responder1
Não conheço nenhuma maneira de fazer o que você deseja com o PAM sem escrever um novo módulo pam. O PAM é relativamente complexo e a maneira como o sshd interage com o PAM e o Kerberos tem sido, em minha experiência, tal que sempre há um caso extremo que simplesmente não funciona.
O que você quer pode ser possível, só não sei como fazer. Se você só precisa proteger o ssh, o que eu sugiro é usar
ForceCommand /path/to/2fa_executable
no seu sshd_config. Isso permitiria que você implementasse a lógica desejada, a desvantagem é que o 2fa_executable precisa ser configurado para ler quaisquer segredos 2fa.
Há um exemplo e código no site Duo Security. Você pode usar o wrapper duo setuid e qualquer código 2fa que estiver usando.
Responder2
- Um usuário com um ticket Kerberos válido e existente deve ser solicitado apenas para o segundo fator.
Isso não pode ser alcançado através do PAM.
A autenticação baseada em chave bem-sucedida executada em sshd ignora a auth
pilha de PAM. Isso inclui GSSAPI, que é um requisito para autenticação Kerberos baseada em tickets. Ele não tem escolha a não ser fazer isso, pois o PAM simplesmente não foi projetado com esse tipo de autenticação em mente.
A configuração UsePAM yes
faz o seguinte:
ChallengeResponseAuthentication
ePasswordAuthentication
conectará aauth
pilha do PAM para validar a senha. Qualquer forma de autenticação diferente destes dois métodosnãotoque naauth
pilha.- Na autenticação bem-sucedida, a
account
pilha do PAM será chamada para determinar se o usuário autenticado tem permissão de acesso. (sempre) - A
session
pilha do PAM será chamada para lidar com tarefas de configuração de sessão.
Resumo: Não há absolutamente nenhuma maneira de fazer com que um prompt de autenticação de dois fatores localizado na auth
pilha seja acionado para alguém que se autenticou com uma chave GSSAPI ou ssh. Você pode usar account
e session
empilhar em conjunto com esses métodos de autenticação, mas isso é tudo que o PAM irá fazer.
Responder3
Aqui está uma explicação de como fazer issohttps://cern-cert.github.io/pam_2fa/
- A base: autenticação de 2 fatores com pam
Um módulo pam que entende mais sobre os métodos de autenticação ssh:
auth [sucesso=2 ignorar=ignorar padrão=morrer] pam_ssh_user_auth.so
OpenSSH recente ou corrigido para expor isso ao pam
Métodos de autenticação gssapi-com-mic, teclado interativo: pam chave pública, teclado interativo: pam teclado interativo: pam