カテゴリ

CentOS OpenLDAP OpenSSH

SSH(CentOS標準リポジトリのOpenSSH)の公開鍵認証でLDAP認証を利用する手順です。
LDAPにはCentOS標準リポジトリのOpenLDAPを利用しました。
※CentOS 5系ではこの手順ではうまくいきません。

目次

前提知識

LDAPはDNSやファイルシステムのディレクトリ(フォルダ)/ファイル構成と同じような、ツリー型にデータ(エントリ)を保持します。
各エントリは属性をもち、そのエントリが持つ属性の定義(スキーマ)も objectClass という属性としてそのエントリ内に格納しています。

特定のエントリを識別する表記(識別子)を DN(Distinguished Name)といいます。
※DNSでいうFQDN。

参考 http://www.turbolinux.co.jp/products/server/11s/user_guide/openldapdirtree.html

RDBのイメージに近づけると LDAPディレクトリ全体をデータベース、エントリをテーブル(ただし常に1レコードのみ)、スキーマをテーブル定義、属性を各フィールド、と考えると理解しやすいかもしれません。
Web系のエンジニアであればDOM構造を考えればほぼそのままです。

想定する環境

LDAPサーバのホスト名
ldap.example.com
LDAPのBASE DN
dc=example,dc=com
管理者のDN
cn=ldapadmin,dc=example,dc=com
管理者のパスワード
secret
認証対象のユーザ
user1

LDAPサーバの準備

インストール

必要なパッケージは openldap-servers、 openssh-ldap です。
※実際には openssh-ldap はSSHサーバ側の動作に必要なものでありLDAPサーバ側には不要ですが、後に述べるスキーマが含まれるため合わせて入れてしまいます。

yum install openldap-servers openssh-ldap

初期設定

OpenLDAPサーバが動作するサービスは slapd です。
初期インストール状態でslapdは動き始めていますが、諸々クリアにするために一度とめ、デフォルトのデータ類を削除します。

service slapd stop

cd /etc/openldap

# 一応バックアップ
mkdir ../openldap_orig/etc_openldap
mkdir ../openldap_orig/var_lib_ldap
cp -rf * ../openldap_orig/etc_openldap
cp -rf /var/lib/ldap/* ../openldap_orig/var_lib_ldap

# デフォルトデータ削除
rm -rf /etc/openldap/slapd.d
rm -rf /var/lib/ldap/*

設定に必要な各種ファイルを準備します。

# 雛形となる各種ファイルコピー
cp /usr/share/openldap-servers/slapd.conf.obsolete  slapd.conf
cp /usr/share/doc/openssh-ldap-5.3p1/openssh-lpk-openldap.schema schema/openssh-lpk-openldap.schema
cp /usr/share/openldap-servers/DB_CONFIG.example /var/lib/ldap/DB_CONFIG

slapd.conf の編集

slapd.conf を編集します。

スキーマファイルのインクルードが並んでいる最後あたりに下記を追記。

include     /etc/openldap/schema/openssh-lpk-openldap.schema

# Sample access control policy: とか言ってる後あたりに下記を追記。
管理者アカウントの設定と、誰でも読み込めて本人のみ編集化として権限設定。

access to attrs=userPassword
        by dn="cn=ldapadmin,dc=example,dc=com" write
        by self write
        by anonymous auth
        by * none
access to *
        by self write
        by * read

# database definitions 以下で利用するDBの設定(今回は bdb)

database    bdb
suffix      "dc=example,dc=com"
checkpoint  1024 15
rootdn      "cn=ldapadmin,dc=example,dc=com"
rootpw      secret

※rootpw は実際はプレインテキストではなく、slappasswd コマンドでパスワードを入力した結果出てくるハッシュを入れるべき。

この状態で slapd サービスを起動すると、自動的に slapd.d 以下および /var/lib/ldap 以下に関連ファイルが作成される(はず)。

service slapd start

データ登録

本来はOUとかを合わせて考える方がいいですが、今回は簡略のためベース直下に直接ユーザを配置するつもりで。

LDAPのツリー構造のルートと、管理アカウントのエントリをまず作るための LDIFファイル(仮に init.ldif とします)を作成します。

dn: dc=example,dc=com
objectClass: dcObject
objectClass: organization
dc: example
o: example

dn: cn=ldapadmin,dc=example,dc=com
objectclass: organizationalRole
cn: ldapadmin

これをLDAPに登録します。

ldapadd -x -h localhost -D "cn=ldapadmin,dc=example,dc=com" -w secret -f init.ldif

[help]
【参考】実用 Apache 2.0運用・管理術(7):Apacheで作るファイルサーバ(LDAP認証編) (1/4) - @IT
http://www.atmarkit.co.jp/ait/articles/0601/17/news096.html
[/help]

LDAP認証を利用するユーザのエントリ登録

前提知識

この手順の場合、LDAP認証の際に実際に使われているコマンドは /usr/libexec/openssh/ssh-ldap-wrapper [ユーザ名] 、ssh-ldap-wrapper の実態は ssh-ldap-helper -s $1 、実際に検索に使っているのは (&(objectclass=posixAccount)(objectclass=ldapPublicKey)(uid=ユーザ名)) のようでした。
→ posixAccountスキーマ かつ ldapPublicKeyスキーマ のエントリの属性 uid でチェック。

しかし、posixAccountスキーマ、ldapPublicKeyスキーマはどちらも AUXILIARY なスキーマであり、LDAPのエントリには STRUCTURAL なスキーマが1つは必要なため、accountスキーマを利用します。
また、ldapPublickey スキーマは uid と sshPublicKey しか属性を持っていませんが、accountスキーマ、posixAccount スキーマは下記の属性を含みます。

account
[必須属性]
  • userid(uidと同義)
[任意属性]
  • description
  • seeAlso
  • localityName
  • organizationName
  • organizationalUnitName
  • host
posixAccount

:

[必須属性]
  • cn
  • uid
  • uidNumber
  • gidNumber
  • homeDirectory
[任意属性]
  • userPassword
  • loginShell
  • gecos
  • description

※今回の手順の場合、pam等で認証をしているわけではなく、OpenSSHの公開鍵認証の際の公開鍵の取得先をLDAPにしているだけなので、uid、sshPublicKey 以外は何を書いていても動作に影響しません。

LDIFファイル作成→LDAPに登録

これらを踏まえて、認証ユーザのエントリを下記のようなファイル(LDIFファイル:仮に user1.ldif というファイルとして)に作成します。

user1.ldif

dn: uid=user1,dc=example,dc=com
objectClass: account
objectClass: posixAccount
objectClass: ldapPublickey
uid: user1
cn: user1
uidNumber: 1001
gidNumber: 1001
homeDirectory: /home/user1
sshPublicKey: [公開鍵テキストを1行で貼り付ける]

※空白行を区切りにすることで、複数エントリを1ファイルに作ることができます。

user1.ldif を利用して、LDAPサーバにエントリを登録します。

ldapadd -x -D 'cn=ldapadmin,dc=example.dc=com' -f user1.ldif -W
>(パスワード入力)

問題がなければ正常に取り込まれるはずです。

SSHサーバ側(LDAP認証を利用するサーバ)の設定

前提条件として、LDAP認証を行いたいサーバ側から上記で用意したLDAPサーバに接続できる必要があります。
iptablesなどの設定を確認しておきましょう。

また、認証ユーザのアカウントが存在する必要があります。

事前準備:アカウント作成

既にアカウントがある場合は次の[インストール]に進んで構いません。

useradd user1

インストール

必要なパッケージは openssh-ldap です。
※LDAPサーバと同一サーバで、上記の手順で構築した場合は既にインストールされています。

yum install openssh-ldap

初期設定

/etc/ssh/ldap.conf として下記を作成。

uri ldap://ldap.example.com/
base dc=example,dc=com

ssl no

/etc/ssh/sshd_config に下記を追記

AuthorizedKeysCommand /usr/libexec/openssh/ssh-ldap-wrapper

一旦動作テスト

sshdの再起動(設定反映)をする前にこの時点で一旦動作テストをします。

上記の sshd_config の設定で /usr/libexec/openssh/ssh-ldap-wrapper を使って公開鍵を取得するように設定したので、そのコマンドを手動で叩いてみるということです。

/usr/libexec/openssh/ssh-ldap-wrapper user1

正常に動作すればuser1の公開鍵がLDAPから取得されて表示されます。
何も表示されないとか何かエラーが表示される場合はどこかに間違いがあるので、messegeログなどを参考にトラブルシューティングします。

sshd に設定反映

sshd は再起動しても既につながれているセッションを切断しないので、現在接続している環境で再起動し、そのセッションをつないだまま別のターミナルなどからSSH接続のテストをします。
テストで接続できないときは既につないでいる方のセッションでなんとかします。
(なんとかできないと大変なことになります。)

service sshd restart

テストの際は、user1の .ssh/authorized_keys を一度どこかに移動するなど、公開鍵が設定されていない状態にしてから行うと確かにLDAPから取得しているのかがわかりやすいです。

注意事項

本来はSSL対応や iptables などの接続制限など様々考慮する必要がありますが、この投稿の範囲では割愛しています。
(この投稿の範囲でネットワーク上を流れるのは「公開鍵」だし・・・とか言い訳。)

また、素直にLDAP検索をするようなクライアントツールは openldap-client をインストールすることで利用できます。

コメント