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.so | rootユーザによるアクセス許可をする | 
| pam_secirty.so | /etc/securityファイルに記載された端末のみrootログインの許可 | 
| pam_stack.so | 他のPAM設定ファイルをincludeする | 
| pam_succedd_if.so | 特定のファイル属性をチェックしてサービス許可する | 
| pam_unix.so | 通常のパスワード認証を行う | 
| pam_ldap.so | LDAP認証を行う | 
| pam_warn.so | 認証時/パスワード変更時のログ出力する | 
| pam_sss.so | SSSDを使った認証を行う | 
| pam_wheel.so | root権限アクセスをwheelグループメンバーのみに制限する | 
11.2.2. LDAP
LDAPとは
LDAPはネットワーク機器やユーザーID、パスワードを管理するディレクトリサービスの維持やアクセスを行うプロトコルのこと。
堅く言うと、X.500をベースとしたディレクトリサービスに接続するために使用されるプロトコルでDAPを軽量化したものともいえる。
一般的にLDAPは一元管理の認証サーバを構築する際に使用される。
LDAPによりユーザやリソースに関する情報を検索したり管理することができる。
なお、OpenLDAPの設定方法は、OpenLDAP2.3以降、テキストの設定ファイルから起動時に設定を読み込む一般的な方法から、LDAPを使った動的な設定方法に変更されている。
LDAPの概念
LDAPではデータをオブジェクトとして扱う。
オブジェクトとは現実世界に存在する何らかの実体をコンピュータ上で表したもの。
- エントリ- LDAPでのオブジェクトの単位のこと
- それぞれのエントリはオブジェクトクラスに属する
- 下位のエントリを分類する目的のみに使用するエントリはコンテナと呼ばれる
 
- 属性- エントリ(オブジェクト)が持つ情報を表すもの
- 属性は属性名と属性値から構成される
 
- DIT(ディレクトリ情報ツリー)- エントリ間の関係を階層構造(木構造)で表したもの
 

LDAPの仕組み
ディレクトリ情報ツリーと識別名
LDAPでは情報はDIT(ディレクトリ情報ツリー)という階層に格納される。
ディレクトリ情報ツリー内のエントリ識別には識別名(DN)を使用する。
識別名はエントリ属性名とその値から構成される相対識別名を「,」でつないだもの、以下のように格納される。
uid=student,ou=IEducation,dc=CCNA,dc=jaDIT上にあるエントリを識別するための識別子には、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.schema | OpenLDAP必須のスキーマ cnやouなどの基本的属性が定義されている | 
| cosine.schema | ディレクトリサービスのX.500規格で規定された属性が定義されたスキーマ | 
| inetorgperson.schema | アドレス帳/個人情報を扱うためのスキーマ | 
| nis.schema | Unix/Linuxユーザ/グループ情報を扱うためのスキーマ | 
属性名
主な属性は以下の通り。
| 属性名 | 説明 | 
|---|---|
| dn | 識別名 | 
| objectClass | オブジェクトクラス | 
| c | 国名 | 
| cn | 一飯名称 | 
| dc | ドメイン構成要素 | 
| メールアドレス | |
| 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 | ディレクトリ管理者のパスワードを指定する | 
| directory | LDAPデータベースの格納ディレクトリのパス指定 | 
| 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 * noneLDAPの起動
slapdの起動は以下のようにする。
/usr/local/etc/libexex/slapdSysVinitのシステムでは以下のように起動。
/etc/init.d/slapd startsystemdのシステムでは以下の通り。
systemctl start slapd.serviceslappasswdコマンド
slapd.confファイルのrootpwに関する管理者パスワードを作成するコマンド。
サーバ管理者のパスワードをハッシュ化して生成する。
slappasswdslapcatコマンド
LDAPデータベースの内容をLDIF形式で出力するコマンド。
slapcat > ldapdb.ldifslaptestコマンド
設定ファイルslapd.confの構文をチェックするコマンド。
slaptestslapaddコマンド
LDIFデータをLDAPデータベースにリストアするコマンド。
slapadd -l ldapdb.ldif| オプション | 説明 | 
|---|---|
| -v | 詳細表示 | 
| -d 数 | デバッグレベルの指定 | 
| -f ファイル | 設定ファイルの指定 | 
| -c | エラー時も処理を継続 | 
| -n 数 | 使用するデータベースをDB番号で指定 | 
| -b DN | 使用するデータベースをDNで指定 | 
slapindexコマンド
データベースのインデックスを再構築するコマンド。 slapaddコマンドの後に実行する。
slapindexLDAPクライアントの利用
LDAPクライアントコマンドには以下のようなコマンドがある。
| コマンド | 説明 | 
|---|---|
| ldapadd | エントリを追加する | 
| ldapsearch | エントリを検索する | 
| ldapdelete | エントリを削除する | 
| ldapmodify | エントリを変更する | 
| ldappasswd | パスワードを変更する | 
ldapaddコマンド
エントリを追加するコマンド。
追加するには/tmp/test.ldifにLDIFで記述してからコマンドを実行して追加する。
ldapadd <オプション>| オプション | 説明 | 
|---|---|
| -h ホスト | LDAPサーバの指定(デフォルトはローカルホスト) | 
| -x | SASLを使わず簡易認証を用いる | 
| -D バインドDN | 認証に利用するDNを指定する | 
| -W | 認証時のパスワードを対話的に入力する | 
| -w パスワード | 認証時のパスワードを指定する | 
| -f ファイル名 | LDIFファイルの指定 | 
ldapdeleteコマンド
LDAPサーバに登録されたエントリを削除するコマンド
ldapdelete ldapsearchコマンド
エントリを検索するコマンド。
ldapsearch <オプション> 検索フィルタ <出力属性>| オプション | 説明 | 
|---|---|
| -h ホスト | LDAPサーバの指定 | 
| -H URI | LDAPサーバの指定をldapurlで指定 | 
| -x | SASLを使わず簡易認証を用いる | 
| -D バインドDN | 検索を開始するDNを指定する | 
| -L | 検索結果をLDIFv1形式で表示する | 
| -LL | 検索結果をコメントなしで表示する | 
| -LLL | 検索結果をコメントとLDAPバージョン表示なしで表示する | 
| -b 識別名 | 検索開始位置の指定 | 
ldapsearchコマンド
LDAPサーバのエントリを検索するコマンド。
ldapsearch [オプション] 検索条件 [出力属性]| オプション | 説明 | 
|---|---|
| -h ホスト名/IPアドレス | 検索を行うLDAPサーバを指定 | 
| -H URI | 検索を行うLDAPサーバをldapuri形式で指定 | 
| -x | SASLを使用せずに簡易認証を行う | 
| -b 識別名 | 検索開始位置の指定 | 
| -L | 検索結果をLDIFv1形式で表示 | 
| -LL | 検索結果をコメントなしで表示 | 
| -LLL | 検索結果をコメントとLDAPバージョン表記なしで表示 | 
slapd-config
OpenLDAP2.3以降の設定方法はslapd-configと呼ばれる。
この方法ではLDAPのデータベース(ディレクトリ)に保存されている設定データを追加・変更・削除等することで、動的に設定を更新する。
これはディレクトリベースの設定と呼ばれ、通常は設定変更による再起動等が不要となる。
また、設定データベースのツリー構造のルートは、DN(識別名)がcn=configで定義され、変更できない。
設定を行う際は設定用のLDIFファイルを定義し、ldapadd、ldapdelete、ldapmodifyといったコマンドにより、データベースを更新する。
グローバルセクションに使用する主なディレクティブ
グローバルセクションに使用する主なディレクティブは以下の通り。
| slapd.confディレクティブ | slapd-configディレクティブ | 説明 | 
|---|---|---|
| argsfile ファイル名 | olcArgsFile | slapdデーモン起動時のコマンド引数を格納するファイルの指定 | 
| pidfile ファイル名 | olcPidFile | slapdのプロセスIDを格納するファイルの指定 | 
| include ファイル名 | olcInclude | 読み込む設定ファイルのを指定 | 
| logfile ファイル名 | olcLogFile | デバックログの出力ファイルを指定 | 
| loglevel 数 | olcLogLevel | ログレベルの指定 | 
| idletimeut 秒数 | olcIdleTimeout | アイドル状態のクライアント接続を強制的に切断するまでの秒数指定 | 
| timelimit 秒数 | olcTimeLimit | slapdが検索要求の応答に使う最大秒数の指定 | 
データベースセクションで使用する主なディレクティブ
slapd.confとslapd-configのデータベースセクションで使用する主なディレクティブの対応表は以下の通り。
| slapd.confディレクティブ | slapd-configディレクティブ | 説明 | 
|---|---|---|
| database 種類 | orcDatabase | バックエンドデータベースの種類を指定 | 
| suufix DN | orcSuffix | ディレクリのトップとなるDNの指定 | 
| rootdn DN | orcRootDN | データベース管理者のDNの指定 | 
| rootpw パスワード | orcRootPW | データベース管理者のパスワードを指定 | 
| index 属性名 種類 | orcDbindex | 属性に作成するインデックスの種類の指定 | 
| dircetory ディレクトリ | orcDbDirectory | データベースファイルを格納するディレクトリの指定 | 
slapd-configで使用される基本的なディレクティブ
slapd-configで使用される基本的なディレクティブは以下の通り。 なお「olc」という文字は「OpenLDAP Configuration」の略となる。
| ディレクティブ | 説明 | 定義されるエントリと説明 | 
|---|---|---|
| orcLogLevel | syslogに出力するレベル指定 orcLogLevel: | cn=config サーバ全体に適用 必須オブジェクトクラス: orcGlobal | 
| orcInclude | includeファイルを指定 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 = truesssdサービスはsystemctl start sssd.serviceで可能。
また/etc/nsswitch.confで以下のようにSSSDを参照するようにする。(sssと記述する)
passwd: files sss
shadow: files sss
group:  files sss