IAM AWS User クラウドサービスをフル活用しよう！番外編1[PrivateSubnet上のRDSに踏み台EC2のSSHトンネル経由でローカルからアクセスする方法]

みなさんAWS使っていますか？このシリーズ(IAM AWS User クラウドサービスをフル活用しよう！）はAWSサービスの紹介をする記事を投稿するのですが，今回は番外編で実際に私が行ってみて便利だったAWSの使い方を紹介します．今回は番外編1としてPrivateSubnet上のRDSに踏み台EC2のSSHトンネル経由でローカルからアクセスする方法について紹介します．具体的には以下のようなアーキテクチャを想定しています．

![スクリーンショット 2024-12-14 9.31.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3757442/3838d5fc-464a-af61-a930-2117ee036f46.png)

AWSの環境において、セキュリティを強化するためにRDSインスタンスをプライベートサブネットに配置することが一般的である．しかし，プライベートサブネット上のRDSに直接アクセスすることは推奨されないため、踏み台EC2インスタンスを経由してアクセスする方法が必要となる．本記事では，SSHトンネルを用いてローカルマシンからプライベートサブネット上のRDSに接続する手順について詳述する．

# シリーズIAM AWS User クラウドサービスをフル活用しよう！
**Part1** バックエンドとは何なのか？クラウドコンピューティングとバックエンド開発の関係性を知ろう！

https://qiita.com/JavaLangRuntimeException/items/371a334f5a6e07035db5

**Part2** クラウドとは？ & ネットワーク編その1(VPC・サブネット・インターネットゲートウェイ・ルートテーブル・NATゲートウェイ・VPCエンドポイント)

https://qiita.com/JavaLangRuntimeException/items/c9641c0908795467104a

# 他のシリーズ
**AWS UserのGCP浮気日記**
GCPの様子をAWSと比較して考えてみるシリーズ

https://qiita.com/JavaLangRuntimeException/items/527d99e774165a763180

**チートシート**
様々な言語，フレームワーク，ライブラリなど開発技術の使用方法，基本事項，応用事例を網羅し，手引書として記載したシリーズ

https://qiita.com/JavaLangRuntimeException/items/f038fbaccdd92fb0308a

> この記事はSQLのチートシートで，インフラ触るエンジニアならぜひ知っておいた方がいい言語(?)です．
git/gh，lazygit，docker，vim，typescript，プルリクエスト/マークダウン，ステータスコード，ファイル操作，OpenAI AssistantsAPI，Ruby/Ruby on Rails のチートシートがあります．以下の記事に遷移した後，各種チートシートのリンクがあります.

**TypeScriptで学ぶプログラミングの世界**
プログラミング言語を根本的に理解するシリーズ

https://qiita.com/JavaLangRuntimeException/items/cadf49bb419076819963

**情報処理技術者試験合格への道[IP・SG・FE・AP]**
情報処理技術者試験に出題されるコンピュータサイエンス用語の紹介や単語集

https://qiita.com/JavaLangRuntimeException/items/991be402099542ccb936

**Project Gopher: Unlocking Go’s Secrets**
Go言語や標準ライブラリの深掘り調査レポート

https://qiita.com/JavaLangRuntimeException/items/dc45b412d3fbd2ccb9e8

**Gopher’s Journey: Exploring TCP Protocol**
Goを用いてTCPプロトコルを探求 & 作成するシリーズです．

https://qiita.com/JavaLangRuntimeException/items/38091220106d86651d2b

# 接続の概要

SSHトンネルを利用することで、ローカルマシンと踏み台EC2インスタンス間にセキュアな通信経路を確立し、その経路を通じてプライベートサブネット内のRDSにアクセスすることが可能となる。この方法により、直接RDSにアクセスする必要がなくなり、セキュリティを向上させることができる。

# 準備
VPC・パブリックサブネット・プライベートサブネット・ルートテーブル・インターネットゲートウェイなどは用意済みと仮定する．

**1. 踏み台EC2インスタンスの準備**
   - パブリックサブネットにEC2インスタンスを用意する
   - EC2インスタンスには **SSH(22)** のインバウンドを許可したセキュリティグループを設定

![スクリーンショット 2024-12-13 23.12.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3757442/ca1f3548-f5e9-dfdf-f3a9-d3a83047d733.png)


**2. SSHキーの準備**
   - EC2インスタンスへの接続をするページでローカルマシンに踏み台EC2インスタンスにアクセスするためのSSHキー（例: example.pem）を取得し，~/.ssh/以下に設置する
   - キーのパーミッションが適切に設定されていることを確認する

SSHキーはEC2インスタンスを起動させるためのインスタンス作成ページにSSHキーを作成し，秘密鍵(.pem)を入手できる．公開鍵はAWS側にある．

> githubへのssh接続と同じです．

![スクリーンショット 2024-12-13 23.43.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3757442/44af889d-031c-5073-ea05-8db0b3bfab8f.png)

**3. RDSの準備**
   - プライベートサブネットにRDSを用意する(今回はMySQLを使用しました)
   - RDSには**EC2のセキュリティグループから**の **MySQL(3306)** のインバウンドを許可したセキュリティグループを設定する

![スクリーンショット 2024-12-13 23.41.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3757442/8c111e03-dbd2-0cf6-6159-a6dab838bdc7.png)

EC2インスタンスにSSH接続するためのコマンドは「インスタンスに接続」のページで「SSHクライアント」のタブに接続方法が記載されている．
![スクリーンショット 2024-12-13 23.42.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3757442/f810afeb-d7d8-98f8-b2b7-7ffa346b51a6.png)

# SSHトンネルの設定

ローカルマシンで以下のコマンドを用いてSSHトンネルを設定する
```bash
ssh -i "~/.ssh/example.pem" -N -L 3307:[RDSのエンドポイント]:3306 ec2-user@[EC2のパブリック IPv4 DNS]
```
> RDSのエンドポイントやEC2のパブリック IPv4 DNSはそれぞれのインスタンスの詳細ページにあります．

:::note info
**コマンドの解説**
- `ssh`: SSHプロトコルを使用して接続を確立するコマンド
- `-i "~/.ssh/example.pem"`: 接続に使用するSSHキーのパスを指定
- `-N`: リモートコマンドの実行を行わず、トンネルの確立のみを行うオプション
- `-L 3307:[RDSのarn]:3306`: ローカルマシンのポート3307をRDSのエンドポイント（ポート3306）に転送する設定
- `ec2-user@[EC2のパブリック IPv4 DNS]`: 踏み台EC2インスタンスのユーザー名とホスト名を指定する

**データの移り変わり**
どのようにデータの送受信をしていて，ポートフォワーディングをしているかを説明する．
**1. ローカルマシン**

コマンドの  `-L 3307:[RDSのエンドポイント]:3306` の指定により，ローカルマシンのポート 3307 がトンネルのエントリーポイントとして機能する．
例えば，MySQLクライアントが 127.0.0.1:3307 に接続を開始すると，この接続がSSHトンネルを通じて踏み台EC2へ送られる．

![スクリーンショット 2024-12-14 9.34.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3757442/6bd4fb7a-3bae-a427-c65d-6190f5665f5a.png)


**2. 踏み台EC2インスタンス**

踏み台EC2では，SSHトンネルにより受け取ったデータ（ローカルマシンからの接続要求）が指定されたエンドポイント（[RDSのエンドポイント]:3306）に転送される

![スクリーンショット 2024-12-14 9.34.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3757442/9d4e0f3a-0608-09ba-7c33-bc310dc920ac.png)


> 踏み台EC2の役割は，あくまでデータの中継であり，自身がMySQLにアクセスするわけではない

**3. RDS（データベース）**

踏み台EC2経由で到達した接続要求は，RDSのポート 3306 に到達する
RDSはこの接続を受け入れ，クライアント（ローカルマシン）との間でデータの送受信を行う．

![スクリーンショット 2024-12-14 9.34.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3757442/d89a5297-b5c3-cc24-5477-94bfe1b6d57f.png)


:::

# MySQLクライアントからの接続

SSHトンネルが確立された後、以下のコマンドを使用してMySQLクライアントからRDSに接続する。
```bash
mysql -h 127.0.0.1 -P 3307 -u admin -p
```
> いつもはポート3306ですが今回は3307なので注意

このコマンドにより、ローカルマシンのMySQLクライアントからセキュアにRDSに接続することが可能となる。

# 注意点

- **セキュリティグループの設定**: 踏み台EC2インスタンスおよびRDSのセキュリティグループが適切に設定されていることを確認する必要がある。特に、RDSのセキュリティグループは踏み台EC2からの接続を許可するように設定すること。
- **SSHキーの管理**: SSHキーは厳重に管理し、不正アクセスを防ぐために必要なパーミッションを設定すること。
- **ポートの競合**: ローカルマシンのポート3307が他のサービスで使用されていないことを確認すること。必要に応じて別のポートを使用することも検討する。

# エラー対応
**1. mysqlコマンドを使ってデータベースに接続するときに怒られた**

(mysql-clientの最新版に問題があるようです)

```bash
brew uninstall mysql-client
brew install mysql-client@8.0
```

**2. sshのpermissionDenied系で怒られる**

(.ssh/は適切な権限付与がないと怒られるみたいです)

```bash
chmod 600 ~/.ssh/
chmod 600 ~/.ssh/example.pem
chmod 700 ~/.ssh/known_hosts
```

SSHトンネルを利用することで、プライベートサブネット上のRDSに対してセキュアかつ効率的にアクセスすることが可能となる．本記事で紹介した手順を踏襲することで，ローカル環境から安全にデータベース操作を行うことができる．セキュリティを維持しつつ，柔軟なアクセス方法を実現するために，是非活用してほしい．

それではQiitaアドカレ.24企画の今日のクリスマスツリーです．

> 詳しくは[こちら](https://qiita.com/JavaLangRuntimeException/items/1f4a6febf957f522ba45)の記事から

![スクリーンショット 2024-12-13 10.49.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3757442/f6a1183e-ddfe-c6b6-c42b-ec17f7f84263.png)