CentOS7でOpenldap構築 - 2.LDAPサーバ構築手順

　Openldapを用いたLDAPサーバの構築手順を記載します
　※本記事はもともとLDAPサーバ、クライアントの構築手順を記載していましたが、思いのほか閲覧している方がいたため、きちっとした連載記事に作成し直しました。
　他の記事のリンクとなります。
[1.Openldapの仕組み](https://qiita.com/y-araki-qiita/items/0c954c3ae25d4ed9dbb8)
2.LDAPサーバ構築手順 ※本記事
[3.LDAPクライアント設定手順](https://qiita.com/y-araki-qiita/items/b0f3b291011d1e55d95f)
[4.LDAPディレクトリ構成例とACLの設定](https://qiita.com/y-araki-qiita/items/bc874aeb40ede9c5368c)
[5.バックアップリストアテスト](https://qiita.com/y-araki-qiita/items/ad000141c3fccaef7167)
[6.パスワード有効期限切れ通知スクリプト(おまけ)]()

　現在推奨されているOLC方式で構築します。OLC方式とは元来のslapd.confに設定を記載する方ではなく、LDIFファイルという設定ファイルを作成する方法です。またLDAPアカウント管理ツールとしてLAM(LdapAccountManager)を使います。

　dnはdc=test,dc=orgとします。[前回の記事](https://qiita.com/y-araki-qiita/items/0c954c3ae25d4ed9dbb8)の構成や知識を前提としているため、読んでいただけるとわかりやすいです。

## 前提
・OSはCentOS7です。
・selinuxを無効化しておきます。

## LDAPサーバ構築
rootユーザでの作業です。
　※LDIFファイルの設定は---から---までを記載してくださいという意味です。LDIFファイルは、行末に半角スペースが混じっているだけで設定投げてもエラーになります。ldapコマンドの前に確認したほうがよいかもしれません。

### OpenLDAPインストール
```
yum install openldap openldap-servers openldap-clients
```

### DB設定ファイル用意
```
cp -p /usr/share/openldap-servers/DB_CONFIG.example /var/lib/ldap/DB_CONFIG

# オーナー変更
chown ldap. /var/lib/ldap/DB_CONFIG
```

### slapd起動、自動起動有効
```
systemctl start slapd
systemctl enable slapd
```

### ファイルディスクリプタ上限値の設定
　LDAPサーバはセッション数が多く、ファイルディスクリプタの数が非常に増えます。
Linuxではデフォルト上限値が1024であり、その値に到達するとそれ以上LDAPログイン不可となるためこの設定が必要です。

```
# 確認
grep "Max open files" /proc/`pidof slapd`/limits
※以下のように表示されること
---
Max open files            1024                 4096                 files
---

# 設定
vi /usr/lib/systemd/system/slapd.service
※[Service]の箇所の一番下に追加
---
LimitNOFILE=65536
LimitNPROC=65536
---

# デーモン読み込み、再起動
systemctl daemon-reload
systemctl restart slapd

# 確認
grep "Max open files" /proc/`pidof slapd`/limits
※以下のように表示されること
---
Max open files            65536                65536                files
---

# OS再起動しても上限値が65536であることを確認する
shutdown -r now
grep "Max open files" /proc/`pidof slapd`/limits
```

### ログ設定
LDAPはログが滝のように出力されるため必ずローテートの設定をします。

```
vi /etc/rsyslog.conf
※以下追記
---
local4.* /var/log/slapd/slapd.log
---

# rsyslog再起動
systemctl restart rsyslog

# ログローテート設定
vi /etc/logrotate.d/syslog
※以下追記
---
/var/log/slapd/slapd.log
---
```

### 設定管理者の設定
```
# 設定管理者パスワード生成　※パスワードは例
slappasswd
New password: 1111qqqq
Re-enter new password: 1111qqqq
※暗号化されたパスワードをメモに控える
{SSHA}aaaaaaaaaaaa111111111111111

# LDIF作業用ディレクトリ作成
mkdir /root/ldif

# 設定管理者追加用LDIF作成
vi /root/ldif/rootdn.ldif
※olcRootPWに先ほどメモしたパスワードを記載
---
dn: olcDatabase={0}config,cn=config
changetype: modify
add: olcRootDN
olcRootDN: cn=admin,cn=config
-
add: olcRootPW
olcRootPW: {SSHA}aaaaaaaaaaaa111111111111111
---

# 設定管理者設定追加
ldapmodify -Y EXTERNAL -H ldapi:/// -f /root/ldif/rootdn.ldif
```

### 標準スキーマ追加
　LDAPで使う属性の集まりみたいなものを投入します。ldapコマンドを叩くたび先ほどの設定管理者パスワードを入力します。

```
ldapadd -x -W -D cn=admin,cn=config -f /etc/openldap/schema/cosine.ldif
ldapadd -x -W -D cn=admin,cn=config -f /etc/openldap/schema/nis.ldif
ldapadd -x -W -D cn=admin,cn=config -f /etc/openldap/schema/inetorgperson.ldif
ldapadd -x -W -D cn=admin,cn=config -f /etc/openldap/schema/ppolicy.ldif

# スキーマ確認
ldapsearch -x -LLL -W -D cn=admin,cn=config -b cn=schema,cn=config dn
※dn: cn={1}cosine,cn=schema,cn=config など投入したスキーマが表示されること。
```

### ディレクトリマネージャーの設定
```
# ディレクトリマネージャパスワード生成
slappasswd
New password: 1111aaaa
Re-enter new password: 1111aaaa
※暗号化されたパスワードをメモに控える
{SSHA}11111111111111111aaaaaaaaaaaaaaaaaaa

# 設定変更用LDIF作成
vi /root/ldif/hdbconfig.ldif
※olcRootPWに先ほどメモしたパスワードを記載。olcAccessの箇所でACL(ディレクト毎のアクセス制御)を設定しているのですが、後々変更するので一時的なものです。
---
dn: olcDatabase={1}monitor,cn=config
changetype: modify
replace: olcAccess
olcAccess: {0}to * by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" read by dn.base="cn=admin,dc=test,dc=org" read by * none

dn: olcDatabase={2}hdb,cn=config
changetype: modify
replace: olcSuffix
olcSuffix: dc=test,dc=org
-
replace: olcRootDN
olcRootDN: cn=admin,dc=test,dc=org
-
add: olcRootPW
olcRootPW: {SSHA}11111111111111111aaaaaaaaaaaaaaaaaaa
-
add: olcAccess
olcAccess: {0}to dn.sub="ou=tool,dc=test,dc=org" attrs=userPassword,shadowLastChange by self write by anonymous auth by dn.sub="ou=user,dc=test,dc=org" write by dn.sub="ou=tool,dc=test,dc=org" write by users none
olcAccess: {1}to attrs=userPassword,shadowLastChange by self write by anonymous auth by dn.sub="ou=user,dc=test,dc=org" write by users none
olcAccess: {2}to by dn.sub="ou=user,dc=test,dc=org" write by read
---

# 設定変更
ldapmodify -x -W -D cn=admin,cn=config -f /root/ldif/hdbconfig.ldif

# 設定確認
ldapsearch -x -LLL -W -D cn=admin,cn=config -b cn=config olcDatabase={1}monitor
ldapsearch -x -LLL -W -D cn=admin,cn=config -b cn=config olcDatabase={2}hdb
```

### 初期データ用LDIF作成
　簡単なディレクトリ構成の初期データを投入します。投入時はディレクトリマネージャーのパスワードを入力します。
※ldapコマンドのオプションにcn=admin,cn=configとある場合は設定管理者、
　cn=admin,dc=test,dc=orgとある場合はディレクトリマネージャーです。

```
vi /root/ldif/init.ldif
---
dn: dc=test,dc=org
objectClass: top
objectClass: dcObject
objectClass: organization
o: Infra
dc: test

dn: ou=group,dc=test,dc=org
objectclass: organizationalUnit
ou: group

dn: ou=user,dc=test,dc=org
objectclass: organizationalUnit
ou: user

dn: cn=infra,ou=group,dc=test,dc=org
objectclass: posixGroup
gidNumber: 10000
cn: infra

dn: cn=users,ou=group,dc=test,dc=org
objectclass: posixGroup
gidNumber: 10001
cn: users
---

# 初期データ投入
ldapadd -x -W -D cn=admin,dc=test,dc=org -f /root/ldif/init.ldif

# 初期データ確認
ldapsearch -x -LLL -W -D cn=admin,dc=test,dc=org -b dc=test,dc=org
```

### オーバーレイ追加用LDIFファイル作成
```
vi /root/ldif/ppolicyoverlay.ldif
---
dn: olcOverlay=ppolicy,olcDatabase={2}hdb,cn=config
objectClass: olcOverlayConfig
objectClass: olcPPolicyConfig
olcOverlay: ppolicy
olcPPolicyDefault: cn=default,ou=Policies,dc=test,dc=org
---

# オーバーレイ追加
ldapadd -x -W -D cn=admin,cn=config -f /root/ldif/ppolicyoverlay.ldif
```

### パスワードポリシー設定
```
#モジュール追加用LDIFファイル作成
vi /root/ldif/ppolicymodule.ldif
---
dn: cn=module,cn=config
objectClass: olcModuleList
cn: module
olcModulePath: /usr/lib64/openldap
olcModuleLoad: ppolicy.la
---

# モジュール追加
ldapadd -x -W -D cn=admin,cn=config -f /root/ldif/ppolicymodule.ldif

# パスワードポリシーエントリ用LDIFファイル作成
※各項目の意味については後で図示。
vi /root/ldif/ppolicy.ldif
---
dn: ou=policies,dc=test,dc=org
objectClass: top
objectClass: organizationalUnit
ou: policies

dn: cn=default,ou=policies,dc=test,dc=org
cn: default
objectClass: top
objectClass: device
objectClass: pwdPolicy
objectClass: pwdPolicyChecker
pwdCheckModule: check_password.so
pwdAttribute: userPassword
pwdLockout: TRUE
pwdMaxFailure: 5
pwdLockoutDuration: 300
pwdCheckQuality: 1
pwdMinLength: 8
pwdSafeModify: FALSE
pwdMaxAge: 7776000
pwdExpireWarning: 604800
pwdInHistory: 2
pwdGraceAuthNLimit: 0
pwdMustChange: TRUE
---

# パスワードポリシー設定追加
ldapadd -x -W -D cn=admin,dc=test,dc=org -f /root/ldif/ppolicy.ldif

# パスワードチェックモジュール設定変更
vi /etc/openldap/check_password.conf
---
useCracklib 0
minPoints 0
minUpper 1
minLower 1
minDigit 1
minPunct 0
---
```
#### ※パスワードポリシーについて各項目の説明
<img width="497" alt="キャプチャ4.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131627/7521cda3-f4d8-3410-66cd-91fdda155d3f.png">

### SSH公開鍵認証設定
```
# LDAPアカウントSSH用パッケージインストール
yum install openssh-ldap

# SSHスキーマ追加用LDIF作成
vi /root/ldif/openssh-lpk-openldap.ldif
---
dn: cn=openssh-lpk-openldap,cn=schema,cn=config
objectClass: olcSchemaConfig
cn: openssh-lpk-openldap
olcAttributeTypes: ( 1.3.6.1.4.1.24552.500.1.1.1.13 NAME 'sshPublicKey' DESC 'MANDATORY: OpenSSH Public key' EQUALITY octetStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )
olcObjectClasses: ( 1.3.6.1.4.1.24552.500.1.1.2.0 NAME 'ldapPublicKey' DESC 'MANDATORY: OpenSSH LPK objectclass' SUP top AUXILIARY MUST ( sshPublicKey $ uid ) )
---

# スキーマ追加
ldapadd -x -W -D cn=admin,cn=config -f /root/ldif/openssh-lpk-openldap.ldif

# スキーマ確認
ldapsearch -x -LLL -W -D cn=admin,cn=config -b cn=schema,cn=config dn
```

### テストユーザ追加
あとでLDAPクライアント設定時にログインを試す用のユーザです。

```
# ユーザエントリにsshPublickey属性と公開鍵追加
vi /root/ldif/test-admin.ldif
---
dn: cn=test-admin,ou=user,dc=test,dc=org
objectClass: posixAccount
objectClass: inetOrgPerson
objectClass: organizationalPerson
objectClass: person
homeDirectory: /home/test-admin
loginShell: /bin/bash
uid: test-admin
cn: test-admin
uidNumber: 10000
gidNumber: 10000
sn: test
o: Infra
description: Infra
---

# 追加
ldapadd -x -W -D cn=admin,dc=test,dc=org -f /root/ldif/test-admin.ldif

# 鍵作成
ssh-keygen -t rsa

# sshPublickey属性追加
vi /root/ldif/add_sshpubkey.ldif
※作成した公開鍵を記載。sshPublicKeyのパラメータは""でくくらない。
---
dn: cn=test-admin,ou=user,dc=test,dc=org
changetype: modify
add: objectClass
objectClass: ldapPublicKey
-
add: sshPublicKey
sshPublicKey: ssh-rsa AAAABx3cffdjjjjdnL........RGLddafsafo7aJl5Q==
---
# ユーザエントリ編集
ldapmodify -x -W -D "cn=admin,dc=test,dc=org" -f /root/ldif/add_sshpubkey.ldif

# ユーザエントリ確認
ldapsearch -x -LLL -W -D cn=admin,dc=test,dc=org -b dc=test,dc=org uid=test-admin
```
　ldapコマンドでOpenldapを構築してきましたが、ldapaddやldapmodifyでデータを投入し、ldapsearchで確認の繰り返しが面倒に感じたかもしません。
　
## LAM(LdapAccountManager)のインストールと設定
　ただこのLAMをインストールしてしまえば、GUIでLDAPの構成変更が可能です。LAMで操作すればサーバ内でldapコマンドが走っているのと同じことなので、正直サーバでの構築に多少失敗してもこちらで修正できます。

### LAMインストール
```
# 作業ディレクトリ作成
mkdir /root/work
cd /root/work

# LAMパッケージダウンロード
wget https://sourceforge.net/projects/lam/files/LAM/6.6/ldap-account-manager-6.6-0.fedora.1.noarch.rpm/download

## PHP 7.2 インストール
# EPELリポジトリ
yum install epel-release
# Remiリポジトリ
rpm -Uvh http://rpms.famillecollet.com/enterprise/remi-release-7.rpm

# インストール
yum install --enablerepo=remi,remi-php72 php php-ldap php-json php-zip php-json php-zip php-xml

# LAMインストール
rpm -Uvh download
```

### SSL化
とりあえずオレオレ証明書設定するだけなので、必要ないと思う方はやらなくてOKです。

```
# mod sslインストール
yum install mod_ssl

#作業ディレクトリ
mkdir /etc/httpd/ssl
cd /etc/httpd/ssl
# 秘密鍵作成
openssl genrsa -aes128 2048 > server.key
# 秘密鍵パスフレーズ解除
openssl rsa -in server.key -out server.key
# CSR作成
openssl req -new -key server.key > server.csr
# 証明書作成
openssl x509 -req -days 3650 -signkey server.key < server.csr > server.crt
# パーミッション変更
chmod 400 /etc/httpd/ssl/server.*

# 設定変更
vi /etc/httpd/conf.d/ssl.conf
※以下2箇所編集
---
SSLCertificateFile /etc/httpd/ssl/server.crt
SSLCertificateKeyFile /etc/httpd/ssl/server.key
---
# HTTP→HTTPSリダイレクト設定
vi /etc/httpd/conf.d/rewrite.conf
---
<ifModule mod_rewrite.c>
RewriteEngine On
LogLevel crit rewrite:trace3
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%\{HTTP_HOST}%{REQUEST_URI} [R=301,L]
</ifModule>
---

# Apache起動
systemctl restart httpd

# 動作確認
ブラウザからhttps://LDAPサーバIP/lamにアクセスしてダッシュボードが表示されること。
```

### LAMの設定

```
# プロファイル設定
vi /var/lib/ldap-account-manager/config/config.cfg
※デフォルトプロファイル(lam)から変更する場合は任意のプロファイル名にする
---
default: admin
---

#config.cfgで設定したプロファイル名にする
cp -p /var/lib/ldap-account-manager/config/lam.conf /var/lib/ldap-account-manager/config/admin.conf
vi /var/lib/ldap-account-manager/config/admin.conf
---
Admins: cn=admin,dc=test,dc=org
treesuffix: dc=test,dc=org
defaultLanguage: ja_JP.utf8
types: suffix_user: ou=user,dc=test,dc=org
types: suffix_group: ou=group,dc=test,dc=org
---

# Apache再起動
systemctl restart httpd
```

## LAMのブラウザでの設定
　LAMにアクセスし直してトップ画面右上の「LAM構成設定」で初期設定をします。いろいろ眺めていじってみてください。
<img width="459" alt="キャプチャ.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131627/2387acfe-b1b8-5edf-c835-cc9a659f1bd3.png">


・LAM構成設定→サーバープロファイルの編集→サーバープロファイルの操作→プロファイルパスワード設定で任意のパスワードに変更→最下部OK。
※マスターパスワードはデフォルトはlamです。

・LAM構成設定→サーバープロファイルの編集→変更したパスワード入力→OK→以下修正
1.サーバーアドレス (必要ないかも)
2.タイムゾーン → Asia/Tokyo
3.ログイン方法 
　※最初は固定リストでディレクトリマネージャー(uidはadmin)でLAMにログインできるようにして、ディレクトリツリーを作成してから、LDAP検索に変更して任意のouのユーザでログインできるよう変更するとよいと思います。

・LAM構成設定→サーバープロファイルの編集→変更したパスワード入力→アカウント種別タブ
1.ホストとSambaドメインを"×"で消す。
2.ユーザのLDAPサフィックスを dc=test,dc=org にする。

・LAM構成設定→サーバープロファイルの編集→変更したパスワード入力→モジュールタブ
モジュールを選択し以下のようにする。
※ユーザ
<img width="364" alt="キャプチャ3.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131627/b12e9a07-a00f-5d79-34e9-a2fb26697538.png">
※グループ
<img width="361" alt="キャプチャ4.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131627/bac0b654-3ed7-7728-cc72-6d6f36bc73c0.png">

・LAM構成設定→サーバープロファイルの編集→変更したパスワード入力→モジュール設定タブ
1.ユーザのUID番号の最大値、最小値を入力
2.グループのGID番号の最大値、最小値を入力

最後ディレクトリマネージャーのアカウントでLAMにログインしてみます。
ユーザ:admin
パスワード:ディレクトリマネージャーに設定したパスワード
<img width="750" alt="キャプチャ5.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131627/a7174d9a-7bde-3ff2-b7e2-ffae6f5edebc.png">

　このように表示されたらOKです(「あ」と表示されなくてOKです)。ここでユーザやグループを追加できます。また上部「ツリービュー」をクリックするとユーザ、グループの追加修正だけでなくディレクトリツリーの構成も変更することができます。

　次回はLDAPクライアントを設定し、LDAPログインを試します。
[・CentOS7でOpenldap構築 - 3.LDAPクライアント設定手順](https://qiita.com/y-araki-qiita/items/b0f3b291011d1e55d95f)

と締めくくるところでしたが、おまけです。
## auditlogモジュール追加
　LDAPアカウントを追加削除したりディレクトリの内容を変更した時のログをきっちり残したほうがよいため、auditログモジュールを追加します。

```
# auditファイルの作成 ※ディレクトリは任意
mkdir -p /data/log
touch /data/log/ldap_audit.log
chown ldap:ldap /data/log/ldap_audit.log
 
# auditlogモジュールの追加 ※ヒアドキュメントでやってみました。
cat << 'EOT' | ldapmodify -x -D "cn=admin,cn=config" -w 設定管理者パスワード
dn: cn=module{0},cn=config
changetype: modify
add: olcModuleLoad
olcModuleLoad: auditlog.la
EOT
 
#モジュール番号確認
ldapsearch -x -D "cn=admin,cn=config" -b 'cn=module{0},cn=config' -w 設定管理者パスワード | grep auditlog.la
※モジュール番号は上記コマンド結果の{ }auditlog←括弧内の番号
 
#auditの設定
※{ }auditlogに番号入れる。
cat << 'EOT' | ldapmodify -x -D "cn=admin,cn=config" -w 設定管理者パスワード
dn: olcOverlay={1}auditlog,olcDatabase={2}hdb,cn=config
changetype: add
objectClass: olcOverlayConfig
objectClass: olcAuditlogConfig
olcOverlay: {1}auditlog
olcAuditlogFile: /data/log/ldap_audit.log
EOT

# ログローテート設定 ※あくまで例です。
vi /etc/logrotate.d/ldapaudit
---
/data/log/ldap_audit.log {
    ifempty            
    dateformat .%Y%m%d 
    missingok          
    compress           
    daily
    rotate 7
    postrotate
        /bin/kill -HUP `cat /var/run/syslogd.pid 2> /dev/null` 2> /dev/null || true
    endscript
}
---

logrotate -dv /etc/logrotate.d/ldapaudit
logrotate -f /etc/logrotate.d/ldapaudit
```

おしまい。

## 関連記事
[・CentOS7でOpenldap構築 - 1.Openldapの仕組み](https://qiita.com/y-araki-qiita/items/0c954c3ae25d4ed9dbb8)
[・CentOS7でOpenldap構築 - 2.LDAPサーバ構築手順](https://qiita.com/y-araki-qiita/items/6b2dcbf1a39a969d8024)
[・CentOS7でOpenldap構築 - 3.LDAPクライアント設定手順](https://qiita.com/y-araki-qiita/items/b0f3b291011d1e55d95f)
[・CentOS7でOpenldap構築 - 4.LDAPディレクトリ構成例とACLの設定](https://qiita.com/y-araki-qiita/items/bc874aeb40ede9c5368c)
[・CentOS7でOpenldap構築 - 5.バックアップリストアテスト](https://qiita.com/y-araki-qiita/items/ad000141c3fccaef7167)
[・CentOS7でOpenldap構築 - 6.パスワード有効期限切れ通知スクリプト](https://qiita.com/y-araki-qiita/items/65103497c2ce0ad63d24)