LDAPとKerberosの使用

Kerberosを使用する場合、ローカルネットワークにユーザ情報(ユーザID、グループ、ホームディレクトリなど)を配布するために、LDAPを使用することができます。 LDAPを使用する場合、偽のパケットによる攻撃や他の攻撃を防止するために、強力な認証メカニズムが必要になります。 対処方法の1つとして、LDAP通信にKerberosを使用することが挙げられます。

OpenLDAPは、SASL (Aimple Authentication Session Layer)を通じて、多くの認証フレーバーを実装しています。 基本的にSASLは、認証用に設計されたネットワークプロトコルです。 実装版のSASLはcyrus-saslで、さまざまな認証フレーバーをサポートしています。 Kerberos認証は、GSSAPI (General Security Services API)を介して実行されます。 デフォルトでは、GSSAPI用SASLプラグインはインストールされていません。 このプラグインをインストールするには、rpm -ivh cyrus-sasl-gssapi-*.rpmを実行します。

KerberosにOpenLDAPをバインドさせるには、プリンシパルldap/earth.example.comを作成して、それをkeytabに追加します。

デフォルトでは、LDAPサーバslapdが、ユーザおよびグループldapとして動作し、keytabファイルはrootしか参照できません。 そのため、LDAPの設定を変更して、サーバをrootとして動作させるか、またはグループldapがkeytabファイルを参照できるようにしてください。 /etc/sysconfig/openldapファイル中の変数OPENLDAP_KRB5_KEYTABにkeytabファイルが指定され、変数OPENLDAP_CHOWN_DIRSyesが設定されている場合(デフォルト)、グループldapがkeytabファイルを参照できるようにする設定作業は、OpenLDAP起動スクリプト(/etc/init.d/ldap)により自動的に行われます。 OPENLDAP_KRB5_KEYTABに何も指定されていない場合は、/etc/krb5.keytabにあるデフォルトのkeytabが使用されます。この場合は、以降の説明に従って、自分のアクセス権限を設定する必要があります。

slapdをrootとして実行する場合は、/etc/sysconfig/openldapを編集します。 変数OPENLDAP_USEROPENLDAP_GROUPの直前に注釈文字を指定して、これらの変数を無効にしてください。

グループLDAPがkeytabファイルを参照できるようにするには、次のコマンドを実行します。

chgrp ldap /etc/krb5.keytab

chmod 640 /etc/krb5.keytab
  

それ以外に、OpenLDAPに特殊なkeytabファイルを使用させる方法もあります。この方法が最良かもしれません。 この場合、kadminを起動してldap/earth.example.comを追加した後に、次のコマンドを入力します。

ktadd -k /etc/openldap/ldap.keytab ldap/earth.example.com@EXAMPLE.COM 
  

シェルから次のコマンドを実行します。

chown ldap.ldap /etc/openldap/ldap.keytab 
chmod 600 /etc/openldap/ldap.keytab
  

OpenLDAPに別のkeytabファイルを使わせるには、/etc/sysconfig/openldap中の次の変数を変更します。

OPENLDAP_KRB5_KEYTAB="/etc/openldap/ldap.keytab"
  

最後に、rcldaprestartコマンドで、LDAPサーバを再起動します。

LDAPでのKerberos認証の使用

ここまでの作業で、ldapsearchなどのツールをKerberos認証で利用できるようになりました。

ldapsearch -b ou=people,dc=example,dc=com '(uid=newbie)'

SASL/GSSAPI authentication started
SASL SSF: 56
SASL installing layers
[...]

# newbie, people, example.com
dn: uid=newbie,ou=people,dc=example,dc=com
uid: newbie
cn: Olaf Kirch
[...]
   

ご覧のように、GSSAPI認証を開始したことを伝えるメッセージが、ldapsearchから表示されます。 次のメッセージは難解ですが、SSF (Security Strength Factor)が 56であることを表しています(ここで、 56は任意の値になります。 ここには、DES暗号キーのビット数が表示されます)。 ここのメッセージは、GSSAPI認証が正常に開始され、LDAP接続を保護するために暗号が使われていることを表しています。

Kerberosでは、認証は常に相互に行われます。 つまり、LDAPサーバの認証を受けるだけでなく、こちら側でもLDAPサーバを認証します。 つまり、攻撃者が設定した偽のサーバではなく、正しいLDAPサーバと通信していることを確認することができます。

Kerberos認証とLDAPのアクセス制御

ここでは、ユーザに各自のLDAPユーザレコードのログインシェル属性の変更を許可する作業を行います。 この例では、ユーザjoeのLDAPエントリがuid=joe,ou=people,dc=example,dc=comにあり、/etc/openldap/slapd.confファイルに次のアクセス制御が設定されていると仮定しています。

# This is required for things to work _at all_
access to dn.base="" by * read
# Let each user change their login shell
access to dn="*,ou=people,dc=example,dc=com" attrs=loginShell
       by self write
# Every user can read everything
access to *
       by users read
   

2番目のステートメントでは、認証されたユーザに対して、自己のLDAPエントリのloginShell属性への書き込みアクセス権を与えています。 3番目のステートメントでは、認証されたユーザに対して、LDAPディレクトリ全体に対する読み込みアクセス権を与えています。

ここまでで、1つ分からないことがあります。LDAPサーバはどのようにして、Kerberosユーザであるjoe@EXAMPLE.COMが、LDAP識別名のuid=joe,ou=people,dc=example,dc=comと対応していることを判断するのでしょうか。 このためには、saslExprディレクティブを使って、手動でマッピングを設定する必要があります。 この例の場合は、次の項目をslapd.confに追加してください。

authz-regexp
   uid=(.*),cn=GSSAPI,cn=auth 
   uid=$1,ou=people,dc=example,dc=com

この仕組みを理解するには、いつSASLがユーザを認証するか、OpenLDAPがSASLから与えられた名前(joeなど)を使って識別名を作成するか、およびSASLフレーバーの名前(GSSAPI)を知る必要があります。 その結果が、 uid=joe,cn=GSSAPI,cn=authになります。

authz-regexpが指定されている場合、最初の引数を正規表現として使い、SASL情報から作成されたDNがチェックされます。 この正規表現が一致した場合、名前がauthz-regexpステートメントの2番目の引数に置換されます。 プレースホルダの$1は、(.*)式に一致するサブストリングで置き換えられます。

より複雑な式を作成することもできます。 ユーザ名がDNの一部にはならない複雑なディレクトリ構造またはスキーマがある場合でも、検索式を使ってSASL DNをユーザDNにマップすることができます。