OCI Bastion経由でMySQL Database Serviceに接続する

__初めに__
冒頭ですが、この記事の位置付けは、次のシリーズ記事の1つです。
[OCI Bastion サービス](https://qiita.com/letian/items/10152a4fec813c1b7d98#bastion-%E3%82%B5%E3%83%BC%E3%83%93%E3%82%B9)

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1121622/962be3ef-1001-86b6-c20b-c5e167be96f4.png", width="650">
MySQL Database Serviceに接続したい時、OCI Bastion サービスを利用すれば、踏み台サーバを立てず、On-Pのクライアントから、サブネット(Public/Private)にあるMySQL DBに接続できます。OCI Bastionサービスは<font color=blue>無料</font>で使用できます。

__検証環境__

|項目|内容|コメント|
|--|--|--|
|DBタイプ|MySQL Database Service|IaaS DBにも接続可能|
|クライアントOS|Oracle Linux 8|
||Windows Server 2019|
|DB接続ツール|MySQL Shell, MySQL Client|For Linux|
||MySQL Workbench 8.0.29|For Windows|
||SQL Developer Ver 21.4.3 (JDK8付き)|For Windows|
|JDBCドライバー|mysql-connector-java-8.0.29.jar|For SQL Developer|

__目次__
- [1. 事前準備](#1-事前準備)
- [2. Bastionの作成](#2-bastionの作成)
- [3. セッションの作成](#3-セッションの作成)
- [4. セキュリティ・リストにイングレス・ルールを追加](#4-セキュリティリストにイングレスルールを追加)
- [5. SSHトンネルの作成](#5-sshトンネルの作成)
- [6. MySQLに接続](#6-mysqlに接続)
  - [6-1. MySQL Shellからの接続](#6-1-mysql-shellからの接続)
  - [6-2. MySQL Clientからの接続](#6-2-mysql-clientからの接続)
  - [6-3. MySQL Workbenchからの接続](#6-3-mysql-workbenchからの接続)
  - [6-4. SQL Developerからの接続](#6-4-sql-developerからの接続)
- [付録](#付録)
  - [トラブル・シューティング](#トラブルシューティング)
  - [Bastionの制限](#bastionの制限)

# 1. 事前準備
クライアント側で、DB接続ツールを用意しておきます。

__MySQL Shellからの接続__
MySQL Shellをインストールするコマンド： `sudo yum install mysql-shell`

__MySQL Clientからの接続__
MySQL Clientをインストールするコマンド： `sudo yum install mysql`

__MySQL Workbenchからの接続__
ダウンロードURL：https://dev.mysql.com/downloads/workbench/
インストーラをダウンロードし、実行してください（詳細を省略）。

__SQL Developerからの接続__
- ダウンロードURL：https://www.oracle.com/tools/downloads/sqldev-downloads.html
この例は、Windows版(JDK8付き)を使用します（※オラクルのアカウントは必要です）。

- Zipファイルを解凍して後、sqldeveloper.exeを実行すれば起動できます（インストール不要）。

- JDBCドライバーのダウンロード
  URL: https://dev.mysql.com/downloads/windows/installer/8.0.html
インストーラ・ファイルをダウンロードし、実行します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1121622/a79ed4bd-452a-e98b-963a-2c8beaab8c4c.png", width="550">
タイプは、"Custom"を選んで続行します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1121622/d0ca7fb2-f85b-9679-fe8a-5ba5d0c40ff5.png", width="550">
以下のように、"MySQL Connector"を選んで続行します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1121622/3838ee08-f9dc-8a15-1c2d-ab645e2557ce.png", width="550">
"MySQL Connector"をダウンロードし、インストールします。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1121622/2e2fb89f-f764-9031-df7b-1a32f2a2d5c9.png", width="550">
インストール・パス：`C:\Program Files (x86)\MySQL\Connector J 8.0`
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1121622/649c5133-75ff-6f2f-005d-de318948b00c.png", width="550">

- JDBCドライバーの追加
SQL Developer MENU -> Tools -> Preferences -> Database -> Third Party JDBC Drivers -> Add Entry
以下のように、ドライバーを指定します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1121622/7bd44a60-e05c-435b-dec2-435d5f9db1c9.png", width="500">
OKをクリックし追加します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1121622/3971be19-44bf-9288-2816-9cce8e87aa3f.png", width="550">

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

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

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1121622/b716edbf-981b-4218-6bf6-8839cc41aeab.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/86285b01-40d1-5ccf-edaf-f42079a9a32e.png)

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

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1121622/8f7cb24a-34db-28c3-b415-51062cc9e4f4.png", width="500">

ヒント：DBの情報詳細画面で、MySQL DatabaseのプライベートIPが取得できます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1121622/b6751428-9e69-f688-e62e-48ad7347c382.png", width="400">

セッションはアクティブの状態になりましたら、次のように、3ドットのメニューをクリックしてSSHコマンドをコピーします。このコマンドは、[STEP 5. SSHトンネルの作成](#5-sshトンネルの作成)で使用されます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1121622/5481aa4b-03e7-cabe-7288-259c6cc8da59.png">
デフォルトでは、セッションは3時間有効ですが、Bastionを作成する際にはこの期間を変更することが可能です。

# 4. セキュリティ・リストにイングレス・ルールを追加
MySQL Database Serviceに接続するために、TCPポート<font color=blue>3306</font>をセキュリティ・リストのイングレス・ルールに追加する必要があります。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1121622/bb1ad861-d868-d1fb-6f50-2915a5319a53.png", width="600">
"<strong>Source CIDR</strong>"は、Bastionの「プライベート・エンドポイントIP」です（Bastionの情報ページに表示されます）。

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

* `<privateKey>`を秘密キーのパスとファイル名に置き換える。
　Linuxの例：`~/.ssh/id_rsa`
　Windowsの例（PowerShell）：`$home\.ssh\id_rsa`
　秘密キーを上記パスに保存してください（パスが存在しない場合、作成しておいてください）。
* `<localPort>`を<font color=blue>3306</font>に置き換える。
* `<Private_IP_of_DB>`は自動に実のIPが埋められるので、変更する必要がない。

コマンドを置き換えた後、実施します（結果を省略）。

# 6. MySQLに接続

### 6-1. MySQL Shellからの接続
コマンド：mysqlsh \<Username>@<font color=blue>127.0.0.1</font>

```sql
[opc@linux8 ~]$ mysqlsh admin@127.0.0.1
Please provide the password for 'admin@127.0.0.1': ************
Save password for 'admin@127.0.0.1'? [Y]es/[N]o/Ne[v]er (default No): Y
MySQL Shell 8.0.29

Copyright (c) 2016, 2022, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its affiliates.
Other names may be trademarks of their respective owners.

Type '\help' or '\?' for help; '\quit' to exit.
Creating a session to 'admin@127.0.0.1'
Fetching schema names for autocompletion... Press ^C to stop.
Your MySQL connection id is 93
Server version: 8.0.29-cloud MySQL Enterprise - Cloud
No default schema selected; type \use <schema> to set one.
 MySQL  127.0.0.1:3306 ssl  JS > \s
MySQL Shell version 8.0.29

Connection Id:                93
Current schema:
Current user:                 admin@10.0.1.213
SSL:                          Cipher in use: ECDHE-RSA-AES128-GCM-SHA256 TLSv1.2
Using delimiter:              ;
Server version:               8.0.29-cloud MySQL Enterprise - Cloud
Protocol version:             Classic 10
Client library:               8.0.29
Connection:                   127.0.0.1 via TCP/IP
TCP port:                     3306
Server characterset:          utf8mb4
Schema characterset:          utf8mb4
Client characterset:          utf8mb4
Conn. characterset:           utf8mb4
Result characterset:          utf8mb4
Compression:                  Disabled
Uptime:                       5 hours 41 min 15.0000 sec

Threads: 6  Questions: 47978  Slow queries: 0  Opens: 377  Flush tables: 3  Open tables: 296  Queries per second avg: 2.343
 MySQL  127.0.0.1:3306 ssl  JS >
```

### 6-2. MySQL Clientからの接続
コマンド：`mysql  -h <hostname or IP> -u myuser -pMySecretPassword`
'-p'のみの場合、プロンプトが表示されたらパスワードを入力してください。

```sql
[opc@linux8 ~]$ mysql -h 127.0.0.1 -u admin -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 91
Server version: 8.0.29-cloud MySQL Enterprise - Cloud

Copyright (c) 2000, 2021, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> \s
--------------
mysql  Ver 8.0.26 for Linux on x86_64 (Source distribution)

Connection id:          91
Current database:
Current user:           admin@10.0.1.213
SSL:                    Cipher in use is ECDHE-RSA-AES128-GCM-SHA256
Current pager:          stdout
Using outfile:          ''
Using delimiter:        ;
Server version:         8.0.29-cloud MySQL Enterprise - Cloud
Protocol version:       10
Connection:             127.0.0.1 via TCP/IP
Server characterset:    utf8mb4
Db     characterset:    utf8mb4
Client characterset:    utf8mb4
Conn.  characterset:    utf8mb4
TCP port:               3306
Binary data as:         Hexadecimal
Uptime:                 5 hours 37 min 59 sec

Threads: 6  Questions: 47443  Slow queries: 0  Opens: 357  Flush tables: 3  Open tables: 276  Queries per second avg: 2.339
--------------

mysql>
```

### 6-3. MySQL Workbenchからの接続
- 接続を新規作成 (CTRL+U)
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1121622/d7eff5b6-919f-6a9b-952d-e23738e44705.png", width="650">
- 接続後
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1121622/587cd902-1b3c-88fd-f52d-3979b05c6076.png", width="650">

### 6-4. SQL Developerからの接続

- 接続を新規作成
Database Type: <font color=blue>MySQL</font>を指定
Hostname: <font color=blue>localhost</font>を指定 (重要)
「テスト」ボタンを押し、接続をテストします。接続成功を確認したら、「接続」ボタンを押し、接続を立てます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1121622/78eb673b-d9b9-be87-f468-54b9f26b3433.png", width="650">

- 接続後
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1121622/4d8a55c3-de78-563b-f866-cd6a9bd00bfb.png", width="650">

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

- 無効なユーザーまたはパスワード。
- MySQLインスタンスはまだ起動していない。
- リスナー・ポート（TCP 3306）は、イングレス・ルールに追加されていない。
対策：セキュリティ・リストを確認してください。
- 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)