EC2シリアルコンソールをSSHクライアントから利用する

話題沸騰 (一部方面で) の「EC2シリアルコンソール」について、「もう一つの接続方法」を試してみました。
2021.04.01

みなさん、こんにちは!
AWS事業本部の青柳@福岡オフィスです。

昨日、突如として発表された、EC2インスタンスへのシリアルポート接続を提供する「EC2シリアルコンソール」機能ですが、弊社に一定数生息する「元オンプレインフラおじさん」たちが妙に色めき立だって反応していました。
やっぱり、サーバー障害発生でシリアルケーブルを持ってトラブルシューティングに駆け付けるのは、男のロマンなんですかねぇ~ (女子も大歓迎)

まあ、私もその「元オンプレインフラおじさん」の一人なんですけどね!

早速、おじさんたち ネクストモード 吉井、コンサルティング部 柴田 がブログを公開しています。

これらのブログでは、Webブラウザ (AWSマネジメントコンソール) を使ってEC2シリアルコンソールを利用しています。

今回、もう一つの手段である「SSHクライアントを使った、コマンドラインによるEC2シリアルコンソールの利用」を試してみました。

SSHを使ったEC2シリアルコンソール利用の概要

図で表すと、このような感じだと思われます。

SSHクライアントからEC2インスタンスに対して直接接続している訳ではなく、まず、AWSのリージョン毎に用意されている「EC2シリアルコンソール」のエンドポイントに対してSSHプロトコルを使って接続します。

そして、EC2シリアルコンソールからEC2インスタンスに対してシリアルポート接続を行い、ユーザ名&パスワードを使ってOSにログインします。

この図をご覧頂いて「どこに対してSSHで接続するのか」を頭に入れた状態で、これから説明する利用手順を見て頂くと、理解し易いのではないかと思います。

前提条件 (利用のための準備)

これらの前提条件は、WebブラウザからEC2シリアルコンソールを利用する場合と同じです。
(「AWS CLIバージョン」の要件を除く)

吉井のブログ記事、および、AWSドキュメント を併せて参照ください。

AWS CLIが「EC2シリアルコンソール」に対応したバージョンになっていること

以下のバージョンがEC2シリアルコンソールに対応しています。

  • AWS CLI v2: バージョン 2.1.33 以降
  • AWS CLI v1: バージョン 1.19.41 以降

EC2シリアルコンソール機能が有効化されていること

AWSマネジメントコンソールより、EC2サービスのダッシュボード画面にある「EC2 Serial Console」の設定で、機能を有効化してください。

もしくは、AWS CLIを使っても有効化を行うことができます。

$ aws ec2 enable-serial-console-access --region ap-northeast-1

※ AWS CLIのバージョンが前述の条件を満たさなければaws ec2 enable-serial-console-accessコマンドは使えません。

接続で使用するIAMユーザーに必要な権限が与えられていること

SSHクライアントで接続を行う前に、用意したSSH公開鍵をEC2シリアルコンソールのエンドポイントにアップロードする必要があります。

この操作 (AWS CLIコマンド実行) を行う際、IAMユーザーに権限が必要となります。

IAMユーザー (またはIAMロール等) に以下の権限を付与してください。
ec2-instance-connect:SendSerialConsoleSSHPublicKey

IAMユーザーへの権限の与え方については、以下のようなパターンがあります。

  • 全てのEC2インスタンスに対してEC2シリアルコンソールの利用を許可する
  • 特定のEC2インスタンスのみに対して許可する
  • 原則全てのEC2インスタンスに対して許可するが、特定のEC2インスタンスに関しては禁止する
  • タグによってアクセス可否を制御する (例:EC2インスタンスに付与したタグとIAMユーザーに付与されたタグの値が一致する場合のみ許可)

詳細は、AWSドキュメントの該当部分を参照してください。
https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/configure-access-to-serial-console.html#serial-console-iam

EC2インスタンスが「EC2シリアルコンソール」に対応したインスタンスクラスで起動されていること

EC2シリアルコンソールを利用するには、EC2インスタンスがNitroベースのインスタンスファミリーである必要があります。

具体的には以下のインスタンスクラスが対応しています。(2021/03/31時点)

  • A1
  • C5, C5a, C5ad, C5d, C5n, C6g, C6gd
  • M5, M5a, M5ad, M5d, M5dn, M5n, M5zn, M6g, M6gd
  • R5, R5a, R5ad, R5d, R5dn, R5n, R6, R6gd
  • T3, T3a, T4g
  • Z1d

ログインで使用するOSユーザーにパスワードが設定されていること

前述の図で説明した通り、EC2インスタンスのOSにログインするためには、OS上のユーザー名とパスワードでログインする必要があります。

SSHキーペアが登場するので「パスワード無しで接続できるのでは」と期待してしまうかもしれませんが、SSHキーペアを使うのはあくまで「EC2シリアルコンソール」のエンドポイントへの接続です。

ですので、ログインに使用するOSユーザーに対して、事前に必ずパスワードを設定しておきましょう。

例えば、障害発生時のトラブルシューティングを想定して、rootユーザーを使ってOSにログインしたい場合は、rootユーザーにパスワードを設定しておく必要があります。

$ sudo passwd root
Changing password for user root.
New password:
Retype new password:
passwd: all authentication tokens updated successfully.

もしくは、メンテナンス専用のユーザーを作成して、そちらにパスワードを設定するというやり方もあるかもしれません。

接続

それでは、実際にEC2インスタンスへシリアルポート接続を行ってみましょう。

用意したIAMユーザーでAWS CLIが実行できるように設定する

~/.aws/credentialsにIAMユーザーのアクセスキーID/シークレットアクセスキーを記述する」「プロファイルでIAMロールのスイッチロールが行えるように設定する」など、必要な設定を行ってください。

SSHの公開鍵と秘密鍵のペアを作成する

SSH鍵認証で用いるキーペア (公開鍵と秘密鍵の組) を作成します。

使用できるキーペアの要件は、EC2インスタンスに独自のキーペアをインポートして使用する際の「キーペアの要件」と同じです。

参考: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-key-pairs.html#how-to-generate-your-own-key-and-import-it-to-aws

例えば、次のようなコマンドでキーペアを作成することができます。

$ ssh-keygen -t rsa -b 2048 -f ~/.ssh/serial-console-key
Generating public/private rsa key pair.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/user/.ssh/serial-console-key.
Your public key has been saved in /home/user/.ssh/serial-console-key.pub.
The key fingerprint is:
(以下略)

秘密鍵のパスフレーズは必要に応じて設定してください。(未指定でももちろん構いません)

SSH公開鍵をEC2シリアルコンソールのエンドポイントにアップロードする

AWS CLIのコマンドを実行して、SSH公開鍵のアップロードを行います。

$ aws ec2-instance-connect send-serial-console-ssh-public-key \
    --instance-id i-12345678901234567 \
    --serial-port 0 \
    --ssh-public-key file://~/.ssh/serial-console-key.pub \
    --region ap-northeast-1

--instance-idには、接続対象EC2インスタンスのインスタンスIDを指定します。

--serial-portは、0で固定です。(現時点では、ポート番号は「0」のみがサポートされています)

--ssh-public-keyには、作成したキーペアの「公開鍵」の方を指定します。

コマンドが正常に実行されると、以下のように結果が表示されます。

{
    "RequestId": "12345678-1234-1234-1234-123456789012",
    "Success": true
}

なお、アップロードしたSSH公開鍵は「60秒間」だけ有効であることに留意してください。

60秒が経過すると、アップロードしたSSH公開鍵は自動的に削除され、使用できなくなります。
その場合は、再度コマンドを実行してアップロードを行ってください。

EC2シリアルコンソールに接続する

SSHクライアントを使ってEC2シリアルコンソールのエンドポイントに接続します。

$ ssh -i ~/.ssh/serial-console-key i-12345678901234567.port0@serial-console.ec2-instance-connect.ap-northeast-1.aws

-iオプションで、作成したキーペアの「秘密鍵」を指定します。

接続先の指定は「SSHログインユーザー名@接続先ホスト名」となっています。

  • 「SSHログインユーザー名」は、EC2インスタンスのインスタンスID.port0となります。
  • 「接続先ホスト名」は、リージョン毎に用意されたエンドポイントのFQDN名でserial-console.ec2-instance-connect.リージョン名.awsとなります。

初回接続時 (SSHサーバーの公開鍵フィンガープリントの確認)

各リージョンのEC2シリアルコンソールのエンドポイントに初めて接続した際、SSHサーバー (=エンドポイント) が持つ公開鍵のフィンガープリントの確認を求められます。

このあたりは、一般的なSSH接続の際と同様ですので、理解されている方は読み飛ばしてください。
以下「なんじゃこりゃ?」という方のための解説です。

The authenticity of host 'serial-console.ec2-instance-connect.ap-northeast-1.aws (3.112.64.15)' can't be established.
RSA key fingerprint is SHA256:RQfsDCZTOfQawewTRDV1t9Em/HMrFQe+CRlIOT5um4k.
Are you sure you want to continue connecting (yes/no)?

これは、いわゆる「中間者攻撃」を未然に防ぐためのもので、フィンガープリントが確かにエンドポイントのものであることを確認できたら、「yes」を入力して続行します。

各リージョン毎のエンドポイントが持つ公開鍵のフィンガープリント一覧は、下記AWSドキュメントを参照ください。
https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/connect-to-serial-console.html#sc-fingerprints

「yes」で続行すると、以下のようになります。(「信頼できる既知の接続先ホストとして登録しましたよ!」という意味)

Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'serial-console.ec2-instance-connect.ap-northeast-1.aws,3.112.64.15' (RSA) to the list of known hosts.

この後、EC2インスタンスのOSログイン画面が表示されるはず・・・なのですが、
私が試してみた際は、ここで何故かエンドポイントから強制切断されてしまいました。

Connection closed by 3.112.64.15 port 22

原因が分からなかったのですが、再度sshコマンドで接続を試みたところ、今度は問題なくOSログイン画面まで表示されました。

接続に失敗したパターン

以下のようなエラーメッセージが表示される場合があります。

i-12345678901234567.port0@serial-console.ec2-instance-connect.ap-northeast-1.aws: Permission denied (publickey).

このメッセージが表示された場合、SSH公開鍵のアップロードから60秒が経過してしまった可能性があります。

もう一度、「SSH公開鍵をEC2シリアルコンソールのエンドポイントにアップロードする」からやり直してみてください。

OSログイン画面の表示 ~ ユーザー名/パスワードによるログイン

さて、問題なくEC2シリアルコンソールのエンドポイントにSSH接続すると、EC2シリアルコンソールからEC2インスタンスへシリアルポート接続が行われ、EC2インスタンスのOSログイン画面が表示されるはずです。

(何も表示されない場合、Enterキーを1回入力してみるとよいでしょう)

Amazon Linux 2
Kernel 4.14.225-169.362.amzn2.x86_64 on an x86_64

ip-192.168.xx.xx login:

パスワード設定済みのユーザーでログインします。

ip-192.168.xx.xx login: root
Password:

ちゃんとログインできました!!

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

https://aws.amazon.com/amazon-linux-2/
[root@ip-192-168-xx-xx ~]#

OSからのログオフ、EC2シリアルコンソールの接続終了

OSからログオフするには、通常通りにexitコマンドを実行してください。

[root@ip-192-168-xx-xx ~]# exit
logout

Amazon Linux 2
Kernel 4.14.225-169.362.amzn2.x86_64 on an x86_64

ip-192-168-xx-xx login:

OSログイン画面まで戻りました。

ここでEC2シリアルコンソールの接続を終了するには、「Ctrl+C」を入力したりせずに、以下のようにしてください。

  • キーボードから「~」、「.」の順にタイピングする。(Enterは押さない)

これで、以下のメッセージが表示され、EC2シリアルコンソールの接続が終了します。

ip-192-168-xx-xx login: Connection to serial-console.ec2-instance-connect.ap-northeast-1.aws closed.

おわりに

Webブラウザではなく、SSHクライアントを使ってEC2シリアルコンソールを利用するメリットとしては、以下のようなものが考えられます。

  • 使い慣れている環境 (SSHクライアントやターミナル) が使える
  • SSHクライアントやターミナルのロギング機能を使って、操作ログを記録できる

操作ログについては、「ログの記録を強制化」している訳ではないため、監査などの目的であれば「SSMセッションマネージャー」などの利用を検討してください。

また、今回Linuxインスタンスへの接続のみでWindowsインスタンスへの接続は試していませんが、恐らく同様の手順で接続できるのではないかと思います。

いざという場合のトラブルシューティングや、あるいは他の用途でも使えそうな「EC2シリアルコンソール」を、是非試してみてください!