Session Manager で SSH/SCP をトンネリングして EC2 接続

# 今更ながらこれやってみる
[セッションマネージャーが SSH と SCP のトンネリングサポートを開始](https://aws.amazon.com/jp/about-aws/whats-new/2019/07/session-manager-launches-tunneling-support-for-ssh-and-scp/)

# これができることで
セキュリティグループで SSH 22番ポートを開ける必要がなくなり、踏み台も不要、 EIP も不要になるので、コスト削減につながりますよね。

# 前提
今回の手順は Client: Mac, Server: Amazon Linux 2 で実施する場合。

### Client
- awscli 1.16.12 以上
- Session Manager Plugin 1.1.23.0 以上
- Session Manager のエンドユーザーポリシー権限を持った IAM User
    - [クイックスタート Session Manager のデフォルト IAM ポリシー](https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/getting-started-restrict-access-quickstart.html)

### Server
- ssm agent 2.3.672.0以上
- `AmazonEC2RoleforSSM` の IAM Role がインスタンスにアタッチされていること

# Client の設定
### awscli
適宜、前提バージョンの awscli をインストール/アップデートする。

### Session Manager Plugin
バージョン確認

```
$ session-manager-plugin --version
```

インストール/アップデート

```
curl "https://s3.amazonaws.com/session-manager-downloads/plugin/latest/mac/sessionmanager-bundle.zip" -o "sessionmanager-bundle.zip"
unzip sessionmanager-bundle.zip
sudo ./sessionmanager-bundle/install -i /usr/local/sessionmanagerplugin -b /usr/local/bin/session-manager-plugin 
```

[(オプション) AWS CLI 用の Session Manager Plugin をインストールする](https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/session-manager-working-with-install-plugin.html)

### SSH ファイルの設定
適当に名前つけて設定入れる。

```~/.ssh/config
Host matsu-test
      Hostname i-XXXXXXXXXXXX
      User ec2-user
      IdentityFile ~/.ssh/matsu-test.pem
      ProxyCommand sh -c "aws ssm start-session --target %h --document-name AWS-StartSSHSession --parameters 'portNumber=%p'"
```

# Server の設定
### SSM エージェントをインストールする
#### SSM エージェント プリインストールされた AMI
SSM エージェント は、次の Amazon マシンイメージ (AMI) にデフォルトで事前インストールされています。とのこと。

- 2016 年 11 月以降に公開された Windows Server 2003-2012 R2 AMI
- Windows Server 2016 および 2019
- Amazon Linux
- Amazon Linux 2
- Ubuntu Server 16.04
- Ubuntu Server 18.04

[SSM エージェント の使用](https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/ssm-agent.html)

#### 手動でインストールするなら
ssm-agent がインストール可能な下記の Linux OS

- Amazon Linux および Amazon Linux 2
- Ubuntu Server
- Red Hat Enterprise Linux (RHEL)
- CentOS
- SUSE Linux Enterprise Server (SLES) 12
- Raspbian

[Amazon EC2 Linux インスタンスに SSM エージェント を手動でインストールする](https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/sysman-manual-agent-install.html)

### SSM エージェントをアップデートする
#### バージョン確認

```
$ rpm -qi amazon-ssm-agent
```

#### 起動時にインターネットにアクセスできるインスタンスなら
userdata に入れちゃう。

```:userdata
#!/bin/bash
yum update -y
yum install -y https://s3.amazonaws.com/ec2-downloads-windows/SSMAgent/latest/linux_amd64/amazon-ssm-agent.rpm
```

手動でアップデートするならこれだけ。

```
$ yum install -y https://s3.amazonaws.com/ec2-downloads-windows/SSMAgent/latest/linux_amd64/amazon-ssm-agent.rpm
```

### セキュリティグループ
SSH 22番ポートを開けなくて良い。

# SSH してみる

```
$ ssh matsu-test
The authenticity of host 'i-06a06ac4cebcc5301 (<no hostip for proxy command>)' can't be established.
ECDSA key fingerprint is SHA256:3ZAr+OF/DACbhOWrOUxzjmwM/OFOhTQHUwxAAwVbDaI.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'i-06a06ac4cebcc5301' (ECDSA) to the list of known hosts.

       __|  __|_  )
       _|  (     /   Amazon Linux 2 AMI
      ___|\___|___|

https://aws.amazon.com/amazon-linux-2/
[ec2-user@ip-10-4-2-202 ~]$
```

# SCP でファイル転送
普通にできる。

```
$ scp test.txt matsu-test:~/
test.txt                                                                                                                    100%    0     0.0KB/s   00:00

$ ssh matsu-test
Last login: Fri Nov 15 02:40:28 2019 from localhost

       __|  __|_  )
       _|  (     /   Amazon Linux 2 AMI
      ___|\___|___|

https://aws.amazon.com/amazon-linux-2/

$ ll
合計 0
-rw-r--r-- 1 ec2-user ec2-user 0 11月 15 02:46 test.txt
```

# PostgreSQL にポートフォワード
RDS PostgreSQL に対してポートフォワードし、ローカル環境から PostgreSQL に接続してみる。

RDS エンドポイントの 5432 ポートを ローカルの 9999 ポートに向ける。

```
$ ssh matsu-test -L 9999:matsuki-postgre.XXXXXXXXX.ap-northeast-1.rds.amazonaws.com:5432
```

ローカル環境から PostgreSQL に接続してみる。

```
$ psql -h 127.0.0.1 -p 9999 -U postgres
Password for user postgres:
psql (11.5)
SSL connection (protocol: TLSv1.2, cipher: ECDHE-RSA-AES256-GCM-SHA384, bits: 256, compression: off)
Type "help" for help.

postgres=>
```

OK

# Private なインスタンスの場合
Private Subnet に配置されたインスタンスはインターネット接続できないため、 Session Manager を利用できないが、 **NAT GW** を作成することで、インターネット向けの通信を通すことができるのでこれでいける。

### NAT GWがなくても VPC エンドポイントがあればいける

#### VPC の設定確認
VPC の `DNS 解決` および `DNS ホスト名` を有効化する。

#### VPC エンドポイントを作成
以下を作成。

- com.amazonaws.ap-northeast-1.ssm
- com.amazonaws.ap-northeast-1.ssmmessages
- com.amazonaws.ap-northeast-1.ec2messages

#### セキュリティグループ設定
インスタンスから VPC エンドポイントの SG への https (443) アクセスを許可する。
※VPC エンドポイントの SG をインスタンスと同じ SG で作成していれば、該当 SG 自身を全て許可するように設定すれば良い。

[ステップ 6: (オプション) プライベートクラウドエンドポントの作成](https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/setup-create-vpc.html)