1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Oracle Databaseの外部認証 - OCI IAMとBaseDBのトークン・ベースの認証連携① -

Last updated at Posted at 2024-02-01

※2025/7 Base Database内の構成が変わっているようなので、23aiベースで手順を見直し最新化しました。

前回の設定で必要なTLS認証が完了しましたので、実際にIAMとトークン・ベースで認証連携させるためのデータベースの設定やIAMユーザーの作成等を行っていきます。

1. IDENTITY_PROVIDER_TYPEの設定

OCI IAMとの認証連携機能を有効化するためには、データベース側のIDENTITY_PROVIDER_TYPEのパラメータをOCI_IAMに設定する必要がある。

-- Alter System文でIdentity ProviderをIAMに設定
SQL> ALTER SYSTEM SET IDENTITY_PROVIDER_TYPE=OCI_IAM SCOPE=BOTH;
SQL> SELECT NAME, VALUE FROM V$PARAMETER WHERE NAME='identity_provider_type';
NAME                      VALUE
------------------------  -------------
identity_provider_type    OCI_IAM

2. IAMグループとポリシーの作成

IAMトークンを使用してデータベースに接続するためには、そもそもIAMユーザーがBaseDBサービスを使用するための権限をIAMポリシーとして許可されていなければならない。

ここでは、そのサービスを使用できるポリシーを持つdbtoken_grpというグループを作成し、emp1mgr1というユーザーをそのグループに所属させる。

IAMユーザーの作成

  • IAMにemp1mgr1のユーザーを二つ作成する
    image.png

グループとポリシーの作成

  • グループを作成 -> グループ名: dbtoken_grp

  • データベースの権限をグループに付与したポリシーを作成 -> ポリシー名: dbtoken_pol
    allow group dbtoken_grp to use database-connections in tenancy
    allow group dbtoken_grp to use database-family in tenancy
    image.png

  • 作成したグループにemp1とmgr1ユーザーを割り当てる
    image.png

3. クライアントの設定

今回のテストでは、IAMの二つのユーザー(emp1とmgr1)をOCIのコンフィグで切り替えてDBアクセストークンを取得し、それぞれのIAMユーザーのトークンを用いてDBに接続する。そのための必要なOCI Cliの実行環境の設定を行う。

OCI Cliでアクセス・トークンを取得する設定

#clientにopcで接続
#oci cliのインストール
$ sudo pip3 install oci-cli

#oci cliの接続設定
$ oci setup config
Enter a location for your config [/home/opc/.oci/config]: --> Enter
Enter a user OCID: ocid1.user.oc1..xxxxxxxx --> emp1のOCID
Enter a tenancy OCID: ocid1.tenancy.oc1..xxxxx
Enter a region by index or name  
Do you want to generate a new API Signing RSA key pair? (If you decline you will be asked to supply the path to an existing key.) [Y/n]: Y
Enter a directory for your keys to be created [/home/opc/.oci]: --> Enter
Enter a name for your key [oci_api_key]: --> Enter
Enter a passphrase for your private key ("N/A" for no passphrase): -->N/Aと入力

#oci configのPublic Keyをコピー
$ cat /home/opc/.oci/oci_api_key_public.pem 
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxuxnwAZVRFVVi4yVu9BZ
vFifL/KVtMQWoY5pjomLxMgyoYeSydjThxui6EHEbdxGhvo0BgmiWcNFQI603jL1
oXkkUO8+IcNETslW4bffoCwiGrcAlZ/u*****
-----END PUBLIC KEY-----

  • 作成したemp1ユーザーのAPIキーとして追加する
    image.png
#ociコマンドを実行し、結果が表示されればOK
$ oci iam region list --output table
+-----+-------------------+
| key | name              |
+-----+-------------------+
| AMS | eu-amsterdam-1    |
| ARN | eu-stockholm-1    |

IAMユーザーを切り替えてアクセストークンを取得するテストを行うので、emp1とmgr1でそれぞれconfigを切り替えて接続できるようにする

#emp1の接続キーをemp1フォルダにまとめ、configを変更
$ mkdir /home/opc/.oci/emp1
$ mv /home/opc/.oci/oci_api_key* /home/opc/.oci/emp1
$ vi /home/opc/.oci/config
[emp1] <--名前変更
user=ocid1.user.oc1..xxxxxxxx
fingerprint=e1:dd:32:10:0c:b5:4d:8e:93:63:05:27:be:64:0e:38 
key_file=/home/opc/.oci/emp1/oci_api_key.pem <--ディレクトリ変更
tenancy=ocid1.tenancy.oc1..xxxxxxxx
region=ap-tokyo-1

#今度はmgr1でconfigの設定を行う
$ oci setup config
Config file: /home/opc/.oci/config already exists. Do you want add a profile here? (If no, you will be prompted to overwrite the file) [Y/n]: --> Enter
Enter the name of the profile you would like to create: mgr1
以降は前回と同じ。作成後は同様にPublic KeyをAPIキーとしてmgr1に登録する

#mgr1の接続キーをmgr1フォルダにまとめ、configを変更
$ mkdir /home/opc/.oci/mgr1
$ mv /home/opc/.oci/oci_api_key* /home/opc/.oci/mgr1
$ vi /home/opc/.oci/config
[mgr1]
user=ocid1.user.oc1..xxxxxxxx
fingerprint=f1:37:19:5a:58:48:55:63:42:ee:74:61:95:5d:c0:10
key_file=/home/opc/.oci/mgr1/oci_api_key.pem <--ディレクトリ変更
tenancy=ocid1.tenancy.oc1..xxxxxxxx
region=ap-tokyo-1

#IAMユーザーの切り替えはOCI_CLI_PROFILEの変数で行う。それぞれのユーザーでDBアクセストークンを取得するociのコマンドが実行できるかどうかを確認しておく
$ export OCI_CLI_PROFILE=emp1
$ oci iam db-token get
Private key written at /home/opc/.oci/db-token/oci_db_key.pem
db-token written at: /home/opc/.oci/db-token/token   <-- トークンが格納されているディレクトリ
db-token is valid until 2024-01-28 05:46:42

$ export OCI_CLI_PROFILE=mgr1
$ oci iam db-token get
iam db-token get
Private key written at /home/opc/.oci/db-token/oci_db_key.pem
db-token written at: /home/opc/.oci/db-token/token
db-token is valid until 2024-01-28 05:50:48

Oracle Database Clientのトークン認証の設定

クライアント側のtnsnames.oraにトークン認証の接続文字列を追加する

$ vi /home/opc/instant19c/tnsnames.ora
# ※ホスト名はサーバー証明書と同じであることが必要。今回の一連の手順だとFQDNで指定しない。
接続文字列 =
   (description= (retry_count=20)(retry_delay=3)
      (address=(protocol=tcps)(port=1522)(host=ホスト名))
      (connect_data=(service_name=サービス名))
      (security=(ssl_server_dn_match=yes)(TOKEN_AUTH=OCI_TOKEN)))
   
#<例> 
iam =
   (description= (retry_count=20)(retry_delay=3)
      (address=(protocol=tcps)(port=1522)(host=db23ai4iam))
      (connect_data=(service_name=ora23ai_pdb1.privatesubnetin.vcn0408035740.oraclevcn.com))
      (security=(ssl_server_dn_match=yes)(TOKEN_AUTH=OCI_TOKEN)))

4. IAMユーザーとのDBスキーマのマッピング

IAMユーザーがトークンでDB認証されると、Databaseは最終的には何らかのDBスキーマにマッピングしなければならない。マッピングの方式は、排他的スキーマと共有スキーマの2種類あるが、ここでは一番簡単な排他的マッピングでトークン認証の設定が正しくできているかどうかの基本的な動作確認を行う。
排他的マッピングとは、IAMユーザとDBスキーマを1:1でマッピングする方法

-- 排他的マッピングユーザーの作成
CREATE USER emp1 IDENTIFIED GLOBALLY AS 'IAM_PRINCIPAL_NAME=emp1'; -- DBスキーマ:emp1 = IAMユーザ:emp1
grant connect to emp1; -- connect権限を付与
最新のBase Databaseでは、本手順は必要なくなっているようなのでアーカイブとして残しておく opensslのパッケージをインストール 19c以降のOracle Databaseでは、libcrypto.so.10、libssl.so.10のライブラリが入っておらず、トークン認証のフローでエラーになる。内容はDBのアラートログで確認できるが、以下のパッケージをBaseDBにインストールしておくこと
$ sudo yum install  compat-openssl10 

※BaseDB 23cの場合、libauth_sdk_iam.soの不足で接続できない場合がある。アラートログで確認。回避策としては、19cから$ORACLE_HOME/lib/libauth_sdk_iam.soをコピーし、23cにコピーする。

5. 接続テスト

トークンを使用してDBに接続できることを確認する

#emp1ユーザーのOCIプロファイルに変更
$ export OCI_CLI_PROFILE=emp1

#DBトークンを取得
$ oci iam db-token get
Private key written at /home/opc/.oci/db-token/oci_db_key.pem
db-token written at: /home/opc/.oci/db-token/token
db-token is valid until 2024-01-31 14:12:43

#トークン・ベースで接続
$ sqlplus /@iam
Connected to:
Oracle Database 23ai Enterprise Edition Release 23.0.0.0.0 - for Oracle Cloud and Engineered Systems
Version 23.8.0.25.04
SQL> show user
USER is "EMP1"  #DBスキーマ EMP1にマッピングされた

データベースへの接続は、下記のようなフローで動作する
① DB Clientは、oci iam db-token getでemp1ユーザーのDBトークンを取得する。トークンは.oci/db-token/tokenに出力される
② データベースにsqlplus /@接続文字列で接続することでトークンをTLSでDatabaseに送信する
③ DatabaseはトークンをValidationし、トークンに含まれるユーザーIDのグループをチェックし、最終的にDBスキーマにマッピングする

6.トラブルシューティング

手順通りに実施しても一発で接続成功することは難しいかもしれないので、どの部分の問題なのか段階的に調査するのが良い

  • クライアント側のSQL Traceのログからアクセストークンは正しく取得できているか?
  • Databaseのアラートログにエラーは出力されていないか?
  • IAMのグループやユーザーは適切に設定されているか?
  • DatabaseとIAMのマッピングユーザーは適切か?
  • OS側、OCI側のFirewallで必要なポートをブロックしていないか?
  • サポートされているバージョンのDatabase Clientを使用しているか?

ありがちなエラーメッセージと対応方法

#トークンが古い -> 再度取得して接続する
ORA-25708: The expiration time of the token has passed.
Help: https://docs.oracle.com/error-help/db/ora-25708/


#トークンが指定された場所にない。トークンの場所は、~/.oci/db_token/token
ORA-25707: The token is invalid.
Help: https://docs.oracle.com/error-help/db/ora-25707/

#トークンで接続するTnsnames.oraのホスト名がサーバー証明書のCNと一致していない可能性。ホスト名のみやFQDNで試してみる
ORA-29002: SSL transport detected invalid or obsolete server certificate.
Help: https://docs.oracle.com/error-help/db/ora-29002/

トークンに含まれるユーザー等の情報は、下記サイトのデコーダーで確認できる
https://web-toolbox.dev/tools/jwt-decoder

次回は、より実践的なIAMのグループとDatabaseの共有スキーマをマッピングする手順について紹介します。

1
1
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?