Tera Termでセッションマネージャーを使ってEC2にログインする方法色々

# はじめに
`Windows`を使って仕事しているインフラエンジニア的には当たり前なソフトとなる`Tera Term`ですが、スイッチロール先のEC2にログインするとき、`Tera Term`でログインするにはどうすればよいだろうと調べた結果を紹介したいと思います。

# セッションマネージャーを使う際の問題
セッションマネージャーはAWSの機能となり、EC2等への接続を行う際に使用するものとなります。

EC2インスタンス等に接続する際、セキュリティグループ等でSSHポートを許可しなくても済み、SSH接続とは異なることから、キーペアのような永続鍵を管理する必要もないことから使われている方も多いと思います。

- [Systems Manager Session Managerを使ってEC2からキーペアを根絶する。](https://qiita.com/sakai00kou/items/ecb41aea16f5a831c9f4)

ただし、セッションマネージャーは上述の通り、AWSの機能となるため、`Tera Term`は対応しておらず、コマンドラインでログインする際にはAWS CLIでログインする必要があることから、Windows PCで使用する場合は、コマンドプロンプトやPowerShell、もしくは別のソフトウェア等を使用する必要があります。

じゃあ、`Tera Term`を使わず、他の手段を取ればいいじゃないかと考える方もおられるかと思いますが、`Tera Term`はマクロも使用できるため、マクロありきで運用されているところも多く、例えば新しく導入したシステムだけPowerShellで運用するというのは中々ハードルが高い問題となります。

というわけで今回は`Tera Term`でEC2に接続するという運用は変えずにセッションマネージャーでEC2に接続し、スイッチロールを行っているアカウントのEC2にも接続する方法をまとめてみたいと思います。

# Tera Termでセッションマネージャーを使ってスイッチロール先EC2にログインする方法
以下で挙げる方法以外にも色々とあると思いますが、今回は私が考えた以下３つの方法を紹介したいと思います。

- [WSLで起動した仮想マシンでSSHサーバを動作させて仮想マシン経由で接続を行う](#wslで起動した仮想マシンでsshサーバを動作させて仮想マシン経由で接続を行う)
- [ローカルPCでOpenSSHサーバ機能を動作させてローカルSSHサーバ経由で接続を行う](#ローカルpcでopensshサーバ機能を動作させてローカルsshサーバ経由で接続を行う)
- [セッションマネージャーのポートフォワード機能を使用して接続を行う](#セッションマネージャーのポートフォワード機能を使用して接続を行う)

前提として、操作するWindows PCにはTera Term、AWS CLI、セッションマネージャープラグインがインストールされている前提で進めるため、インストールされていない場合は以下よりインストールしておいてください。

- [Tera Term Home Page](https://teratermproject.github.io/)
- [AWS CLI インストールと更新の手順](https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/getting-started-install.html#getting-started-install-instructions)
- [Windows での Session Manager プラグインのインストール](https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/install-plugin-windows.html)

## WSLで起動した仮想マシンでSSHサーバを動作させて仮想マシン経由で接続を行う
`Windows Subsystem for Linux`（以下`WSL`）で何かしらのサーバをローカルPC内で動作させて、仮想マシン経由で接続するという方法となります。

別に`WSL`に限らずともローカルPC内で`Tera Term`接続できるサーバが構築できればいいので`Docker`で起動したサーバや`VirtualBox`で作成したサーバ等でもOKです。

今回は`WSL`の`Ubuntu`でSSHサーバを動作させて接続する例を示します。

`WSL`は以下の記事等を参考にセットアップしておいてください。

- [WSL2をインストールしてネイティブなSystemdを使う。](https://qiita.com/sakai00kou/items/212f037600e202e07690)

なお、私の環境は既に`WSL`を大分カスタマイズしてしまっている構成のため、素の状態からの手順確認ができなかったので、うまくできない場合は他のサイトも参考にしてください。

以下私の環境で試した結果を参考として載せておきます。

### WSLの仮想マシンで接続する場合の前提条件
`WSL`を有効化する必要があるため、各会社のポリシーにより有効化できない場合はそもそもこの手段を取れないため、別の手段を検討してください。

### SSHサービスインストール
`WSL`で`Ubuntu`をインストールしている前提で進めます。

デフォルトだとSSHサービスはインストールされていないため、`Ubuntu`上から以下コマンドを実行し、SSHサービスをインストールします。

```bash:SSHサービスインストール
sudo apt-get update
sudo apt -y install ssh
```

再起動した際に起動するようサービスの有効化とサービス起動を行っておきます。

```bash:SSHサービスの有効化とサービス起動
sudo systemctl enable --now ssh
```

### AWS CLIとセッションマネージャープラグインインストール
今回の構成の場合、`Tera Term`でローカルの`Ubuntu`にSSH接続して、`Ubuntu`からEC2インスタンスに接続することになるため、`Ubuntu`に`AWS CLI`とセッションマネージャープラグインをインストールします。

```bash:AWS CLIのインストール
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install
```

```bash:セッションマネージャープラグインのインストール
curl "https://s3.amazonaws.com/session-manager-downloads/plugin/latest/ubuntu_64bit/session-manager-plugin.deb" -o "session-manager-plugin.deb"
sudo dpkg -i session-manager-plugin.deb
```

### AWS CLIのセットアップ
`Windows`ホスト側で設定しているAWS CLIの設定とは共有できないため、`Ubuntu`側にも設定します。

```bash:AWS CLIのセットアップ
aws configure
```

### Tera TermでのEC2インスタンスへの接続
ここまでで`Ubuntu`側の設定が一通りできたので、`Tera Term`で接続します。

`Ubuntu`側でSSHサービスを起動すると、`Windows`側でもSSHサービスの待受がされているはずなので、`Tera Term`で以下のように接続します。

|項目|設定|
|:--|:--|
|ホスト|localhost|
|サービス|SSH|
|TCPポート|22|
|SSHバージョン|SSH2|
|IPバージョン|AUTO|

接続する際、`Windows`ホスト側のユーザ名、パスワードで接続できるかと思いますので、入力して接続します。

|項目|設定|
|:--|:--|
|ユーザ名|※Windowsホスト側ユーザ名|
|パスフレーズ|※Windowsホスト側パスワード|
|認証方式|プレインパスワードを使う|

`Tera Term`で接続できてしまえば後はセッションマネージャーのコマンドでEC2インスタンスに接続してください。

```bash:セッションマネージャーでの接続
aws ssm start-session　--target [接続先EC2インスタンスID]
```

## ローカルPCでOpenSSHサーバ機能を動作させてローカルSSHサーバ経由で接続を行う
方法としてはWSLで起動した仮想マシン経由で接続する方法と同じような接続構成となりますが、WSLの場合と異なり、標準のオプション機能の有効化で済む点がWSLよりは手軽にできるかと思います。

- [Windows 用 OpenSSH の概要](https://learn.microsoft.com/ja-jp/windows-server/administration/openssh/openssh_install_firstuse?tabs=gui)

### OpenSSHサーバ機能で接続する場合の前提条件
OS標準のオプションを利用する方法となりますが、`WSL`の場合と同様、会社のポリシーにより有効化できない場合は使用できませんので、別の手段を検討してください。

前提条件の確認のため、**管理者権限で`PowerShell`を起動**して以下を実行します。

```powershell:ビルトインAdministratorグループのメンバーであるかの確認
(New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent())).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
```

結果が`True`で無い場合は別の手段をご検討ください。

### OpenSSHクライアントとサーバの有効化
今回はWindows11で設定を行っていきます。

Windows10等の場合は、先程の公式ページから確認してみてください。

`OpenSSH`はWindowsのオプション機能から有効化できるので、「**設定**」から「**システム**」→「**オプション機能**」を選択します。

![Monosnap_20240727_111439.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569912/93959d19-2d20-2bb3-24f2-87dc753a955f.png)

「**追加された機能**」に「**OpenSSHサーバ**」と「**OpenSSHクライアント**」があるかを確認し、「**オプション機能を追加する**」の「**機能を表示**」から有効化されていないサービスにチェックして有効化します。
※OpenSSHクライアントについてはデフォルトで有効になっているかもしれません。

![Monosnap_20240727_112705.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569912/e656fbac-47b5-3036-680c-aca7d55e4507.png)

OpenSSHサーバ有効化後、Windows起動時に自動でサービスを起動するようにします。

Windowsボタンから「**services.msc**」と検索し、「**サービス**」を選択。

![Monosnap_20240727_113841.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569912/19ed265c-7ae8-7482-0ac7-5d9196e4b62b.png)

「**サービス**」から「**OpenSSH SSH Server**」をダブルクリックし、プロパティ画面を開きます。

![Monosnap_20240727_113937.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569912/af59bd39-1d07-3a15-9bf0-4a277047ea02.png)

「**スタートアップの種類**」を「**自動**」にして、「**開始**」ボタンを選択してサービス起動しておきます。

![Monosnap_20240727_114059.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569912/3d1a2446-b847-2056-221a-38b02933ac7e.png)

### Tera TermでのローカルSSHサーバへの接続
OpenSSHサーバの準備ができたので、`Tera Term`で接続します。

`Ubuntu`に接続する場合と同様、localhostに接続するため、以下のように接続します。

|項目|設定|
|:--|:--|
|ホスト|localhost|
|サービス|SSH|
|TCPポート|22|
|SSHバージョン|SSH2|
|IPバージョン|AUTO|

接続する際、`Windows`ホスト側のユーザ名、パスワードで接続できるかと思いますので、入力して接続します。

|項目|設定|
|:--|:--|
|ユーザ名|※Windowsホスト側ユーザ名|
|パスフレーズ|※Windowsホスト側パスワード|
|認証方式|プレインパスワードを使う|

ローカルSSHサーバに接続できてしまえば、後は`Ubuntu`に接続した場合と同様のため、セッションマネージャーコマンドで接続します。

```bash:セッションマネージャーでの接続
aws ssm start-session　--target [接続先EC2インスタンスID]
```

![Monosnap_20240727_115537.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569912/510c349a-f2de-bd96-77d3-c827f036bd73.png)

もし接続できなかったり、パスワード認証ではなくSSH鍵認証で接続したい場合は以下の接続設定も行ってみてください。

### SSH鍵認証での接続
ユーザ名、パスワードで接続してから接続できなかった場合や、ユーザ名、パスワードでの接続ではなく、鍵認証での接続を行う場合に以下実行してください。

鍵認証での方法も以下公式ドキュメントに記載されておりますので、以下に沿って設定していきます。

- [Windows 用 OpenSSH でのキーベースの認証](https://learn.microsoft.com/ja-jp/windows-server/administration/openssh/openssh_keymanagement)

#### OpenSSHの設定変更
公式ドキュメントに記載されておりませんが、以下設定を行わないと鍵認証での接続がうまくいかなかったので設定します。

OpenSSHの設定を変更するため、「`C:\ProgramData\ssh\sshd_config`」をVS Code等のエディタで開いて、以下の設定箇所をコメントアウトします。

```powershell:C:\ProgramData\ssh\sshd_configでのコメントアウト
#Match Group administrators
#       AuthorizedKeysFile __PROGRAMDATA__/ssh/administrators_authorized_keys
```

保存する際、管理者権限が必要となるメッセージが表示されると思うので、管理者権限で保存します。

設定を反映するため、PowerShellを**管理者モードで起動して**OpenSSHを再起動します。

```powershell:OpenSSHサーバの再起動
Stop-Service sshd
Start-Service sshd
```

#### SSH鍵の生成
この後も管理者モードで操作する箇所があるため、そのまま以下進めていきます。

SSH接続する際のSSH鍵を生成します。

```powershell:SSHキーの生成
ssh-keygen -t ed25519
```

生成時、SSH鍵の出力先パスやパスフレーズが聞かれますが、すべてEnterでOKです。
※ファイル名等変更したい場合は任意で設定してください。

生成すると「`C:\Users\username/.ssh/`」に以下２つのファイルが作成されます。

|ファイル名|備考|
|:--|:--|
|id_ed25519|SSH秘密鍵|
|id_ed25519.pub|SSH公開鍵|

#### SSH Agentを使用したSSH秘密鍵の登録
ssh-addを使用してSSH秘密鍵を格納するためにSSH Agentを管理者権限で有効にします。

```powershell:自動起動の有効化とSSH Agentの起動
Get-Service ssh-agent | Set-Service -StartupType Automatic
Start-Service ssh-agent
```

起動後、`Get-Service`コマンドで確認することで、起動できたか確認できます。

```powershell:SSH Agentの状態確認
Get-Service ssh-agent
```

`ssh-add`コマンドで先程生成した秘密鍵を登録します。

```powershell:ssh-addによるSSH秘密鍵の登録
ssh-add $env:USERPROFILE\.ssh\id_ed25519
```

正常に登録できたかは`ssh-add -l`コマンドを実行することで確認できます。

```powershell:ssh-addの登録設定確認
ssh-add -l
256 SHA256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx username@hostname (ED25519)
```

#### 公開鍵の登録
SSH鍵認証でSSHサーバに接続する場合、`authorized_keys`ファイルにあらかじめSSH公開鍵を登録しておく必要があるため、登録を行っていきます。

登録は以下コマンドを実行することで、`authorized_keys`ファイルの作成や権限設定などいっぺんに行えるので、以下順番に実行します。

```powershell:$authorizedKey変数の指定
$authorizedKey = Get-Content -Path $env:USERPROFILE\.ssh\id_ed25519.pub
```

```powershell:$remotePowershell変数の指定
$remotePowershell = "powershell New-Item -Force -ItemType Directory -Path $env:USERPROFILE\.ssh; Add-Content -Force -Path $env:USERPROFILE\.ssh\authorized_keys -Value '$authorizedKey'"
```

上記の変数設定後、以下コマンドを実行することで、SSH鍵ファイルを格納した「`C:\Users\username/.ssh/`」配下に「`authorized_keys`」ファイルが作成・公開鍵の登録が行われます。

以下`username`の部分は自分の環境のユーザ名を指定してください。

```powershell
ssh username@localhost $remotePowershell
```

fingerprintの登録メッセージとパスワードが聞かれると思うので、fingerprintはyesで登録、パスワードは接続したユーザのパスワードを入力してください。

#### SSH秘密鍵でのSSH接続
上記までの手順で接続の準備ができたので、SSH鍵認証で接続できるか確認してみます。

`username`部分は自分の環境のユーザ名を指定して、以下コマンドを実行します。

```powershell:sshコマンドでのSSH接続確認
ssh username@localhost
```

ちゃんと設定できていればパスワードは聞かれず、自分自身にログインできたかと思います。

```powershell:ログイン時の表示例
Microsoft Windows [Version 10.0.22631.4037]
(c) Microsoft Corporation. All rights reserved.

username@ComputerName C:\Users\username>
```

#### Tera TermでのローカルSSHサーバへの接続（SSH鍵認証）
SSH鍵認証の設定を行ったので、`Tera Term`で接続してみます。

|項目|設定|
|:--|:--|
|ホスト|localhost|
|サービス|SSH|
|TCPポート|22|
|SSHバージョン|SSH2|
|IPバージョン|AUTO|

今回はSSH鍵認証を行うため、認証方式を「**RSA/DSA/ECDSA/ED25519鍵を使う**」で先ほど生成した秘密鍵を指定します。

|項目|設定|
|:--|:--|
|ユーザ名|※Windowsホスト側ユーザ名|
|パスフレーズ|空欄|
|認証方式|RSA/DSA/ECDSA/ED25519鍵を使う|
|秘密鍵|C:\Users\username\\.ssh\id_ed25519|

接続後はパスワードでの接続時と同様、セッションマネージャーコマンドで接続します。

## セッションマネージャーのポートフォワード機能を使用して接続を行う
SSHにも同様の機能がありますが、セッションマネージャーにもポートフォワード機能があるため、指定のポートを接続先EC2インスタンスのSSHポートにフォワードすることで接続する方法となります。

- [AWS Systems Manager Session Managerでポートフォワーディングを使用してリモートホストに接続する](https://aws.amazon.com/jp/blogs/news/use-port-forwarding-in-aws-systems-manager-session-manager-to-connect-to-remote-hosts-jp/)

EC2インスタンスに接続するまではセッションマネージャーで接続する方式となるため、セキュリティグループでSSHポートを許可する必要はありませんが、ポートフォワード先が接続先EC2インスタンスのSSHとなるため、今回の方式の場合、**キーペアの作成が必要となってしまう**ためご注意ください。

### セッションマネージャーのポートフォワードで接続する場合の前提条件
前述の通り、EC2インスタンスにSSH接続するためのキーペアが必要になります。

各システムのセキュリティ要件により、キーペアの作成ができない場合はこの手段を取ることができませんので、別の手段を検討してください。

### 事前準備：SSHキーペアの作成とEC2インスタンスの作成
今回の方式の場合、`PowerShell`等のプロンプトでセッションマネージャーポートフォワードのトンネルを作成し、`Tera Term`が対応しているSSHでEC2インスタンスに接続するため、AWS側でSSH接続用キーペアの作成とEC2インスタンスを作成しておきます。

前述の通り、セキュリティグループの設定は不要です。

### セッションマネージャーポートフォワードの実行
`PowerShell`等のプロンプトを開き、以下コマンドを実行します。

実行することで、AWSのセッションマネージャーとローカルPCとの間に擬似的なトンネルができ、`Tera Term`で、「**[任意の待受ポート]**」で指定したローカルPC側ポート番号にアクセスすると、接続先のEC2インスタンスのSSHポートにフォワーディングされるようになります。

```powershell:セッションマネージャーポートフォワードの実行
aws ssm start-session \
  --target [接続先EC2インスタンスID] \
  --document-name AWS-StartPortForwardingSession \
  --parameters portNumber=22,localPortNumber=[任意の待受ポート]
```

```powershell:セッションマネージャーポートフォワード実行後の出力例
Starting session with SessionId: xxxxx-yyyyyyyyyyyyyyyyyyyyyyyyyy
Port [任意の待受ポート] opened for sessionId xxxxx-yyyyyyyyyyyyyyyyyyyyyyyyyy.
Waiting for connections...
```

セッションマネージャーとのトンネルを維持するため、ウィンドウはそのままにして、`Tera Term`で以下のようにSSH接続すると接続先EC2インスタンスにログインできます。

|項目|設定|
|:--|:--|
|ホスト|localhost|
|サービス|SSH|
|TCPポート|※セッションマネージャーで指定した任意の待受ポート|
|SSHバージョン|SSH2|
|IPバージョン|AUTO|

ローカルのポートに接続できれば、ユーザ名等の入力画面が開くため、ユーザ名やキーペア情報を指定して接続します。

|項目|設定|
|:--|:--|
|ユーザ名|ec2-user|
|パスフレーズ|※空欄|
|認証方式|RSA/DSA/ECDSA/ED25519鍵を使う|
|秘密鍵|※EC2接続用キーペア|

問題なければ`Tera Term`でEC2インスタンスにログインできるはずです。

SSHキーペアの作成と、接続ユーザへのキーペアの共有が必要となるため、永続鍵を管理しないといけなくなる点は注意が必要です。

また、ポートフォワードのやり方次第でRDSに直接接続したり、プライベートサブネット上のサービスにアクセスしたりすることもできてしまう可能性があるため、システム管理者側の方たちからすると頭が痛い問題となるかもしれません。

もしこの方法を使用する場合、システム管理者の方はその点理解して利用するようにしましょう。

# おわりに
オンプレからクラウドに移るにあたり、昔から使っている`Tera Term`のようなソフトウェアから切り替えたいと思っていても、所属する組織の事情だったり、良い乗り換え先が見つからなかったりと、中々切り替えに踏み切れない方は多いかと思います。

私も以前は`Tera Term`マクロを書きまくっていたので、すんなり切り替えできないという気持ちはよくわかります。

ただ単に他のソフトウェアに切り替えるのではなく、今まで蓄えてきたマクロ等を活用して使い続けたい方の参考になればと思います。