Active DirectoryとLinuxの認証を統合しよう【2017年版】

第5回LDAPによる認証連携

第3回第4回は、pam_krb5による連携について紹介しました。今回からしばらくは、LDAPによる認証連携、認証統合について紹介します。

第2回で説明したように、Active Directory(AD)の認証は主としてKerberosによって行われています。一方、インターネット上を少し検索すれば、Active DirectoryをLDAPサーバと見立ててLDAP認証を行うための設定方法がいろいろ見つかると思います。 実はこれには幾つかの注意点や落とし穴があるのですが、それについて説明する上で、まずはオーソドックスな設定方法を紹介します。

今回は、IPアドレスが172.16.2.10で、WIN2K16DC-04というコンピュータ名のWindows Server 2016が稼働するDCが存在する、addom11.ad.localというADドメインでLinuxサーバの認証を行う場合を例に、設定例を示します。Linuxディストリビューションとしては、RHEL系の代表としてCentOS 7.3、Debian/Ubuntu系の代表としてUbuntu 16.04LTSを使っています。

なお、OpenLDAPなどのLinuxで動作する一般的なLDAPサーバではデフォルトで匿名アクセスが許可されていますが、ADのデフォルトでは許可されていません。そのため、以下の設定でも匿名アクセスは無効のままとし、ADアクセス用のユーザとして、Usersコンテナの直下に作成したフルネーム(CN)がLDAP Proxyというユーザを使用する際の設定例を示します。

パッケージのインストールと設定

各ディストリビューションで必要なパッケージの名称を表1に示します。まずは、これらのパッケージをインストールしてください。

表1 必要なパッケージ
CentOSnss_ldap
Ubuntulibnss-ldap

Ubuntuの場合、パッケージのインストール中にいくつかの設定を聞かれますが、これらは後から変更できるので、ここではすべてデフォルトのままで構いません。パッケージのインストールが完了したら、引き続き設定を行います。

CentOS 7.3における設定

CentOS 7.3では、次のようにauthconfigを実行することで必要なファイルが変更されます。

# authconfig --enableldap --enableldapauth --ldapserver=172.16.2.10 --ldapbasedn=DC=ADDOM11,DC=AD,DC=LOCAL --update

具体的には/etc/openldap/ldap.conf、/etc/nslcd.conf、/etc/pam.d/system-auth-ac、/etc/nsswitch.confといったファイルが更新されます。ただし、この設定はOpenLDAPなどの汎用のLDAPサーバを前提としたものですので、これだけではADで認証を行うことはできません。

前述したとおり、ADでは匿名アクセスがデフォルトで禁止されていますので、/etc/nslcd.confの以下の個所でbinddnおよびbindpwを設定して、ADに対する参照用のユーザとそのパスワードを明示的に指定する必要があります。

# The distinguished name of the search base.
base DC=ADDOM11,DC=AD,DC=LOCAL

# The distinguished name to bind to the server with.
# Optional: default is to bind anonymously.
#binddn cn=proxyuser,dc=example,dc=com
binddn cn=ldap proxy,cn=users,dc=addom11,dc=ad,dc=local ←ADを参照する際に用いるユーザのDN

# The credentials to bind with.
# Optional: default is no credentials.
# Note that if you set a bindpw you should check the permissions of this file.
#bindpw secret
bindpw (上記ユーザのパスワード)

なお、このパスワードはnslcd.confファイルに平文で書かれてしまいます。ファイル自体のパーミッションはデフォルトで600となっていますのでroot以外のユーザから見られることはありませんが、平文でパスワードを記載することに抵抗感のある方も多いでしょう。

さらに、ADに特化した設定を有効化するために、/etc/nslcd.confの以下の箇所のコメント(行頭の#)を削除して設定を有効にします。

# Mappings for Active Directory
pagesize 1000
referrals off
idle_timelimit 800
filter passwd (&(objectClass=user)(!(objectClass=computer))(uidNumber=*)(unixHomeDirectory=*))
map    passwd uid              sAMAccountName
map    passwd homeDirectory    unixHomeDirectory
map    passwd gecos            displayName
filter shadow (&(objectClass=user)(!(objectClass=computer))(uidNumber=*)(unixHomeDirectory=*))
map    shadow uid              sAMAccountName
map    shadow shadowLastChange pwdLastSet
filter group  (objectClass=group)

これでCentOSでの設定は完了です。

Ubuntu 16.04における設定

Ubuntuの場合はnslcdを使わないため、設定方法が若干異なります。まずは、nslcd.confの代わりに/etc/ldap.confファイルの以下の箇所を編集します。

……

# The distinguished name of the search base.
#base dc=example,dc=net
base dc=ADDOM11,dc=AD,dc=LOCAL

……

# Another way to specify your LDAP server is to provide an
#uri ldapi:///
uri ldap://172.16.2.10/ ←ADサーバのIPアドレスを指定

……

# The distinguished name to bind to the server with.
# Optional: default is to bind anonymously.
binddn cn=ldap proxy,cn=users,dc=ADDOM11,dc=AD,dc=LOCAL  ← LDAPサーバに検索を行うときに用いるユーザのDN

# The credentials to bind with.
# Optional: default is no credential.
bindpw (上記ユーザのパスワード)

……

# RFC 2307 (AD) mappings ←これ以下の行について、コメントを外す
nss_map_objectclass posixAccount user
nss_map_objectclass shadowAccount user
nss_map_attribute uid sAMAccountName
nss_map_attribute homeDirectory unixHomeDirectory
nss_map_attribute shadowLastChange pwdLastSet
nss_map_objectclass posixGroup group
nss_map_attribute uniqueMember member
pam_login_attribute sAMAccountName
pam_filter objectclass=User
pam_password ad

binddnやbindpwといったキーワードの意味はCentOSと同様です。⁠RFC 2307 (AD) ...」以下の設定は、ADとLDAPでの属性などのマッピングを行うためのものです。適切な設定がコメントアウトされた状態で記載されているので、単にコメントを外してください。

前述の通り、bindpwにはパスワードを平文で設定した上で、ldap.confのパーミッションは644など一般ユーザが読み取り可能にしておく必要があります。そのため、事実上このユーザのパスワードはサーバにログイン可能な全ユーザに公開されてしまいますので、留意してください。なお、rootbinddnを設定する必要はありません。

引き続き、/etc/nsswitch.confに以下のようにldapというキーワードを追加します。

# /etc/nsswitch.conf
#
# Example configuration of GNU Name Service Switch functionality.
# If you have the `glibc-doc-reference' and `info' packages installed, try:
# `info libc "Name Service Switch"' for information about this file.

passwd:         compat ldap
group:          compat ldap
shadow:         compat ldap
(以下略)

これでUbuntuでの設定は完了です。

Active Directoryでの設定

引き続き、AD側の設定を行います。

ADアクセス用ユーザの作成

まずは冒頭で説明したADアクセス用ユーザを作成します。Usersコンテナの下に図1のようにしてフルネーム(CN)がLDAP Proxyというユーザを作成します。このユーザのパスワードはLinux側の設定ファイルに平文で書き込まれますので、ユーザの権限は最低限にするように注意してください。⁠Domain Guests」グループのみに所属させた上で、対話的ログオンは許可しない設定を行うことをお薦めします。

図1 ADアクセス用ユーザの作成
図1 ADアクセス用ユーザの作成

各ユーザに対するUNIX属性の追加

ここまでの設定を行った状態でgetent passwdやgetent groupを行っても、ADに存在するユーザやグループの情報は返却されないはずです。その際、CentOSの/var/log/messagesには次のようなログが出力されます。

Oct  9 17:23:31 centos73-01 nslcd[2094]: [495cff] <group(all)> CN=Domain Users,CN=Users,DC=ADDOM11,DC=AD,DC=LOCAL: gidNumber: missing
Oct  9 17:23:31 centos73-01 nslcd[2094]: [495cff] <group(all)> CN=Domain Guests,CN=Users,DC=ADDOM11,DC=AD,DC=LOCAL: gidNumber: missing

これは、ADユーザやグループには、Linuxユーザとして必須の属性であるUIDやGIDの情報がデフォルトで設定されていないためです。Linuxサーバと認証連携を行うためには、各ユーザやグループ毎にこれらの属性を適切に設定する必要があります。

Windows Server 2012 R2までのWindowsサーバでは、⁠NISサーバー」役割サービスをインストールすることで図2のような「UNIX属性」タブが出現し、ここからGUIベースで設定ができたのですが、この機能はWindows Server 2016から削除されています。

図2 UNIX属性(Windows Server 2008 R2)
図2 UNIX属性(Windows Server 2008 R2)

そのため、Windows Server 2016以降でこれらの属性を変更するには、スクリプトなどで行うか、属性エディタを用いて属性を直接編集する必要があります。図3に属性エディタでgidNumberを修正する例を示します。

図3 属性エディタによる属性の修正
図3 属性エディタによる属性の修正

ユーザについては、uidNumberに加え、所属グループのGIDを示すgidNumberも設定する必要があります。加えてCentOSの場合はnslcd.confのデフォルトがunixHomeDirectoryの値が設定されているユーザを検索する設定となっているため、unixHomeDirectoryの値も設定する必要があります。これらの設定を行うことで、getent passwdやgetent groupの出力にユーザが表示されるようになります。

さらにLinuxサーバへのログオンを可能とするためには、loginShell属性に適切なシェルを設定する必要があります。関連する属性を表2に示します。

表2 Linuxユーザ用の属性
属性名意味設定例必須or任意
gidNumber所属グループのGID100必須
loginShellシェル/bin/bash任意
uidNumberUID10001必須
unixHomeDirectoryホームディレクトリのパス/home/ldap01任意

 CentOSでのデフォルト設定では必須

グループの場合はgidNumber属性の設定のみが必須となります。

ここまでの設定を行うことで、getentコマンドやidコマンドで次のようにエントリが表示されるようになるはずです。

$ getent passwd ldap01
ldap01:*:10011:100:ldap 01.:/home/ldap01:/bin/bash
$ id ldap01
uid=10011(ldap01) gid=100(users) groups=100(users)

認証連携の動作確認

ここまでの設定を適切に行うことで、次のようにsshなどでログインする際にADで設定したパスワードを指定することで、ログインすることが可能となっているはずです。

$ ssh ubuntu1604-01 -l ldap01
Password:
Last login: Mon Oct  9 18:27:08 2017
Could not chdir to home directory /home/ldap01: No such file or directory

ホームディレクトリの自動作成

上記では指定したホームディレクトリを作成していないためエラーが発生していますが、事前に作成しておくか、pam_mkhomedirモジュールを有効化し、ホームディレクトリ自動作成するように設定することでエラーを抑止することができます。CentOSの場合は、authconfigコマンドを次のように実行することで、モジュールを有効化します。

# authconfig --enablemkhomedir --update

Ubuntuの場合は、pam-auth-updateコマンドを起動し、メニューから「Create home directory on login」にチェックをしてください。

LDAP認証の通信と問題点

ここでは、ファイアウォールなどで制御を行う場合を想定し、LDAP認証を行う際の具体的な通信を紹介します。CentOS環境における認証時の通信を図4に示します。

図4 LDAP認証によるログイン時の通信
図4 LDAP認証によるログイン時の通信

大量のLDAPのやりとりが行われていますが、基本的にはldap proxyとして認証された通信でldap01ユーザの情報が取得され、最終的にパケット171と172でldap01として認証(bind)が行われて、成功しています。この部分が実質的なユーザ認証となります。認証パケットの詳細を図4の下のペインに示していますが、パスワードが平文で表示されていることが確認できます。

実は、LDAPの標準の認証方式はシンプルバインド(シンプル認証)と呼ばれる平文認証です。認証連携自体は比較的簡単にできますが、ファイルにパスワードを平文で記述する必要があることに加え、ネットワーク上をパスワードが平文で流れてしまうため、セキュリティ上は極めて脆弱です。

なお、ここまでの設定でパスワード変更を行うことはできません。実際に行うと以下のようなメッセージが表示されます。

$ passwd
Changing password for user ldap01.
(current) LDAP Password:
New password:
Retype new password:
password change failed: Protocol error
passwd: Authentication token manipulation error

これは、Active Directoryの仕様上LDAP経由でのパスワード変更をサポートしていないためです。上記の操作の際のパケットを図5に示します。

図5 LDAP認証によるパスワード変更時(失敗)の通信
図5 LDAP認証によるパスワード変更時(失敗)の通信

パケット528以降でパスワード変更の通信が行われています。ここではパケットの詳細を示していませんが、平文で変更後のパスワードが送信された上で、エラーとなっています。

ADで匿名認証を有効化する

冒頭で紹介したように、ADのデフォルトでは匿名認証が許可されていませんが、図6のようにdsHeuristicという属性の値を変更することで、ADで匿名認証を許可させることもできます。

図6 dSHeuristics属性の変更
図6 dSHeuristics属性の変更

詳細についてはMicrosoft サポートのWindows Server 2003 のドメイン コントローラでは Active Directory に対する匿名の LDAP 操作が無効になっているなどを参照してください。

匿名認証を許可したら、引き続き、アクセスを許可させたいオブジェクトのアクセス制御リストに匿名ユーザのアクセス制御エントリを追加します。運用上はLDAP認証で使用するユーザをどこかのコンテナに集めてしまい、該当のコンテナに対して匿名ユーザのアクセス制御エントリを追加するのがよいでしょう。

ここではLDAPという名前のOUに適切な設定を行う際の例を説明します。⁠Active Directory ユーザーとコンピューター」「拡張機能」をチェックした上でLDAPのプロパティを開き、⁠セキュリティ」タブを選択します。ここで図7のようにANONYMOUS LOGONに「読み取り」アクセス許可を付与してください。

図7 匿名アクセスの追加
図7 匿名アクセスの追加

さらに「詳細設定」ボタンを押して詳細設定画面を開き、適用先を「このオブジェクトのみ」から「このオブジェクトとすべての子オブジェクト」に変更します。

これで、LDAPの配下に作成したユーザやグループのオブジェクトは匿名アクセスで参照が可能となるため、匿名認証を有効にした状態でもLinux側から参照することが可能となっているはずです。これにより、binddnおよびbindpwを設定する必要がなくなるため、Linuxサーバの視点ではセキュリティ上のリスクが軽減されます。一方で、匿名アクセスの設定はフォレスト全体に波及するため、別のセキュリティリスクが発生する点に留意してください。

まとめ

今回は、LDAP認証について、まずはもっとも基本的な設定について説明を行いました。匿名アクセスを有効化した場合でも各ユーザのパスワードはネットワーク上を平文で流れるため、セキュリティ上の問題が残ります。

次回以降ではこれを解決する対策について紹介していきます。

おすすめ記事

記事・ニュース一覧