Autenticação de chave SSH usando LDAP

59

Em resumo:

Gostaria de uma maneira de fazer autenticação de chave SSH via LDAP.

Problema:

Usamos LDAP (slapd) para serviços de diretório e recentemente passamos a usar nossa própria AMI para criar instâncias. A razão pela qual o bit AMI é importante é que, idealmente , gostaríamos de poder fazer login com SSH via autenticação de chave assim que a instância estiver em execução e não precisar esperar que nossa ferramenta de gerenciamento de configuração um tanto lenta inicie um script para adicionar as chaves corretas para a instância.

O cenário ideal é que, ao adicionar um usuário ao LDAP, também adicionemos sua chave e eles possam efetuar login imediatamente.

Autenticação de chave é uma obrigação , porque o login baseado em senha é tanto menos seguro e incômodo.

Eu li esta pergunta que sugere que há um patch para o OpenSSH chamado OpenSSH-lpk para fazer isso, mas isso não é mais necessário com o servidor OpenSSH> = 6.2

Adicionada uma opção sshd_config (5) AuthorizedKeysCommand para oferecer suporte à busca de chaves_computadas de um comando, além de (ou em vez de) do sistema de arquivos. O comando é executado em uma conta especificada por uma opção AuthorizedKeysCommandUser sshd_config (5)

Como posso configurar o OpenSSH e o LDAP para implementar isso?

c4urself
fonte

Respostas:

64

Atualize o LDAP para incluir o esquema OpenSSH-LPK

Primeiro, precisamos atualizar o LDAP com um esquema para adicionar o sshPublicKeyatributo para os usuários:

dn: cn=openssh-lpk,cn=schema,cn=config
objectClass: olcSchemaConfig
cn: openssh-lpk
olcAttributeTypes: ( 1.3.6.1.4.1.24552.500.1.1.1.13 NAME 'sshPublicKey'
    DESC 'MANDATORY: OpenSSH Public key'
    EQUALITY octetStringMatch
    SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )
olcObjectClasses: ( 1.3.6.1.4.1.24552.500.1.1.2.0 NAME 'ldapPublicKey' SUP top AUXILIARY
    DESC 'MANDATORY: OpenSSH LPK objectclass'
    MAY ( sshPublicKey $ uid )
    )

Crie um script que consulte o LDAP para obter a chave pública de um usuário:

O script deve gerar as chaves públicas para esse usuário, por exemplo:

ldapsearch '(&(objectClass=posixAccount)(uid='"$1"'))' 'sshPublicKey' | sed -n '/^ /{H;d};/sshPublicKey:/x;$g;s/\n *//g;s/sshPublicKey: //gp'

Atualize sshd_configpara apontar para o script da etapa anterior

  • AuthorizedKeysCommand /path/to/script
  • AuthorizedKeysCommandUser nobody

Bônus : atualização sshd_configpara permitir autenticação de senha de redes RFC1918 internas, como visto nesta pergunta:

Permitir apenas autenticação de senha no servidor SSH da rede interna

Links Úteis:

EDIT: Usuário adicionado nobodycomo sugerido TRS-80

c4urself
fonte
6
Isso é fantástico, embora eu sugira em AuthorizedKeysCommandUser nobodyvez de fazer root.
TRS-80
Deve haver algo diferente em meu ldapsearch ou sed, porque canalizar a saída para o comando sed black magic que você possui não me fornece saída, mesmo que meu comando ldapsearch esteja retornando dados. Vou precisar escrever um script para limpar a saída em vez de usar o sed.
Chris L
11
Desconsidere meu comentário anterior. Meu problema foi causado por ter uma nova linha à direita na propriedade sshPublicKey, que por sua vez faz com que o ldapsearch base64 codifique a coisa toda. I simplificou o tho comando sed:ldapsearch -u -LLL -o ldif-wrap=no '(&(objectClass=posixAccount)(uid='"$1"'))' 'sshPublicKey' | sed -n 's/^[ \t]*sshPublicKey:[ \t]*\(.*\)/\1/p'
Chris L
11
@ Chris magia de fato menos preto, mas sed ainda é um, a função hash 1-way, uma vez write-;)
Froyke
11
Na minha versão do OpenSSH (5.3p1-122.el6) existe AuthorizedKeysCommandRunAse nãoAuthorizedKeysCommandUser
mveroone
5

Para quem está recebendo o erro ao executar o ldapsearch:

sed: 1: "/^ /{H;d};": extra characters at the end of d command

como eu estava (no FreeBSD), a correção é mudar o primeiro comando sed para:

/^ /{H;d;};

(adicionando um ponto e vírgula após o 'd').

Scott
fonte
4

Só queria compartilhar meu "método", meu lado do cliente é específico do Debian / Ubuntu, mas o meu lado do servidor é basicamente o mesmo que acima, mas com um pouco mais de "HowTo:"

Servidor :

Ativar atributo de chave pública:

Crédito:

https://blog.shichao.io/2015/04/17/setup_openldap_server_with_openssh_lpk_on_ubuntu.html

cat << EOL >~/openssh-lpk.ldif
dn: cn=openssh-lpk,cn=schema,cn=config
objectClass: olcSchemaConfig
cn: openssh-lpk
olcAttributeTypes: ( 1.3.6.1.4.1.24552.500.1.1.1.13 NAME 'sshPublicKey'
  DESC 'MANDATORY: OpenSSH Public key'
  EQUALITY octetStringMatch
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )
olcObjectClasses: ( 1.3.6.1.4.1.24552.500.1.1.2.0 NAME 'ldapPublicKey' SUP top AUXILIARY
  DESC 'MANDATORY: OpenSSH LPK objectclass'
  MAY ( sshPublicKey $ uid )
  )
EOL

Agora use isso para adicionar ldif:

ldapadd -Y EXTERNAL -H ldapi:/// -f ~/openssh-lpk.ldif

Adicionando um usuário com chave pública SSH no phpLDAPadmin

Primeiro, crie um usuário com o modelo "Genérico: conta de usuário". Em seguida, vá para a seção de atributo "objectClass", clique em "adicionar valor" e escolha o atributo "ldapPublicKey". Após o envio, volte para a página de edição do usuário, clique em "Adicionar novo atributo" na parte superior e escolha "sshPublicKey", cole a chave pública na área de texto e, finalmente, clique em "Atualizar Objeto". "

O atributo sshPublicKey não está sendo exibido - autenticação de chave SSH OpenLDAP PHPLDAP

Cliente Ubuntu:

apt-get -y install python-pip python-ldap
pip install ssh-ldap-pubkey
sh -c 'echo "AuthorizedKeysCommand /usr/local/bin/ssh-ldap-pubkey-wrapper\nAuthorizedKeysCommandUser nobody" >> /etc/ssh/sshd_config' && service ssh restart

Crie chaves de teste:

ssh-keygen -t rsa
FreeSoftwareServers
fonte
3

Esta não é uma resposta completa, apenas uma adição à resposta de c4urself . Eu teria adicionado isso como um comentário, mas não tenho reputação suficiente para comentar, portanto, não faça voto negativo!

Este é o script que estou usando para AuthorizedKeysCommand(com base na versão do c4urself). Funciona independentemente de o valor ser retornado na codificação base64 ou não. Isso pode ser especialmente útil se você deseja armazenar várias chaves autorizadas no LDAP - basta separar as chaves com caracteres de nova linha, semelhantes ao arquivo allowed_keys.

#!/bin/bash
set -eou pipefail
IFS=$'\n\t'

result=$(ldapsearch '(&(objectClass=posixAccount)(uid='"$1"'))' 'sshPublicKey')
attrLine=$(echo "$result" | sed -n '/^ /{H;d};/sshPublicKey:/x;$g;s/\n *//g;/sshPublicKey:/p')

if [[ "$attrLine" == sshPublicKey::* ]]; then
  echo "$attrLine" | sed 's/sshPublicKey:: //' | base64 -d
elif [[ "$attrLine" == sshPublicKey:* ]]; then
  echo "$attrLine" | sed 's/sshPublicKey: //'
else
  exit 1
fi
mbrgm
fonte