Аутентифікація ключа SSH за допомогою LDAP


59

Коротко:

Хочеться зробити аутентифікацію ключа SSH через LDAP.

Проблема:

Ми використовуємо LDAP (slapd) для служб каталогів, і нещодавно ми перейшли до використання власного AMI для створення екземплярів. Причина, що важливий біт AMI, полягає в тому, що в ідеалі ми хотіли б мати можливість увійти з SSH за допомогою аутентифікації ключів, як тільки запущений екземпляр, і не доведеться чекати, коли наш дещо повільний інструмент управління конфігурацією відкриє сценарій для додавання правильні ключі до екземпляра.

Ідеальний сценарій полягає в тому, що, додаючи користувача до LDAP, ми також додаємо їх ключ, і вони одразу зможуть увійти.

Аутентифікація ключа є обов'язковою, оскільки вхід на основі пароля є менш захищеним і набридливим.

Я читав це запитання, яке говорить про те, що для цього потрібен патч для OpenSSH під назвою OpenSSH-lpk, але це більше не потрібно для сервера OpenSSH> = 6.2

Додано опцію sshd_config (5) AuthorizedKeysCommand для підтримки вилучення дозволених_кількостей з команди на додаток до (або замість) з файлової системи. Команда виконується під обліковим записом, визначеним параметром AuthorizedKeysCommandUser sshd_config (5)

Як я можу налаштувати OpenSSH та LDAP для цього?

Відповіді:


64

Оновіть LDAP, щоб включити схему OpenSSH-LPK

Спочатку нам потрібно оновити LDAP за допомогою схеми, щоб додати sshPublicKeyатрибут для користувачів:

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 )
    )

Створіть сценарій, який запитує LDAP для відкритого ключа користувача:

Сценарій повинен виводити відкриті ключі для цього користувача, наприклад:

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

Оновіть, sshd_configщоб вказати на сценарій з попереднього кроку

  • AuthorizedKeysCommand /path/to/script
  • AuthorizedKeysCommandUser nobody

Бонус : оновлення, sshd_configщоб дозволити автентифікацію пароля з внутрішніх мереж RFC1918, як це зазначено в цьому питанні:

Дозволити автентифікацію пароля на SSH-сервері з внутрішньої мережі

Корисні посилання:

EDIT: Додано користувача, nobodyяк пропонується TRS-80


6
Це фантастично, хоча я б запропонував AuthorizedKeysCommandUser nobodyзамість кореня.
TRS-80

Щодо мого ldapsearch або sed має бути щось інше, тому що підключення виводу до команди black black magic, яка у вас є, не дає мені виводу, навіть якщо моя звичайна команда ldapsearch повертає дані. Мені доведеться написати сценарій, щоб очистити вихід, а не використовувати sed.
Кріс Л

1
Ігноруйте мій попередній коментар. Моя проблема була викликана тим, що у властивості sshPublicKey є зворотний новий рядок, що, в свою чергу, змушує ldapsearch до base64 кодувати всю справу. Я спростив команду sed тому:ldapsearch -u -LLL -o ldif-wrap=no '(&(objectClass=posixAccount)(uid='"$1"'))' 'sshPublicKey' | sed -n 's/^[ \t]*sshPublicKey:[ \t]*\(.*\)/\1/p'
Кріс Л,

1
@Chris справді менш чорна магія, але sed - це все-таки функція хешування одноразового запису;)
Froyke

1
У моїй версії OpenSSH (5.3p1-122.el6) є AuthorizedKeysCommandRunAsі немаєAuthorizedKeysCommandUser
mveroone

5

Для всіх, хто отримує помилку під час запуску ldapsearch:

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

як я був (на FreeBSD), виправлення полягає в тому, щоб змінити першу команду sed на:

/^ /{H;d;};

(додавання крапки з комою після 'd').


4

Просто хотів поділитися своїм "методом", моя клієнтська сторона - Debian / Ubuntu Specific, але моя сторона сервера в основному така ж, як і вище, але з трохи більше "HowTo:"

Сервер:

Увімкнути атрибут відкритого ключа:

Кредит:

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

Тепер використовуйте це, щоб додати ldif:

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

Додавання користувача з відкритим ключем SSH у phpLDAPadmin

Спочатку створіть користувача за допомогою шаблону «Загальний: обліковий запис користувача». Потім перейдіть до розділу атрибута «objectClass», натисніть «додати значення» та виберіть атрибут «ldapPublicKey». Після подання, поверніться на сторінку редагування користувача, натисніть "Додати новий атрибут" у верхній частині та виберіть "sshPublicKey", вставте відкритий ключ у текстову область та нарешті натисніть "Оновити об'єкт". "

Атрибут sshPublicKey не відображається - OpenLDAP PHPLDAP SSH Key Auth

Клієнт 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

Створіть тестові ключі:

ssh-keygen -t rsa

3

Це не повна відповідь, а лише доповнення відповіді c4urself . Я б додав це як коментар, але я не маю достатньої репутації для коментарів, тому, будь ласка, не зволікайте!

Це сценарій, який я використовую для AuthorizedKeysCommand(на основі версії c4urself). Він працює незалежно від того, повертається значення в кодування base64 чи ні. Це може бути особливо корисно, якщо ви хочете зберегти кілька дозволених ключів у LDAP - просто розділіть ключі з символами нового рядка, подібно до файлу санкціонованих_кісів.

#!/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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.