11.2. PAM/LDAP

11.2.1. PAM

PAMの仕組み

PAMはプログラムに対してユーザ認証をするための機能を提供する仕組み
PAMによりプログラム自体がユーザ情報を/etc/passwdにあるか別のホストにあるかを気にせずに設定できる。 認証方法は設定ファイルの編集をするだけで可能で、特定ユーザのみの認証などもできる。

PAMの設定

PAMの設定ファイルは/etc/pam.dディレクトリに配置さ、ユーザ認証を行うプログラムごとにファイルが用意されている。 またPAM設定ファイルの書式は以下の通り。

モジュールタイプ コントロール モジュールパス 引数
項目説明
モジュールタイプモジュールが用いる認証の型
コントロール認証の成功/失敗時の処理を指定
モジュールパスどのモジュールを使うか指定
  • モジュールタイプ
    • auth … ユーザ認証を行う
    • account … ユーザ認証ができるか確認
    • password … ユーザの設定と変更に使用
    • session … ユーザ認証の前後に処理する内容を指定
  • コントロール
    • requisite … モジュールの実行に失敗したら認証拒否する
    • required … モジュールの実行に失敗してもすぐに拒否せず、同じモジュールの実行完了後に認証を拒否する
    • sufficient … モジュールの実行に成功した場合、上位のrequiredがすべて成功の場合認証を成功とする
    • optional … optionalを指定したモジュールタイプが1つだけの場合を除いてPAMに影響を与えない
    • include … 指定したファイルの設定を読み込んで処理する
    • substack 指定した設定を読み込んで処理する(認証の成否は指定したファイル内で完結し、1モジュールとしてカウントする)

またPAMモジュールは以下の通り。 PAMモジュールは/lib/security/lib64/securityに保存される。

PAMモジュール説明
pam-cracklib.soパスワード安全性の向上
pam_pwquality.soパスワード安全性の向上(RHEL7やCentOS7から使用)
pam_env.soユーザログイン時の環境変数の初期設定
pam_deny.so認証に対し常に失敗を返す
pam_limits.soユーザが利用できるリソースの制限
pam_listfile.soファイル内容に基づきサービスの許可/非許可
pam_nologin.so/etc/nologinファイルがあるとき一般ユーザのログインを拒否する
pam_pwdb.so/etc/passwd,/etc/shadow,NISを使ったユーザ認証/パスワード変更を行う
pam_rootok.sorootユーザによるアクセス許可をする
pam_secirty.so/etc/securityファイルに記載された端末のみrootログインの許可
pam_stack.so他のPAM設定ファイルをincludeする
pam_succedd_if.so特定のファイル属性をチェックしてサービス許可する
pam_unix.so通常のパスワード認証を行う
pam_ldap.soLDAP認証を行う
pam_warn.so認証時/パスワード変更時のログ出力する
pam_sss.soSSSDを使った認証を行う
pam_wheel.soroot権限アクセスをwheelグループメンバーのみに制限する

11.2.2. LDAP

LDAPとは

LDAPはネットワーク機器やユーザーID、パスワードを管理するディレクトリサービスの維持やアクセスを行うプロトコルのこと。
堅く言うと、X.500をベースとしたディレクトリサービスに接続するために使用されるプロトコルでDAPを軽量化したものともいえる。

一般的にLDAPは一元管理の認証サーバを構築する際に使用される。
LDAPによりユーザやリソースに関する情報を検索したり管理することができる。

なお、OpenLDAPの設定方法は、OpenLDAP2.3以降、テキストの設定ファイルから起動時に設定を読み込む一般的な方法から、LDAPを使った動的な設定方法に変更されている。

LDAPの概念

LDAPではデータをオブジェクトとして扱う
オブジェクトとは現実世界に存在する何らかの実体をコンピュータ上で表したもの。

  • エントリ
    • LDAPでのオブジェクトの単位のこと
    • それぞれのエントリはオブジェクトクラスに属する
    • 下位のエントリを分類する目的のみに使用するエントリはコンテナと呼ばれる
  • 属性
    • エントリ(オブジェクト)が持つ情報を表すもの
    • 属性は属性名と属性値から構成される
  • DIT(ディレクトリ情報ツリー)
    • エントリ間の関係を階層構造(木構造)で表したもの

LDAP

LDAPの仕組み

ディレクトリ情報ツリーと識別名

LDAPでは情報はDIT(ディレクトリ情報ツリー)という階層に格納される。
ディレクトリ情報ツリー内のエントリ識別には識別名(DN)を使用する。
識別名はエントリ属性名とその値から構成される相対識別名を「,」でつないだもの、以下のように格納される。

uid=student,ou=IEducation,dc=CCNA,dc=ja

DIT上にあるエントリを識別するための識別子には、DN(Distinguished Name)とRDN(Relative Distinguished Name)がある。

LDIF

LDIFはディレクトリ内の情報を記述するファイル形式のこと。
LDAPサーバにディレクトリ情報を登録、変更する場合に使用されrる。

記法は以下の通り。

dn: 識別名
属性名: 値
属性名: 値
   :    

LDIFファイルでは最初の行でエントリの識別名(DN)を記述する。
また、複数のエントリを記載する場合は空行で区切り、コメントは行頭に「#」をつける。

なお、属性値は通常UTF-8のテキストで記載するが、バイナリデータなどの特殊なデータを指定する場合は「属性名::属性値」のようにし、属性値にはBase64でエンコードした値を指定する。

オブジェクトクラス

オブジェクトクラスはオブジェクトが持つべき属性(情報)を定義したもの

LDAPでのオブジェクトの単位であるエントリは、必ずオブジェクトクラスに属する。オブジェクトクラスによってエントリの実体(エントリが人を表すのか、組織を表すのかなど)が決定される。

オブジェクトクラスは以下の通り。

種類説明
ABSTRACT他のオブジェクトクラスを定義するための基底クラス
STRUCTURAL人や組織などを表すオブジェクトクラス
AUXILIARY構造型クラスと共に用いるイブジェクトクラス

スキーマ

スキーマはオブジェクトや属性の定義のこと
LDAPでは様々なスキーマが事前に登録されており、/etc/openldap/schemaに格納されている。

主なスキーマファイルは以下の通り。

スキーマファイル説明
core.schemaOpenLDAP必須のスキーマ
cnやouなどの基本的属性が定義されている
cosine.schemaディレクトリサービスのX.500規格で規定された属性が定義されたスキーマ
inetorgperson.schemaアドレス帳/個人情報を扱うためのスキーマ
nis.schemaUnix/Linuxユーザ/グループ情報を扱うためのスキーマ

属性名

主な属性は以下の通り。

属性名説明
dn識別名
objectClassオブジェクトクラス
c国名
cn一飯名称
dcドメイン構成要素
mailメールアドレス
o組織名
ou部署などの組織単位
sn苗字
telephoneNumber電話番号
uidユーザのログイン名
uidNumberユーザID

オブジェクト識別子

オブジェクトクラスや属性にはオブジェクト識別子(OID)が割り振られる。
OIDは全世界で重複しないようにIANAにより管理されている。

新しいオブジェクトクラスや属性を作成するためにスキーマファイルを作成・拡張する場合は、IANAから一意のOIDを取得する必要がある。

ホワイトページ

ホワイトページは個人別電話帳のことを指す。
LDAPによりホワイトページを作成し個人別データを登録するとメーラなどのネットワーク経由で電話番号など情報検索が可能。

ホワイトページの使用にはinetorgperson.schemaで定義されたinetOrgPersonクラスを使用するのが一般的となる。

Open LDAPの設定

LinuxでLDAPを使用するにはOpenLDAPが一般的に使用される。
サーバデーモンはslapdとなる。

また設定ファイルは/etc/openldap/slapd.confとなる。
設定ファイルの例は以下の通り。

# スキーマ定義ファイルのInclude
include   /etc/openladp/schema/corba.schema
                 :
                 :

# DBの形式
database bdb

# 管理するディレクトリのトップエントリ
suffix "dc=study,dc=jp"

# ディレクトリ管理者のDN
rootdh "cn=Manager,dc=study,dc=jp"

# ディレクトリ管理者のパスワード
rootpw [SSHA]5en8MexzhkJ90K0myuY/BfQ=

# LDAPデータベースの格納ディレクトリ
directory /var/lib/idap

# LDAPのインデックス登録
index objectClass eq.pres
index ou,cn,mail,surname,givenname eq,pres,sub
                    :
                    :

slapd.confの設定項目は以下の通り。

設定項目説明
includeスキーマファイルなど別のファイルを読み込む
databaseディレクトリデータを格納するBackENDデータベースの形式指定
suffix管理するディレクトリのトップエントリの指定
rootdnディレクトリ管理者のDNを指定する
rootpwディレクトリ管理者のパスワードを指定する
directoryLDAPデータベースの格納ディレクトリのパス指定
index検索用インデックスを作成する属性とインデックスの種類の指定

アクセス制御

OpenLDAPではエントリ/属性に対しアクセス制御(ACL)できる。

accsess to アクセス制御対象
    by 接続元 アクセスレベル
アクセス制御対象説明
*すべてのエントリ
attrs=属性指定した属性のみ
dn=DN指定したDNのみ
接続元説明
*すべてのユーザ
annonymous認証前のユーザ
users認証されたユーザ
self接続中の認証済みユーザ自身
dn=DN指定したDNユーザ
アクセスレベル説明
write属性値を変更できる
read検索結果を参照できる
search検索できる
compare比較できる
auth認証を受けることができる
noneアクセスできない

設定例は以下の通り。

# userPassword属性に対し、管理DNとユーザ自身による更新は許可、ユーザ認証前ユーザは認証のみ許可、それ以外のユーザはアクセス禁止する例
access to attrs=userPassword
       by dn="cn=Manage,dc=study,dc=jp" write
       by self write
       by annonymous auth
       by * none

LDAPの起動

slapdの起動は以下のようにする。

/usr/local/etc/libexex/slapd

SysVinitのシステムでは以下のように起動。

/etc/init.d/slapd start

systemdのシステムでは以下の通り。

systemctl start slapd.service

slappasswdコマンド

slapd.confファイルのrootpwに関する管理者パスワードを作成するコマンド。
サーバ管理者のパスワードをハッシュ化して生成する。

slappasswd

slapcatコマンド

LDAPデータベースの内容をLDIF形式で出力するコマンド。

slapcat > ldapdb.ldif

slaptestコマンド

設定ファイルslapd.confの構文をチェックするコマンド。

slaptest

slapaddコマンド

LDIFデータをLDAPデータベースにリストアするコマンド。

slapadd -l ldapdb.ldif
オプション説明
-v詳細表示
-d 数デバッグレベルの指定
-f ファイル設定ファイルの指定
-cエラー時も処理を継続
-n 数使用するデータベースをDB番号で指定
-b DN使用するデータベースをDNで指定

slapindexコマンド

データベースのインデックスを再構築するコマンド。 slapaddコマンドの後に実行する。

slapindex

LDAPクライアントの利用

LDAPクライアントコマンドには以下のようなコマンドがある。

コマンド説明
ldapaddエントリを追加する
ldapsearchエントリを検索する
ldapdeleteエントリを削除する
ldapmodifyエントリを変更する
ldappasswdパスワードを変更する

ldapaddコマンド

エントリを追加するコマンド。
追加するには/tmp/test.ldifにLDIFで記述してからコマンドを実行して追加する。

ldapadd <オプション>
オプション説明
-h ホストLDAPサーバの指定(デフォルトはローカルホスト)
-xSASLを使わず簡易認証を用いる
-D バインドDN認証に利用するDNを指定する
-W認証時のパスワードを対話的に入力する
-w パスワード認証時のパスワードを指定する
-f ファイル名LDIFファイルの指定

ldapdeleteコマンド

LDAPサーバに登録されたエントリを削除するコマンド

ldapdelete 

ldapsearchコマンド

エントリを検索するコマンド。

ldapsearch <オプション> 検索フィルタ <出力属性>
オプション説明
-h ホストLDAPサーバの指定
-H URILDAPサーバの指定をldapurlで指定
-xSASLを使わず簡易認証を用いる
-D バインドDN検索を開始するDNを指定する
-L検索結果をLDIFv1形式で表示する
-LL検索結果をコメントなしで表示する
-LLL検索結果をコメントとLDAPバージョン表示なしで表示する
-b 識別名検索開始位置の指定

ldapsearchコマンド

LDAPサーバのエントリを検索するコマンド。

ldapsearch [オプション] 検索条件 [出力属性]
オプション説明
-h ホスト名/IPアドレス検索を行うLDAPサーバを指定
-H URI検索を行うLDAPサーバをldapuri形式で指定
-xSASLを使用せずに簡易認証を行う
-b 識別名検索開始位置の指定
-L検索結果をLDIFv1形式で表示
-LL検索結果をコメントなしで表示
-LLL検索結果をコメントとLDAPバージョン表記なしで表示

slapd-config

OpenLDAP2.3以降の設定方法はslapd-configと呼ばれる。
この方法ではLDAPのデータベース(ディレクトリ)に保存されている設定データを追加・変更・削除等することで、動的に設定を更新する。 これはディレクトリベースの設定と呼ばれ、通常は設定変更による再起動等が不要となる。

また、設定データベースのツリー構造のルートは、DN(識別名)がcn=configで定義され、変更できない。
設定を行う際は設定用のLDIFファイルを定義し、ldapaddldapdeleteldapmodifyといったコマンドにより、データベースを更新する。

グローバルセクションに使用する主なディレクティブ

グローバルセクションに使用する主なディレクティブは以下の通り。

slapd.confディレクティブslapd-configディレクティブ説明
argsfile ファイル名olcArgsFileslapdデーモン起動時のコマンド引数を格納するファイルの指定
pidfile ファイル名olcPidFileslapdのプロセスIDを格納するファイルの指定
include ファイル名olcInclude読み込む設定ファイルのを指定
logfile ファイル名olcLogFileデバックログの出力ファイルを指定
loglevel 数olcLogLevelログレベルの指定
idletimeut 秒数olcIdleTimeoutアイドル状態のクライアント接続を強制的に切断するまでの秒数指定
timelimit 秒数olcTimeLimitslapdが検索要求の応答に使う最大秒数の指定

データベースセクションで使用する主なディレクティブ

slapd.confとslapd-configのデータベースセクションで使用する主なディレクティブの対応表は以下の通り。

slapd.confディレクティブslapd-configディレクティブ説明
database 種類orcDatabaseバックエンドデータベースの種類を指定
suufix DNorcSuffixディレクリのトップとなるDNの指定
rootdn DNorcRootDNデータベース管理者のDNの指定
rootpw パスワードorcRootPWデータベース管理者のパスワードを指定
index 属性名 種類orcDbindex属性に作成するインデックスの種類の指定
dircetory ディレクトリorcDbDirectoryデータベースファイルを格納するディレクトリの指定

slapd-configで使用される基本的なディレクティブ

slapd-configで使用される基本的なディレクティブは以下の通り。 なお「olc」という文字は「OpenLDAP Configuration」の略となる。

ディレクティブ説明定義されるエントリと説明
orcLogLevelsyslogに出力するレベル指定
orcLogLevel:
cn=config
サーバ全体に適用
必須オブジェクトクラス: orcGlobal
orcIncludeincludeファイルを指定
orcInclude <ファイル名>
cn=include
slapd.confのincludeファイル用
必須オブジェクトクラス:orcIncludeFile
orcAttributeTypes属性名の定義
orcAttributeTypes: <属性名>
cn=schema
組み込みのスキーマ定義
必須オブジェクトクラス:orcSchemaConfig
orcObjectClassesオブジェクトクラスを定義
orcObjectClasses: <オブジェクトクラス>
cn=schema
組み込みのスキーマ定義
必須オブジェクトクラス:orcSchemaConfig
orcBackendバックエンドの指定
orbBackend = <タイプ>
必須オブジェクトクラス: orcBackendConfig: [type]
typeはbdb,config, ldap, ldif, passwdがある

slapd-configのアクセス権の設定

olcAccessディレクティブを用いてバインドしたDN(ユーザ)に応じたアクセス権の設定を行える。

olcAccess: to アクセス対象 by 要求者 アクセス権 by 要求者 アクセス権 ...

なお、複数行にまたがって記述する場合は2行目以降の行頭にスペースを入れる

olcAccess: to アクセス対象
 by 要求者 アクセス権
 by 要求者 アクセス権
アクセス制御対象説明
*すべてのエントリ
attrs=属性指定した属性のみ
dn=DN指定したDNのみ
filter=検索フィルタ検索フィルタにマッチするエントリ
接続元説明
*すべてのユーザ
annonymous認証前のユーザ
users認証されたユーザ
self接続中の認証済みユーザ自身
dn=DN指定したDNユーザ
アクセスレベル説明
write属性値を変更できる
read検索結果を参照できる
search検索できる
compare比較できる
auth認証を受けることができる
noneアクセスできない

11.2.3. SSSD

SSSDはLDAPなどの認証サービスとの通信を管理/情報をキャッシュする仕組み
これによりLDAPサーバダウン時の可用性の向上や負荷を軽減することができる。

SSSDに設定は/etc/sssd/sssd.confで行う。

[sssd]
config_file_version = 2
services = nss, pam
domains = LDAP

[nss]
filter_users = root,dnsmasq,dbus,bin,daemon,games,gdm,lp,mail,mysql,news,ntp,openldap,sshd,sync,sys
filter_groups = root
homedir_substring = /home

[pam]

[domai/LDAP]
id_provider = ldap
ldap_uri = ldap://ldap.test.com:389
ldap_search_base = dc=test,dc=com
ldap_tls_reqcert = never
ldap_id_usb_start_tls = true
ldap_tls_cacert = /etc/pki/tls/certs/ca-bundle.crt

ldap_schema = rfc2307

cache_ceredentials = true
enumerate = true

sssdサービスはsystemctl start sssd.serviceで可能。
また/etc/nsswitch.confで以下のようにSSSDを参照するようにする。(sssと記述する)

passwd: files sss
shadow: files sss
group:  files sss