ActiveDirectoryをLDAPS(LDAP over SSL/TLS)で接続できるようにする。

# はじめに
通信はセキュアにかぎる。
いついかなるときも、とは限りませんが、セキュアな方法を知っておいて損はない。

# LDAPSとは
LDAP通信をSSL/TLSで保護します。
以上。

# ActiveDirectoryでLDAPSを構築する
面倒なことはしたくないので、ActiveDirectory証明機関をインストールします。
こんな感じでインストールできればOK
[![Screenshot from Gyazo](https://gyazo.com/649334cc29c64761bc19c892fe51483b/raw)](https://gyazo.com/649334cc29c64761bc19c892fe51483b)

コマンドプロンプトで `ldp` をタイプすると、LDPが起動します。
メニューから 接続 -> 接続 -> と選択し、ダイアログを表示させ、
サーバー：localhost　ポート：636　SSLにチェック として OK をクリックします。
[![Screenshot from Gyazo](https://gyazo.com/e62c938c4c19e4307bfeea08e06ee62a/raw)](https://gyazo.com/e62c938c4c19e4307bfeea08e06ee62a)

こんな感じで表示されれば、無事にLDAPSで接続されました。
[![Screenshot from Gyazo](https://gyazo.com/7c27e06a126b7fce1a16c5fd9f115902/raw)](https://gyazo.com/7c27e06a126b7fce1a16c5fd9f115902)

AD上でIISが稼働している場合、公開用にサーバ証明書が存在している場合もあります。
どの証明書が利用されるのか、というと、以下の説明の通りです。

> 最後に、Windows Server 2008 またはそれ以降のバージョンのドメインコントローラーで、ストア内で複数の証明書が検出された場合は、有効期限日が最も遠い証明書が自動的に選択されます。 現在の証明書の有効期限が近づいている場合は、その証明書をストアにドロップすることができます。また、AD DS は自動的に使用に切り替えます。 これらの機能はすべて、Windows Server 2008 AD DS と、2008 Active Directory ライトウェイトディレクトリサービス (AD LDS) に対応しています。 AD LDS の場合は、NTDS サービスではなく、広告 LDS インスタンスに対応するサービスの個人証明書ストアに証明書を配置します。

出典：https://support.microsoft.com/ja-jp/help/321051/how-to-enable-ldap-over-ssl-with-a-third-party-certification-authority


ちなみに、当方の環境では、以下のような証明書がインストールされていました。
サーバー証明書のうち、最も有効期限の長い４番目のものが利用されることとなります。
（２番目のものはルートCAそのものの証明書なので今回用途には使われないようになるみたいですね）
[![Screenshot from Gyazo](https://gyazo.com/409f52b3aeeed2dfc7152a42d199797e/raw)](https://gyazo.com/409f52b3aeeed2dfc7152a42d199797e)

# Linuxのldapsearchから接続してみる

## 証明書の確認
LDAPSで接続した際の証明書は以下で確認できます。

```shell-session
# openssl s_client -connect vmwinserv11.prosper2.net:636  | head
depth=0 CN = VMwinserv11.prosper2.net
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 CN = VMwinserv11.prosper2.net
verify error:num=21:unable to verify the first certificate
verify return:1
CONNECTED(00000003)
---
Certificate chain
 0 s:CN = VMwinserv11.prosper2.net
   i:C = JP, ST = Tokyo, O = Prosper2, CN = Prosper2 Root CA G2
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIFIDCCBAigAwIBAgITSQAAAAx9yrhMOfguVwAAAAAADDANBgkqhkiG9w0BAQsF
ADBOMQswCQYDVQQGEwJKUDEOMAwGA1UECBMFVG9reW8xETAPBgNVBAoTCFByb3Nw
^C  (待ち受けっぱなしになるので ctrl-c で抜けます）
```
サーバ証明書が確認できましたが、前述した「個人」->「証明書」のストアにあるルートCA証明書はチェインされていないようです。
上位CAは自動的にチェインしてくれてもよさそうですが、そうなっていないようですので、後述の **[証明書の保管](#証明書の保管)** で上位CAを保管しておきましょう。

ちなみに、同じサーバでIISが稼働しており、HTTPSが待ち受けています。
同じようにopensslで接続してみると、IISでバインドされたとおりの証明書でした。
（LetsEncryptで取得したものになっています）

```shell-session
# openssl s_client -connect vmwinserv11.prosper2.net:443  | head
depth=2 O = Digital Signature Trust Co., CN = DST Root CA X3
verify return:1
depth=1 C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
verify return:1
depth=0 CN = *.prosper2.net
verify return:1
CONNECTED(00000003)
---
Certificate chain
 0 s:CN = *.prosper2.net
   i:C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
 1 s:C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
   i:O = Digital Signature Trust Co., CN = DST Root CA X3
---
Server certificate
-----BEGIN CERTIFICATE-----
^C  (待ち受けっぱなしになるので ctrl-c で抜けます）
```

## 上位CA証明書の保管
LDAPSのサーバ証明書を保管しておいてもよいけれど、対向先のサーバ数が増えた場合に面倒です。
プライベートPKIを構築しているのであれば、上位CAなどチェインをたどれる証明書を保管しておきましょう。
うまいやりかたが見つからなかったので、以下のように証明機関からルートCAを表示させ、エクスポートします。
（IISのサーバにHTTPSで接続しても、LetsEncryptの証明書なので、プライベートPKIのルートまでたどれないのです。。。）

証明機関のツリーからルートCAの名称を右クリック（図の場合は、Prosper2 Root CA G2）→プロパティをクリック。
「全般」タブの「証明書の表示」をクリックし、証明書のプロパティの「詳細」タブの「ファイルにコピー」をクリック。
[![Screenshot from Gyazo](https://gyazo.com/605ad573a51de2555ec0e94078030f7a/raw)](https://gyazo.com/605ad573a51de2555ec0e94078030f7a)

Base64 形式でファイルにエクスポートしたものを、メモ帳などで開いて、すべて選択しコピーします。
Linuxの `/etc/openldap/certs` に適当な名前でファイルをつくり、ペーストします。
（証明書を配置するディレクトリは別の場所でも構いません。後ほどの設定でディレクトリ指定します。）
[![Screenshot from Gyazo](https://gyazo.com/fe1181ff90c24aba5d9ce1b9f0784382/raw)](https://gyazo.com/fe1181ff90c24aba5d9ce1b9f0784382)

## LDAPクライアントの設定
ldapsearchコマンドを前提に説明します。
ldapsearchが無い場合は、 `yum -y install openldap-clients` でインストールします。

前述の証明書を配置したディレクトリが、デフォルト以外の場所であれば、以下の設定ファイルを修正します。

```:/etc/openldap/ldap.conf
--------8<----(snip)----8<--------
TLS_CACERTDIR   /etc/openldap/certs
--------8<----(snip)----8<--------
```

検索用ユーザ `searchuser` とフィルタ表示ユーザ `soumu.taro` は **[squidでActiveDirectory連携とSSLインターセプトするProxyをdockerで手軽につくる](https://qiita.com/bashaway/items/6adc75265973de9b5fcc)** で作成したものです。

```shell-session
# ldapsearch  -b "dc=prosper2,dc=net" -D searchuser@prosper2.net -w s3arch#PWD -H "ldaps://vmwinserv11.prosper2.net"  "sAMAccountName=soumu.taro" | head -n 20
---
# extended LDIF
#
# LDAPv3
# base <dc=prosper2,dc=net> with scope subtree
# filter: sAMAccountName=soumu.taro
# requesting: ALL
#

# soumu taro, employee, prosper2.net
dn: CN=soumu taro,OU=employee,DC=prosper2,DC=net
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: user
cn: soumu taro
sn: soumu
givenName: taro
distinguishedName: CN=soumu taro,OU=employee,DC=prosper2,DC=net
（～以下省略～）
```

ちなみに、うまいこと証明書の確認がとれない場合はこうなります。

```shell-session
# ldapsearch  -b "dc=prosper2,dc=net" -D searchuser@prosper2.net -w s3arch#PWD -H "ldaps://vmwinserv11.prosper2.net"  "sAMAccountName=soumu.taro"
ldap_sasl_bind(SIMPLE): Can't contact LDAP server (-1)
```

# 出典
https://support.microsoft.com/ja-jp/help/321051/how-to-enable-ldap-over-ssl-with-a-third-party-certification-authority
`# man ldapsearch`
`# man ldap.conf`