Oracle Databaseの認証をActive Directoryで行う①

Oracle DBのActive Directory認証は、以前はOracle Internet Directoryというディレクトリ製品を経由した連携が必要でしたが、18cからはCentrally Managed Usersとして直接Active Directoryのパスワード認証が可能となりました。
データベース・ユーザーは、グローバルユーザーでActive Directoryにマッピングするように作成し、通常のパスワード認証と同様に接続します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562423/dcca1d23-9ac9-a7b5-87ed-a101ed4858f0.png)


マニュアルを読んでイチから環境構築していくのは正直かなり苦労します。ここでは私の備忘録という意味合いも含め、とりあえず機能を試せる環境をOracle Cloud上に構築する手順をまとめます。実際のDB環境の設計・構築前に、必要となる設定の流れやAD認証の挙動を確認しておくのが良いと思います。
詰まらないようにセキュリティ関連の設定は緩くしていますので、動作後に少しづつ設定絞って調整して下さい。

## Active Directoryの準備

1. Windows2019のインスタンスを作成, CPU,Memory,Diskサイズはお好みで
2. セキュリティリストで3389をオープンし、リモート接続
3. Administratorユーザーのパスワードを設定する。コンピュータ -> ユーザ -> Administratorを右クリックしてパスワード設定。設定後、ログオフして、Administratorで再ログイン
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562423/6799cc81-b015-9792-980c-73733460247d.png)
4. サーバー・マネージャーからロールと機能の追加を選択し、Active Directory Domain、DNSをインストール追加する。選択後はNextで進めてOK
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562423/dba91a02-71f2-3e27-95a6-4adddbea93fb.png)
5. インストール完了後、ドメインコントローラーの昇格をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562423/79d5e80c-6f8c-3398-1cc3-3b148af719f3.png)
6. ルートドメインを追加(cmutest.com)。以降は、Nextで進めてOK
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562423/2f5dda31-03ac-05f7-a4a5-b464d4e9a9a9.png)
7. DNS Managerから逆引きIPアドレスのゾーン追加しておく。プライベート・サブネットの範囲を追加
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562423/67001c2c-7136-a80a-89cd-ef0711a11253.png)
8. AD Certificateサービスをインストール
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562423/ac851a28-b7b0-29dc-8ddd-92599d591d25.png)
9. AD Certificateサービスの設定。基本的にNextで進めてOK。Root CAになるように。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562423/641b92c0-b046-c555-3424-37ff263219d1.png)
10. ADへのインバウンドトラフィックの許可が必要なので、ここではWindowsのPrivate Firewallは一旦無効にしておく。同様にOCIのセキュリティリストかセキュリティグループでプライベートサブネットのインバウンドをすべて許可にしておく

## Oracle Databaseとの接続に必要なActive Directoryの設定

1. ADとOracleDB間の内部通信で必要なADユーザ(oracleservice)を作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562423/85a3dc98-f5a9-106e-0ed3-77f73cc2f835.png)

2. oracleserviceユーザーに必要な権限を付与
"User"を右クリック -> 管理権限の委任 -> oracleserviceユーザーにFull Controlを付与
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562423/b519aa87-b671-6cd0-5e96-2c7590724691.png)

3. ADでの認証に必要なパスワードフィルタをインストールするための実行プログラム(opwdintg.exe)を以下から入手
My Oracle SupportのドキュメントID 2462012.1
My Oracle Supportのアカウントがない場合は、$ORACLE_HOME/bin以下を参照

4. opwdintg.exeをWindowsで実行。基本はすべてYes、Yesが通らなかった部分はNoでもOK。インストール後、自動的に再起動される
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562423/cc7f4200-356f-ec7b-288c-f65426d4a498.png)

5. OracleDBの設定の際に必要なのでADからTrusted Root CAをダウンロードしておく
管理者としてコマンドプロンプトを起動し、以下のコマンドを実行
certutil -ca.cert root.crt
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562423/af8e23cf-1ec2-c202-3d7c-13c4cb2269ca.png)
実行後に作成されるroot.crtファイルをコピーしておく


## Oracle Databaseの準備
1. Database Cloudの19cのインスタンスを作成
2. PDBのGUIDを取得
SQL> SELECT PDB_NAME,GUID FROM DBA_PDBS;
DB0325_PDB1
<font color="red">DB0937E27B53234CE0535601A8C0A5EB</font>
3. ADへの接続情報を格納するキーストアの位置を確認
ORACLE_BASE/admin/ORACLE_UNQNAME/PDB_GUID/wallet/
今回は、以下の場所に作成する
/u01/app/oracle/admin/<font color="red">DB0325_iad1p9</font>/<font color="red">DB0937E27B53234CE0535601A8C0A5EB</font>/wallet
4. 接続情報をキーストアに格納する
```
#PDBのキーストア用のディレクトリを作成
$ mkdir /u01/app/oracle/admin/DB0325_iad1p9/DB0937E27B53234CE0535601A8C0A5EB/wallet
$ cd /u01/app/oracle/admin/DB0325_iad1p9/DB0937E27B53234CE0535601A8C0A5EB/wallet

#キーストア作成 & ADの情報を登録
$ orapki wallet create -wallet . -pwd WelCome123## -auto_login
$ mkstore -wrl . -createEntry ORACLE.SECURITY.USERNAME oracleservice
$ mkstore -wrl . -createEntry ORACLE.SECURITY.DN cn=oracleservice,cn=users,dc=cmutest,dc=com
$ mkstore -wrl . -createEntry ORACLE.SECURITY.PASSWORD

#事前に作成しておいたroot.crtをこのディレクトリにコピーし、以下を実行
$ orapki wallet add -wallet . -trusted_cert -cert root.crt

#DSIファイル作成を作成し、以下の内容を追記する。IPは、ADのIPアドレス
$ vi dsi.ora
DSI_DIRECTORY_SERVERS = (192.168.1.181:389:636)
DSI_DEFAULT_ADMIN_CONTEXT = "cn=users,dc=cmutest,dc=com"
DSI_DIRECTORY_SERVER_TYPE = AD

#キーストアに登録した内容の確認
$ orapki wallet display -wallet .
Oracle PKI Tool Release 19.0.0.0.0 - Production
Version 19.4.0.0.0
Copyright (c) 2004, 2021, Oracle and/or its affiliates. All rights reserved.

Requested Certificates:
User Certificates:
Oracle Secret Store entries:
ORACLE.SECURITY.DN
ORACLE.SECURITY.PASSWORD
ORACLE.SECURITY.USERNAME
Trusted Certificates:
Subject:        CN=cmutest-WINDOWSAD2019-CA,DC=cmutest,DC=com
```
ldapbindコマンドで、DB->AD間の接続が作成したキーストアの情報で接続できるかを確認
※バインドが失敗する場合は、必ずバインドが成功するまでネットワークやキーストアに登録情報を見直してください。
```
ldapbind -h 192.168.1.181 -p 636 -U 2 \
-W file:/u01/app/oracle/admin/DB0325_iad1p9/DB0937E27B53234CE0535601A8C0A5EB/wallet \
-P walletのpassword \
-D oracleservice \
-w oracleserviceのpasword

bind successful
```

## AD認証の設定と接続テスト

データベースのADパスワード認証の有効化
```
#PDBで実行
SQL> alter system set ldap_directory_access='PASSWORD';
SQL> alter system set ldap_directory_sysauth ='YES' scope=spfile;

#DBを再起動し、tnsnamesで接続できるようにtnsnames.oraを作成しておく
$ cd /u01/app/oracle/product/19.0.0.0/dbhome_1/network/admin
$ vi tnsnames.ora
PDB =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.1.86)(PORT = 1521))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = db0325_pdb1.oracle.com)
    )
  )
```
AD側で接続するユーザー(testusr)を作成
ユーザー作成後に、ORA_VDR_12cグループに追加する。グループに追加後に、必ずtestusrユーザーをパスワード・リセットで再設定する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562423/5a8b8cb3-f7b0-d732-098b-4284f31b80ee.png)


ADユーザーにマッピングするグローバルユーザーをPDBに作成する
```
$ sqlplus / as sysdba
SQL> alter session set container=DB0325_PDB1;
SQL> create user testusr identified globally as 'cn=testusr,cn=users,dc=cmutest,dc=com';
SQL> grant create session to testusr;

接続のテスト
SQL> connect "testusr@cmutest.com"@PDB
Enter password:
Connected.
```
お疲れ様でした。これで基本的な接続設定は完了です。
ただ、一発で接続がうまくいくのは非常に稀だと思います。接続エラーのメッセージだけで問題箇所のあたりをつけるのはかなり困難なので、トレースを出力してトラブルシュートするのが良いです。
```
SQL> alter system set events='trace[gdsi] disk low';
#トレースのディレクトリをgrep
grep -i kzlg *.trc
```

よくあるのが、walletのディレクトリが違う、ADユーザをORA_VDR_12cにグループに追加していない、パスワードが違う/変更していないなどです。
また、トラブルシュートには[この資料](https://cdn.ymaws.com/ukoug.org/resource/collection/904331A4-A794-4730-AC6B-6AB8B1DD1E36/Oracle18c_19c_&_Centrally_Managed_Users_-_DB_U.pdf)が役立ちます。

[次回](https://qiita.com/western24/items/c46e73082b17a2b67eda)は、グループによる権限付与などCentrally Managed Usersの具体的な使い方を紹介します。