CentOS7のOpenLDAPでSSH公開鍵認証する

Sat, Dec 5, 2015

OpenLDAP と仲間たち Advent Calendar 2015 5日目。

OpenSSHの公開鍵は通常、ホームディレクトリの下($HOME/.ssh/authorized_keys)に配置してると思いますが、サーバーがー多くなってくると集中管理したいですよね。

OpenSSHはファイルだけでなくLDAPに格納された公開鍵を利用して認証を行うこともできます。

CentOS6の古いOpenLDAPはopenssh-ldapパッケージをインストールし、スキーマをincludeするだけで良かったのですが、CentOS/RHEL7系のOpenLDAPはcn=configデータベースを利用するようになったため、少々面倒になりました。

ここではCentOS7/RHEL7で、SSH公開鍵をOpenLDAPに投入して認証する方法を解説します。

OpenLDAPのインストール

まず、openldapとopenssh-ldapパッケージをインストールして、サービスを起動します。

# yum install -y openldap-servers openldap-clients openssh-ldap
# service slapd start

スキーマの追加

ここで、以前は/etc/openldap/slapd.confから /usr/share/doc/openssh-ldap-x.x.x/openssh-lpk-openldap.schema をincludeするだけでよかったのですが、CentOS7からはslapd.conf自体が消え去っているのでこれができません。

LDIFの形式に変換してcn=configデータベースに投入してやる必要があります。

以下のようにして変換します。

# echo "include /usr/share/doc/openssh-ldap-6.6.1p1/openssh-lpk-openldap.schema" > conv.conf
# mkdir tmp
# slapcat -f conv.conf -F tmp -n0 -a "cn={0}openssh-lpk-openldap" \
| sed -E '/^(structuralObjectClass|entryUUID|creatorsName|createTimestamp|entryCSN|modifiersName|modifyTimestamp):/d' \
-e 's/{0}//' \
> openssh-lpk-openldap.ldif

変換が面倒な人は変換済みのLDIFをこちらに置いてあるので、これを使ってください。

# wget https://www.osstech.co.jp/~hamano/posts/centos7-openldap-ssh/openssh-lpk-openldap.ldif

このLDIFをconfigデータベースに投入します。

# ldapadd -H ldapi:/// -f openssh-lpk-openldap.ldif

あと、cosineとinetorgpersonとnisのスキーマが必要です。

# ldapadd -H ldapi:/// -f /etc/openldap/schema/cosine.ldif
# ldapadd -H ldapi:/// -f /etc/openldap/schema/inetorgperson.ldif
# ldapadd -H ldapi:/// -f /etc/openldap/schema/nis.ldif

公開鍵の登録

デフォルトのsuffixがdc=my-domain,dc=comなのでこのまま、cn=test,dc=my-domain,dc=comというユーザーを追加してSSH公開鍵を登録してみましょう。

既定ではldapi経由でdc=my-domain,dc=com書き込みを行う権限がありませんのでまずアクセス権の設定を行います。 同時にldapプロトコルでのACLも設定しています。

# ldapmodify -H ldapi:///
dn: olcDatabase={2}hdb,cn=config
changetype: modify
add: olcAccess
olcAccess: to * by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" manage by * break
-
add: olcAccess
olcAccess: to attrs=userPassword by anonymous auth by * none
-
add: olcAccess
olcAccess: to * by * read

^D

これでdc=my-domain,dc=comに対して書き込めます。まずはベースエントリの投入。

# ldapadd -H ldapi:///
dn: dc=my-domain,dc=com
objectClass: dcObject
objectClass: organization
dc: my-domain
o: my-domain

^D

続いてユーザーエントリの投入、sshPublicKey属性にOpenSSHの公開鍵を指定します。

# ldapadd -H ldapi:///
dn: uid=test,dc=my-domain,dc=com
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: ldapPublicKey
uid: test
cn: test
sn: test
userPassword: password
uidNumber: 1000
gidNumber: 1000
homeDirectory: /home/test
sshPublicKey: ssh-rsa AAAAB3NzaC1yc2EAAAA...

^D

これでtestユーザーのエントリーと公開鍵を登録出来ました。

/usr/libexec/openssh/ssh-ldap-helper コマンドで動作確認してみましょう。

# /usr/libexec/openssh/ssh-ldap-helper -s test

このコマンドでtestユーザーのSSH公開鍵が表示されれば正常です。

OpenSSHの設定

/etc/ssh/sshd_config に以下の設定を記述し、sshdを再起動します。

AuthorizedKeysCommand /usr/libexec/openssh/ssh-ldap-wrapper
# service sshd restart

これでユーザーtestはLDAPに格納されている公開鍵を利用してログインできるようになったはずです。

AuthorizedKeysCommandを利用する際は、SELinuxは無効にするかSELinuxのポリシーを定義しましょう。

# setenforce 0