RDS for OracleのSecure Sockets Layer(SSL)暗号化を試してみた

# はじめに

Oracle Databaseへの接続におけるネットワークレイヤでの暗号化手法は、[Secure Socket Layer(SSL)](https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/Appendix.Oracle.Options.SSL.html)と[Native Network Encryption(NNE)](https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/Appendix.Oracle.Options.NetworkEncryption.html)の二種類がサポートされています。
元々はOracle Enterprise EditionのAdvanced Securityオプションが必要でしたが、AWS RDSではどちらの機能(SSL, NNE)も どのエディション(SE2, EE)でも無償で利用することが可能です。

今回はSSL暗号化を試してみましたので、その結果とどうやって実装するのかについて記載してみます。
NNEを試した記事は [RDS for Oracleのネイティブネットワーク暗号化（NNE）を試してみた](https://qiita.com/asahide/items/cf2d3167d951b3af085c) になります。


# NNEとSSL

NNEの記事と同様に、NNEとSSLの比較を入れておきます。

|| NNE | SSL |
|:-:|:-:|:-:|
|サーバ設定 |オプション・パラメータ設定のみ |オプション・パラメータ設定に加えてWallet／証明書の設定 |
|クライアント設定 |sqlnet設定のみ<br>(標準の暗号化なら設定不要) |Wallet／証明書の設定、接続名の設定<br>個別に設定が可能なので柔軟な設定も可能 |
|ネットワーク設定| 変更不要 | SSLの待ち受けポートが追加になるため<br>セキュリティグループ等の設定 |
|暗号化アルゴリズム| AES、RC4、3DES等複数のサポート | AESのみのサポート |

# RDS for Oracleへの接続(SSL)

RDS for OracleのSSL設定の流れは次のような形になります。
NNEではRDS側の設定のみで完結していましたが、SSLではクライアント側でのwallet設定が追加で必要になります。
1. (RDS側)オプショングループの設定(SSL)を行う
1. (RDS側)SSLを入れたオプショングループをRDSに適用する
1. (Client側)wallet設定を行う
1. (Client側)sqlnet.ora設定を行う
1. sql*plusでSSL暗号化接続を行う

#### 1. オプショングループ設定(SSL)
オプショングループを設定します。
SSLでの待ち受けポートや設定されるセキュリティグループの他に、FIPS_140(※)の設定や暗号化方式、SSL_VERSIONを設定できます。
(※)FIPS_140についてはOracleのガイド [E.3 Transport Layer Securityに対するFIPS 140-2の構成](https://docs.oracle.com/cd/F19136_01/dbseg/oracle-database-fips-140-settings.html#GUID-4601FC6F-2FCB-47F2-A354-23D9AC33B5E1)を参照ください
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2313926/ef0df787-ba01-55ab-a4db-a23b70e4fe73.png)

#### 2．SSLを入れたオプショングループをRDSに適用する
対象のRDSにオプショングループを適用します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2313926/08ed8513-3766-22d7-d3cf-87cc5ee0434d.png)

#### 3．wallet設定を行う
クライアント側でwallet設定を行います。
AWS上のガイドは [RDS for Oracle DB インスタンスで SSL を使用するように SQL*Plus を設定する](https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/Appendix.Oracle.Options.SSL.html#Appendix.Oracle.Options.SSL.ClientConfiguration) にありますが、wallet設定をorapkiで実施する形で記載されています。
orapkiは通常Oracle Clientのインストールが必要で、instant Clientでは利用できないため、今回はSQLclを利用してwallet設定を行います。今回はAmazonLinux2を利用していた関係で、SQLclのインストール方法は [Amazon Linux 2 に SQLcl をインストールする](https://yohei-a.hatenablog.jp/entry/20200824/1598197780) を参照してインストールしました。(最新のSQLcl ver.23 はJDK11がインストールされている必要があります)

##### 3.1. walletの作成
SQLclを利用してwalletを作成します。
今回 ORACLE_HOME=/usr/lib/oracle/instantclient_21_8/ 、walletのパスは $ORACLE_HOME/ssl_wallet に設定しています。
```bash
$ echo $ORACLE_HOME
/usr/lib/oracle/instantclient_21_8/
$ cd $ORACLE_HOME/ssl_wallet
$ java -classpath '/usr/lib/oracle/instantclient_21_8/sqlcl/lib/*' oracle.security.pki.textui.OraclePKITextUI wallet create -wallet . -auto_login_only
Oracle PKI Tool Release 21.0.0.0.0 - Production
Version 21.0.0.0.0
Copyright (c) 2004, 2022, Oracle and/or its affiliates. All rights reserved.

Operation is successfully completed.
```

##### 3.2. 証明書バンドルのダウンロード
 [東京リージョンの証明書バンドル](https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/UsingWithRDS.SSL.html) をダウンロードし、$ORACLE_HOME/ssl_wallet に配置します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2313926/ca7399c5-c656-28b8-5aa9-3a48df16402d.png)

```bash
$ ll $ORACLE_HOME/ssl_wallet | grep bundle
total 8
-rw-rw-r-- 1 ec2-user ec2-user 7540 May  1 07:01 ap-northeast-1-bundle.pem
```

##### 3.3. クライアント証明書の作成
クライアント証明書をSQLclを利用して作成します。
```bash
$ java -classpath '/usr/lib/oracle/instantclient_21_8/sqlcl/lib/*' oracle.security.pki.textui.OraclePKITextUI wallet add -wallet . -trusted_cert -cert /usr/lib/oracle/instantclient_21_8/ssl_wallet/ap-northeast-1-bundle.pem -auto_login_only
Oracle PKI Tool Release 21.0.0.0.0 - Production
Version 21.0.0.0.0
Copyright (c) 2004, 2022, Oracle and/or its affiliates. All rights reserved.

Operation is successfully completed.
```

##### 3.4. クライアント証明書の確認
作成されたクライアント証明書（wallet）の確認を行います。
```bash
$ ll
total 12
-rw-rw-r-- 1 ec2-user ec2-user 7540 May  1 07:01 ap-northeast-1-bundle.pem
-rw------- 1 ec2-user ec2-user 1333 May  1 07:39 cwallet.sso
-rw------- 1 ec2-user ec2-user    0 May  1 07:38 cwallet.sso.lck
$ java -classpath '/usr/lib/oracle/instantclient_21_8/sqlcl/lib/*' oracle.security.pki.textui.OraclePKITextUI wallet display -wallet .
Oracle PKI Tool Release 21.0.0.0.0 - Production
Version 21.0.0.0.0
Copyright (c) 2004, 2022, Oracle and/or its affiliates. All rights reserved.

Requested Certificates:
User Certificates:
Trusted Certificates:
Subject:        CN=Amazon RDS Root 2019 CA,OU=Amazon RDS,O=Amazon Web Services\, Inc.,ST=Washington,L=Seattle,C=US
```

#### 4. sqlnet.ora設定を行う
sqlnet.ora ファイルにssl_wallet設定を行います。
```bash
$ cat $ORACLE_HOME/network/admin/sqlnet.ora
WALLET_LOCATION = (SOURCE = (METHOD = FILE) (METHOD_DATA = (DIRECTORY = $ORACLE_HOME/ssl_wallet)))
SSL_CLIENT_AUTHENTICATION = FALSE
SSL_VERSION = 1.0
SSL_CIPHER_SUITES = (SSL_RSA_WITH_AES_256_CBC_SHA)
SSL_SERVER_DN_MATCH = ON
```

今回はtnsnames.oraファイルも以下のように設定してます。(必須ではありません)
```bash
TESTDB02_S= (DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCPS)
   (HOST = testdb02.************.ap-northeast-1.rds.amazonaws.com) (PORT = 2484)))(CONNECT_DATA = (SID = TEST02))
   (SECURITY = (SSL_SERVER_CERT_DN = "C=US,ST=Washington,L=Seattle,O=Amazon.com,OU=RDS,CN=testdb02.************.ap-northeast-1.rds.amazonaws.com")))
```


#### 5．SSL暗号化での接続
SSL暗号化設定を有効化したRDSへ、SSL暗号化設定(walletの作成等)を行ったClientからSQLPlusで接続してみます。
暗号化が有効になっている(tcpsで接続されている)ことが確認できます。
```SQL
$ sqlplus admin@TESTDB02_S

SQL*Plus: Release 21.0.0.0.0 - Production on Mon May 1 07:44:00 2023
Version 21.8.0.0.0

Copyright (c) 1982, 2022, Oracle.  All rights reserved.

Enter password:
Last Successful login time: Mon May 01 2023 07:44:08 +00:00

Connected to:
Oracle Database 19c Standard Edition 2 Release 19.0.0.0.0 - Production
Version 19.16.0.0.0

SQL> SELECT SYS_CONTEXT('USERENV', 'network_protocol') FROM DUAL;

SYS_CONTEXT('USERENV','NETWORK_PROTOCOL')
--------------------------------------------------------
tcps
```

トレースからも暗号化が有効になっていることが確認できます。
```SQL
(140502187153984) [01-MAY-2023 07:58:01:504] nzos_PrintCryptoLibraryInfo:   Crypto Library: 
	BSAFE Micro Edition Suite (Oracle) 4.6.0.0.1
(140502187153984) [01-MAY-2023 07:58:01:504] nzos_PrintProvInfo: Crypto Provider Information:
	Provider Type: SOFTWARE
	Product: BSAFE Micro Edition Suite (Oracle) 4.6.0.0.1
	Product Version: 4.6.0.0.1
```
## SSL暗号化なしでの接続
比較のため、SSL暗号化なしで RDS for Oracleに接続してみます。
SSL暗号化が有効になっていない(tcpで接続されている)ことが確認できます。
```SQL
$ sqlplus admin@testdb02.************.ap-northeast-1.rds.amazonaws.com:1521/test02

SQL*Plus: Release 21.0.0.0.0 - Production on Mon May 1 08:12:27 2023
Version 21.8.0.0.0

Copyright (c) 1982, 2022, Oracle.  All rights reserved.

Enter password:
Last Successful login time: Mon May 01 2023 08:12:11 +00:00

Connected to:
Oracle Database 19c Standard Edition 2 Release 19.0.0.0.0 - Production
Version 19.16.0.0.0

SQL> SELECT SYS_CONTEXT('USERENV', 'network_protocol') FROM DUAL;

SYS_CONTEXT('USERENV','NETWORK_PROTOCOL')
--------------------------------------------------------
tcp

```



# まとめ
RDS for OracleのSecure Sockets Layer(SSL)暗号化の設定を試し、実際に暗号化が行われていることが確認できました。
SSLの設定はサーバ側だけではなくクライアント側で個別に設定が必要となるため、設定に手間がかかります。一方で、クライアント側に対してそれぞれにセキュリティ設定を実施することができるため、よりセキュアと言えます。
要件としてSSL暗号化が必要な場合には、本手順（とマニュアル）を参考に設定を行ってみてください。


#### おまけ
前回の記事で RDS for OracleではSSLとNNEは同時に利用できない、ということを書きました。
実際にNNEが含まれているオプショングループにSSLを追加しようとすると、次のようなエラーで追加できません。
![001-OptionGroup-NG-01.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2313926/8cec4d05-757b-dfb4-c258-5a72be649ee6.png)