OCI Bastion経由でプライベート・サブネット内のOracle DBに接続する

__初めに__
冒頭ですが、この記事は次のシリーズ記事の1つです。
シリーズ１：[OCI Bastion サービス](https://qiita.com/letian/items/10152a4fec813c1b7d98#bastion-%E3%82%B5%E3%83%BC%E3%83%93%E3%82%B9)
シリーズ２：[プライベート・サブネット内の Oracle DB/ADB に接続](https://qiita.com/liu-wei/items/10152a4fec813c1b7d98#4-%E3%83%97%E3%83%A9%E3%82%A4%E3%83%99%E3%83%BC%E3%83%88%E3%82%B5%E3%83%96%E3%83%8D%E3%83%83%E3%83%88%E5%86%85%E3%81%AE-oracle-dbadb-%E3%81%AB%E6%8E%A5%E7%B6%9A)

接続先のOracle DBがクラウド上にある場合、一般的にはプライベート・サブネットに配置され、On-Pからパブリック・アクセスを通じて直接アクセスできません。VPNを設定しない場合、踏み台サーバを経由して接続できますが、OCI Bastionサービスを利用すれば、<strong>踏み台サーバを構築せず</strong>にOn-Pのクライアントから直接プライベート・サブネット内のOracle DBに接続できます。OCI Bastionサービスは<font color=blue>無料</font>で利用できます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1121622/81556014-8d76-03b3-3f90-4de9ca38cb8b.png", width="650">

__検証環境__

|項目|内容|コメント|
|--|--|--|
|DBタイプ|OCI Base DB (VM)|IaaS DBにも接続可能|
|DBバージョン|19c Standard Edtion|
|クライアントOS|Windows 2019 Server|
|DB接続ツール|SQL Developer Ver 21.4|[ダウンロードURL](https://www.oracle.com/tools/downloads/sqldev-downloads.html)|
||SQL Plus<br>(Oracle Instant Client)|[ダウンロードURL](https://www.oracle.com/jp/topics/technologies/download-instant-client.html)|
|SSHソフト|OpenSSH||

__ステップ__
- [1. Bastionの作成](#1-bastionの作成)
- [2. セッションの作成](#2-セッションの作成)
- [3. セキュリティ・リストに入力ルールを追加](#3-セキュリティリストに入力ルールを追加)
- [4. SSHトンネルの作成](#4-sshトンネルの作成)
- [5. Oracle DBに接続](#5-oracle-dbに接続)
- [付録](#付録)
  - [トラブル・シューティング](#トラブルシューティング)
  - [Bastionの制限](#bastionの制限)

# 1. Bastionの作成
Identity & Security -> Bastion -> Create Bastion

|項目|内容|
|--|--|
|Bastion名|適当な名前を入力|
|ターゲットVCNとサブネット|Oracle DBが所属するVCNとサブネットを選択|
|CIDRブロック許可リスト|このテストではCIDRブロックの許可リストを「0.0.0.0/0」に設定しているが、運用時には範囲を絞り込むことが推奨される。例えば、 接続元（クライアント）のIPアドレスのみを許可するように。|

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1121622/c538fa62-49e8-d1bb-6ae1-6ac42c8faabd.png", width="450">

__注意__
1. このテストでは、CIDRブロックの許可リストを「0.0.0.0/0」に設定しています。運用時には範囲を絞り込むことが推奨されます。例えば、接続元（クライアント）のIPアドレス範囲のみを許可するのが良いでしょう。
2. OCI Bastionを作成する際には、<strong>ターゲット</strong>のVCNとサブネットを指定する必要がありますが、<strong>Bastion自体</strong>に対し、<strong>配置場所を指定する必要はありません</strong>（誤解されることがよくあります）。


Bastionがアクティブの状態になると、「<font color=blue>プライベート・エンドポイントIP</font>」は次の画面から確認できます。このIPはターゲット・サブネット内で自動的に割り当てられます。次のステップで、このIPをセキュリティ・リストの入力ルールに追加します。「CIDRブロック許可リスト」を編集したい場合は、「<strong>編集</strong>」ボタンをクリックすれば大丈夫です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1121622/56e54b70-d9fb-d6e2-186d-daacc18baf33.png)

# 2. セッションの作成
Bastion -> Sessions -> Create session
|項目|内容|
|--|--|
|セッション・タイプ|"<font color=blue>SSH port forwarding session</font>"を選択|
|ターゲット・ホストに接続する方法|"IPアドレス"を選択 (デフォルト)|
|IPアドレス|接続先DBの「プライベートIP」|
|ポート|<font color=blue>1521</font>
|SSHキー|既存のキーファイルを利用するか、新しいキーペアを作成する。(秘密キーをDBクライアント側に保存してください。)|

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1121622/175f6dba-e94d-e404-7fa3-0fef44d0a15c.png", width="450">
<strong>ヒント</strong>：OCI DB Cloud Serviceを接続する場合、以下の画面でプライベートIPが取得できます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1121622/1b6c0d6d-11e4-ed3f-5d85-ebdd49a3467f.png">
セッションはアクティブの状態になりましたら、次のように、3ドットのメニューをクリックしてSSHコマンドをコピーします。このコマンドは、[STEP 4. SSHトンネルの作成](#4-sshトンネルの作成)で使用されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1121622/4070cab4-e4ee-2ca5-48ca-51668a183043.png)
デフォルトでは、セッションは3時間有効ですが、Bastionを作成する際にはこの期間を変更することが可能です。

# 3. セキュリティ・リストに入力ルールを追加
クラウド上のDBにアクセスするため、TCPポート1521を入力ルールに追加するのは必要です。
設定方法は、以下のどちらでもよいです。
* プライベート・サブネットに紐づけられる<strong>セキュリティ・リスト</strong>に、ルールを追加
* DBインスタンスに紐づけられる<strong>NSG</strong>に、ルールを追加

これから、セキュリティ・リストを例にして設定します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1121622/61cd9524-4561-a65c-b912-66cb04bd3632.png", width="600">
"<strong>Source CIDR</strong>"は、Bastionの「プライベート・エンドポイントIP」です（Bastionの情報ページに表示されます）。
# 4. SSHトンネルの作成
クライアントでSSHコマンドを実行してトンネルを作成します。この例は、OpenSSHを利用します。まだインストールされていない場合、PowerShellを起動して、以下のコマンドでインストールしてください（管理者ユーザで実行）。
コマンド：`Get-WindowsCapability -Online | Where-Object Name -like 'OpenSSH*'`
```powershell
PS C:\Windows\system32> Get-WindowsCapability -Online | Where-Object Name -like 'OpenSSH*'


Name  : OpenSSH.Client~~~~0.0.1.0
State : Installed

Name  : OpenSSH.Server~~~~0.0.1.0
State : Installed



PS C:\Windows\system32>
```

__SSHトンネルを作成するコマンド__：
```bash
ssh -i <privateKey> -N -L <localPort>:<Private_IP_of_DB>:1521 -p 22 <bastion_ocid>@host.bastion.ap-tokyo-1.oci.oraclecloud.com
```
上記ステップ１でコピーしたものです。

* `<privateKey>`を秘密キーのパスとファイル名に置き換えます。
　Windowsの例（PowerShell）：`$home\.ssh\id_rsa`
* `<localPort>`を<font color=blue>1521</font>に置き換えます。
* `<Private_IP_of_DB>`は自動に実のIPが埋められるので、変更する必要はありません。

<font color=blue>ヒント</font>:
* バック・グラウンドで実行させたい場合：
   Windows (PowerShell):  `Start-Job {  }`でコマンドを囲む
   Linux OSを使用する時、コマンドの最後に`&`を追加
   バック・グラウンドで実施する場合、出力メッセージを表示しませんので、ご注意ください。<strong>初回トンネル作成時</strong>、或いは<strong>トラブル・シューティング</strong>の時、<font color=blue>フォア・グラウンド・プロセス</font>として実施してください。

```powershell
PS C:\Windows\system32> Start-Job { ssh -i $home\.ssh\id_rsa -N -L 1521:10.0.1.171:1521 -p 22 <bastion_ocid>@host.bastion.ap-tokyo-1.oci.oraclecloud.com }

Id     Name            PSJobTypeName   State         HasMoreData     Location             Command
--     ----            -------------   -----         -----------     --------             -------
1      Job1            BackgroundJob   Running       True            localhost             ssh -i $home\.ssh\id_r...


PS C:\Windows\system32>
```

# 5. Oracle DBに接続
* 接続を新規作成
<strong>Database Type</strong>: デフォルト(Oracle)を指定
<strong>Role</strong>: デフォルトのままでよいが、必要に応じて指定できます。
<strong>Username,Password</strong>: ユーザ名とパスワードを入力。
<strong>Hostname</strong>: <font color=blue>localhost</font>と入力する（重要）。<strong>Port</strong>: <font color=blue>1521</font>
<strong>SID、Service Name</strong>: 片方を入力（PDBへ接続したい場合、PDBのサービス名を入力)。
<strong>Save Password</strong>: チェックしたら、次回接続の時、パスワードの入力が省略できます。
「<font color="blue">テスト</font>」ボタンを押し、接続をテストします。接続成功を確認したら、「<font color="blue">接続</font>」ボタンを押し、接続を立てます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1121622/aad82bce-67e9-49c9-dbf6-323bb6c2013d.png)
サービス名の確認方法は、以下の記事をご参考ください。
[Oracle Base DBのサービス名を取得する](https://qiita.com/liu-wei/items/ecab5bc23efd13410dac)

SQL Plusで接続したい場合、トンネル作成後、以下のコマンドを実行してください。
`sqlplus <User>/<Password>@localhost:1521/<Service_Name>`

```sql
c:\instantclient_21_3>sqlplus system@localhost:1521/DB19cPri_pdb1.privatesubnet1.vcn1.oraclevcn.com

SQL*Plus: Release 21.0.0.0.0 - Production on Fri Apr 22 07:39:11 2022
Version 21.3.0.0.0

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

Enter password:
Last Successful login time: Fri Apr 22 2022 07:38:39 +00:00

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

SQL>
```
# 付録
## トラブル・シューティング
DBへの接続が失敗した場合、以下のような原因は一般的です。ご参考ください。

- 無効なユーザーまたはパスワード。
- ユーザー・ロールの指定は間違った。
- DBインスタンスはまだ起動していない。
- 物理サーバかIaaS DBの場合、接続先サーバのファイアウォールには、リスナー・ポート(1521)が公開されていない。
- クラウドDBの場合、リスナー・ポート（TCP 1521）は、Ingressルールに追加されていない。
対策：セキュリティ・リストまたはNSGを確認してください。
- SSHトンネルは未作成か、作成が失敗した。
トンネル作成失敗、或いはタイムアウトの時、以下のメッセージが表示される。
`Connection to host.bastion.ap-tokyo-1.oci.oraclecloud.com closed by remote host.`
- Bastionのセッション期限が切れた（デフォルトは３時間）。
セッション期限が切れた後、SSHトンネルを作成しようとしたら、以下のエラーが発生する。
`<bastion_ocid>@host.bastion.ap-tokyo-1.oci.oraclecloud.com: Permission denied (publickey)`
対策：セッションを再作成する。

## Bastionの制限

|項目|内容|
|--|--|
|最大Bastion数|テナンシ毎に<font color=blue>5つ</font>|
|最大セッション数|Bastionあたり<font color=blue>20</font>セッション|
|セッション存続時間|<font color=blue>30分~3時間</font>|
|データ転送制限|データ転送の制限はありません。<br>ただし、SSH接続あたりの接続速度は<font color=blue>16 Mbps</font>に制限されます。|

以上です。

----
__自分からの関連記事__
[オラクル・クラウドの個人ブログ一覧](https://qiita.com/liu-wei/items/10152a4fec813c1b7d98)
[SQL Developerで様々なDBに接続する方法](https://qiita.com/liu-wei/items/08f2e2f6d90c08549cbf)
[OCI データベース・ツールでオラクルDBへの接続方法](https://qiita.com/liu-wei/items/1d4ed7477a28b794a56c)
[Oracle Base DBのサービス名を取得する](https://qiita.com/liu-wei/items/ecab5bc23efd13410dac)
[OCI Bastion経由でMySQL Database Serviceに接続する](https://qiita.com/liu-wei/items/e86e01ac3d61999aa811)
[OCI Bastion経由でプライベート・サブネット内のAutonomous DBに接続する](https://qiita.com/liu-wei/items/36dc12c95d3bc72e16db)