水底

ScalaとかC#とかk8sとか

LDAPにSSHの認証をやらせてみた(nscd版)

LDAPRadius無線LANLinuxユーザとSSHの認証まとめたろw」と思ったのが発端. とりあえずLDAPSSHの公開鍵認証は動くようになった. まとまった情報があまり見つからなかったのでメモ.

概要

実験環境

  • (VM上の)Ubuntu16.04
  • dockerやssh環境を前提とする

どこまでやるの

docker上に公開鍵の情報を含むLDAPサーバを作成し, SSHの認証でそれを参照させる. 既存LinuxユーザとLDAP上のユーザを共存させ, 初ログインのLDAPユーザには自動的にホームディレクトリを作成する.

LDAPサーバ

LDAPサーバのdockerコンテナを建てる

docker run --name ldap-server -p 389:389 --env LDAP_ORGANISATION="Example" --env LDAP_DOMAIN="example.com" --env LDAP_ADMIN_PASSWORD="password" -d osixia/openldap:1.1.2

公開鍵に対応したスキーマの設定

dockerコンテナ内. 本来ビルド時でいいが, とりあえずdocker execで.

echo "dn: cn=openssh-lpk-openldap,cn=schema,cn=config
objectClass: olcSchemaConfig
cn: openssh-lpk-openldap
olcAttributeTypes: ( 1.3.6.1.4.1.24552.500.1.1.1.13 NAME 'sshPublicKey' DES
 C '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' DESC
  'MANDATORY: OpenSSH LPK objectclass' SUP top AUXILIARY MUST ( sshPublicKey $
  uid ) )" > /etc/ldap/schema/openssh-lpk-openldap.ldif

ldapadd -H ldapi:/// -f /etc/ldap/schema/openssh-lpk-openldap.ldif
ldapadd -H ldapi:/// -f /etc/ldap/schema/cosine.ldif
ldapadd -H ldapi:/// -f /etc/ldap/schema/inetorgperson.ldif
ldapadd -H ldapi:/// -f /etc/ldap/schema/nis.ldif

ldifファイルを作って公開鍵の情報を持ったユーザ追加(or ldapmodで既存ユーザに追加する)

dn: uid=karen,dc=example,dc=com
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: ldapPublicKey
uid: karen
cn: karen
sn: kujo
gn: karen
uidNumber: 11111
gidNumber: 11111
loginShell: /bin/bash
homeDirectory: /home/karen
mail: karen@example.com
userPassword: password
sshPublicKey: ssh-rsa AAAA略 #コメントは消しておいたほうがいいかも
ldapadd -H ldapi:/// -f karen.ldif

LDAPクライアント(SSH)

yumを使うディストロであればopenssh-ldapというパッケージがあるため, この項目と手法が異るので注意

LDAPクライアントに必要な物をインストールし有効にする

sudo apt install -y nscd ldap-auth-client #インストール時にLDAPサーバの情報を入力
sudo pam-auth-update #LDAPとCreate home directoryを有効にする

再設定は sudo dpkg-reconfigure ldap-auth-config で可能.

pam-auth-update時にCreate home directoryが出てこなかった場合

バージョンによってはデフォルトで用意されていないようなので自作する必要がある(e.g. ubuntu14.04)

新規作成 /usr/share/pam-configs/my_mkhomedir

Name: Create home directory on login
Default: yes
Priority: 0
Session-Type: Additional
Session-Interactive-Only: yes
Session:
    optional            pam_mkhomedir.so

sudo pam-auth-update --force

nsswitchの設定

/etc/nsswitch.confに以下のようにldap追記する.

passwd:    files ldap
shadow:    files ldap
group:    files ldap
sudo serivce nscd restart

SSHの認証にLDAP上の公開鍵を利用する設定

LDAP上の公開鍵を取得するスクリプトを作成(/opt/ssh-ldap/getPublicKey)

LDAPサーバの情報を設定する.

#!/bin/bash

uri=ldap://piyo #server uri
binddn=piyo #bind user
bindpw=piyo #pwd
base=piyo #base
uid=$1
ldapsearch -LLL -H ${uri} -w "${bindpw}" -D "${binddn}" -b "${base}" "(& (objectClass=posixAccount) (uid=${uid}))" "sshPublicKey" | sed -ne '2,$p' | sed -e 's/sshPublicKey: //g' | sed -e 's/^ //g' | tr -d '\n'

ユーザから不可視にする.

sudo chmod 700 -R /opt/ssh-ldap
sudo chown root:root -R /opt/ssh-ldap

SSHの設定(/etc/ssh/sshd_config)

以下を追記する.

AuthorizedKeysCommand /opt/ssh-ldap/getPublicKey
AuthorizedKeysCommandUser root
sudo service ssh reload

注意点

  • SSSDを利用する方法もありそちらのほうがよりスマートらしいがnscdと排他的で試していない. 近々実験予定.
  • /etc/ldap/slapd.confを編集して~という情報は古いから今すぐ投げ捨てろ
  • OpenSSH6.9未満(?)の場合はAuthorizedKeysCommandが利用できないためパッチを当てる必要があるらしい(要確認). 少なくとも, Ubuntu16.04で入る7.2では問題なかった.

ところでなんでSSH-CA認証の証明書はX.501じゃないの…