pecoを使ったssh接続先を一覧表示するスクリプトを実装してみた
Introduction
pecoを使って踏み台サーバーから接続先EC2をリストアップし、ssh接続を自動化するec2-sshスクリプトを実装する
pecoとは?
pecoはLinuxやMacなどで利用できるフィルタリングコマンドツールである。
https://github.com/peco/peco
コマンド履歴の検索性能をあげたり、今回のように必要なインスタンス情報を
抽出して一覧表示してくれるようにしたりすることができる便利ツール
構成図
接続元アカウント(A)から接続先アカウント(B)で稼働しているEC2インスタンスの一覧をpecoで取得してみる
事前準備
- 事前にVPC間の接続およびEC2インスタンスが準備できていること
- bastion01サーバー(踏み台サーバー)からtest001、test002サーバー間は事前にSSH接続ができるようになっていること
- 今回はテストサーバーなので、以下スペックのインスタンスに統一
- OS:
Amazon Linux 2
- インスタンスタイプ:
t2.micro
- OS:
How to
概要手順
- クロスアカウントロールの作成 @アカウントB
- bastion01用サーバーロール(インスタンスプロファイル)の作成 @アカウントA
- pecoのインストール @bastion01
- jqコマンドのインストール @bastion01
- ec2-sshスクリプトの配置 @bastion01
クロスアカウントロールの作成
- アカウントB(EC2インスタンスをリストアップしたい対象先)のアカウントにてAssumeRoleを作成
-
IAMのロール画面から
ロールを作成
をクリック -
以下パラメータを設定して「次へ」をクリック
- 信頼されたエンティティタイプ:
AWSアカウント
- AWSアカウント:
別のアカウント
- アカウントID:
アカウントAのID
※必要に応じてオプションを追加(今回は設定なし)
- 信頼されたエンティティタイプ:
-
許可ポリシーに
AmazonEC2ReadOnlyAccess
を追加して「次へ」をクリック -
ロール名を入力して「ロールを作成」をクリック
-
作成完了
-
「信頼関係」タブから[信頼ポリシーを編集]をクリック
-
Conditionに以下内容を追記して更新
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::アカウントAのID:root" }, "Action": "sts:AssumeRole", "Condition": { //以下内容を追記 "StringEquals": { "sts:ExternalId": "test-ssh-bastion" } } } ] }
bastion01用サーバーロール(インスタンスプロファイル)の作成 @アカウントA
- アカウントAにて、bastion01サーバーからアカウントBのEC2インスタンス閲覧用権限を付与するためにIAMロールを作成
-
IAMのポリシー画面から「ポリシーを作成」を選択
-
AssumeRoleを許可
{ "Version": "2012-10-17", "Statement": [ { "Sid": "EC2SSHPolicy", "Effect": "Allow", "Action": "sts:AssumeRole", "Resource": "arn:aws:iam::741420225566:role/ec2-ssh-accept-role" } ] }
-
名前を入力して「ポリシーの作成」をクリック
-
IAMのロール画面にて「ロールの作成」をクリック
-
信頼されたエンティティに
EC2
を選択 -
先ほど作成したポリシーを選択
-
ロール名をつけて、「ロールを作成」をクリック
-
ロールが作成されたので、これをbastion01インスタンスにアタッチをしましょう
-
bastion01インスタンスを選択して「アクション」-「セキュリティ」-「IAMロールを変更」をクリック
-
作成したIAMロールを選択して「IAMロールの更新」をクリック
-
アタッチされていることを確認
pecoのインストール
- bastion01でpecoをインストールします
- 最新版は以下の公式リポジトリを参照
https://github.com/peco/peco/releases
-
Githubリポジトリからpecoをインストール(ここではx86_64の最新バージョンをインストール)
[root@bastion01 ~]# wget https://github.com/peco/peco/releases/download/v0.5 10/peco_linux_amd64.tar.gz --2023-01-02 11:34:52-- https://github.com/peco/peco/releases/download/v0.5 10/peco_linux_amd64.tar.gz Resolving github.com (github.com)... 20.27.177.113 Connecting to github.com (github.com)|20.27.177.113|:443... connected. HTTP request sent, awaiting response... 302 Found Location: https://objects.githubusercontent.com github-production-release-asset-2e65be/20553267 cbc7b300-c885-11eb-90e5-bd7ad29383d0?X-Amz-Algorithm=AWS4-HMAC-SHA256 X-Amz-Credential=AKIAIWNJYAX4CSVEH53A%2F20230102%2Fus-east-1%2Fs3%2Faws4_req est&X-Amz-Date=20230102T113452Z&X-Amz-Expires=300 X-Amz-Signature=eee259616e4478553ef122ee5a3c43f20acfc523d6e983fb4fb0025a0d56 863&X-Amz-SignedHeaders=host&actor_id=0&key_id=0&repo_id=20553267 response-content-disposition=attachment%3B%20filename%3Dpeco_linux_amd64.tar gz&response-content-type=application%2Foctet-stream [following] --2023-01-02 11:34:52-- https://objects.githubusercontent.com github-production-release-asset-2e65be/20553267 cbc7b300-c885-11eb-90e5-bd7ad29383d0?X-Amz-Algorithm=AWS4-HMAC-SHA256 X-Amz-Credential=AKIAIWNJYAX4CSVEH53A%2F20230102%2Fus-east-1%2Fs3%2Faws4_req est&X-Amz-Date=20230102T113452Z&X-Amz-Expires=300 X-Amz-Signature=eee259616e4478553ef122ee5a3c43f20acfc523d6e983fb4fb0025a0d56 863&X-Amz-SignedHeaders=host&actor_id=0&key_id=0&repo_id=20553267 response-content-disposition=attachment%3B%20filename%3Dpeco_linux_amd64.tar gz&response-content-type=application%2Foctet-stream Resolving objects.githubusercontent.com (objects.githubusercontent.com)... 185.199.110.133, 185.199.111.133, 185.199.108.133, ... Connecting to objects.githubusercontent.com (objects.githubusercontent.com) 185.199.110.133|:443... connected. HTTP request sent, awaiting response... 200 OK Length: 2204567 (2.1M) [application/octet-stream] Saving to: ‘peco_linux_amd64.tar.gz’ 100 [=========================================================================== =====================================>] 2,204,567 1.34MB/s in 1.6s 2023-01-02 11:34:55 (1.34 MB/s) - ‘peco_linux_amd64.tar.gz’ saved [2204567 2204567] ## インストールされている [root@bastion01 ~]# ll total 2156 -rw-r--r-- 1 root root 2204567 Dec 7 2021 peco_linux_amd64.tar.gz
-
ダウンロードしたファイルを解凍
[root@bastion01 ~]# tar zxf peco_linux_amd64.tar.gz [root@bastion01 ~]# ll total 2156 drwxr-xr-x 2 ec2-user ec2-user 50 Jun 8 2021 peco_linux_amd64 -rw-r--r-- 1 root root 2204567 Dec 7 2021 peco_linux_amd64.tar.gz [root@bastion01 ~]# ll peco_linux_amd64 total 4008 -rw-r--r-- 1 ec2-user ec2-user 18890 Jun 8 2021 Changes -rwxr-xr-x 1 ec2-user ec2-user 4049673 Jun 8 2021 peco -rw-r--r-- 1 ec2-user ec2-user 29754 Jun 8 2021 README.md
-
解凍したフォルダ内にpecoの実行ファイルが入っているので
/usr/local/bin
に移動させましょう[root@bastion01 ~]# mv peco_linux_amd64/peco /usr/local/bin/ [root@bastion01 ~]# ll/usr/local/bin/ -bash: ll/usr/local/bin/: No such file or directory [root@bastion01 ~]# ll /usr/local/bin/ total 3956 -rwxr-xr-x 1 ec2-user ec2-user 4049673 Jun 8 2021 peco
-
バージョン情報が表示されれば、pecoのインストールが完了
[root@bastion01 ~]# peco --version peco version v0.5.10 (built with go1.16)
jqのインストール
-
peco実行時にEC2インスタンスの必要な情報を抽出するために、jqをインストールする
[root@bastion01 ~]# yum install jq Loaded plugins: extras_suggestions, langpacks, priorities, update-motd amzn2-core | 3.7 kB 00:00:00 Resolving Dependencies --> Running transaction check ---> Package jq.x86_64 0:1.5-1.amzn2.0.2 will be installed --> Processing Dependency: libonig.so.2()(64bit) for package: jq-1.5-1.amzn2.0.2.x86_64 --> Running transaction check ---> Package oniguruma.x86_64 0:5.9.6-1.amzn2.0.4 will be installed --> Finished Dependency Resolution Dependencies Resolved =========================================================================================================================================================== Package Arch Version Repository Size =========================================================================================================================================================== Installing: jq x86_64 1.5-1.amzn2.0.2 amzn2-core 154 k Installing for dependencies: oniguruma x86_64 5.9.6-1.amzn2.0.4 amzn2-core 127 k Transaction Summary =========================================================================================================================================================== Install 1 Package (+1 Dependent package) Total download size: 281 k Installed size: 890 k Is this ok [y/d/N]: y Downloading packages: (1/2): oniguruma-5.9.6-1.amzn2.0.4.x86_64.rpm | 127 kB 00:00:00 (2/2): jq-1.5-1.amzn2.0.2.x86_64.rpm | 154 kB 00:00:00 ----------------------------------------------------------------------------------------------------------------------------------------------------------- Total 1.9 MB/s | 281 kB 00:00:00 Running transaction check Running transaction test Transaction test succeeded Running transaction Installing : oniguruma-5.9.6-1.amzn2.0.4.x86_64 1/2 Installing : jq-1.5-1.amzn2.0.2.x86_64 2/2 Verifying : jq-1.5-1.amzn2.0.2.x86_64 1/2 Verifying : oniguruma-5.9.6-1.amzn2.0.4.x86_64 2/2 Installed: jq.x86_64 0:1.5-1.amzn2.0.2 Dependency Installed: oniguruma.x86_64 0:5.9.6-1.amzn2.0.4 Complete!
ec2-sshスクリプトの配置
-
作成するスクリプトでは
aws sts assume-role
コマンドを実行し、必要情報を取得できるようにする -
因みに、
aws sts assume-role
コマンドでは対象のロールに対する一時認証情報を取得することができる[root@bastion01 ~]# aws sts assume-role --role-session-name test-ssh --role-arn arn:aws:iam::${アカウントBのID}:role/ec2-ssh-accept-role --external-id test-ssh-bastion { "AssumedRoleUser": { "AssumedRoleId": "AROA2ZIAW2QPO4P6NMAPX:test-ssh", "Arn": "arn:aws:sts::${アカウントBのID}:assumed-role/ec2-ssh-accept-role/test-ssh" }, "Credentials": { "SecretAccessKey": "5C9/VpDU9yWY8QITXV1goLnNh05GAptQvuneHNQN", "SessionToken": "FwoGZXIvYXdzEIX//////////wEaDCGJ4LGsqaUAUEUjliKsAWTBMJmJ9fsr2qTfRuUjGKQz8THi0QRpUd/535raO+RjSS4sT2T6JNqrTnlWavmzeh7jL8Q9d1niJjwXP7boziogsDpqagXv22+kZOVIKJvfexEUFlrcVzo7LgeDjsUiNSs3lVBzSzXY/9a9DNUmolDt+eF+83aE37dGVnCCOMvqZBHH9ZemG3C9DFALBWXUYgUx7ZFFHnuWQsmCDLG5gCdRC01DI4E7HrHZtGwoiorLnQYyLaYJCTzb8Bmu+lrsk/dwO35t5Yvn01IoEF0WdAWKmWMrHfgI+wxno3aklPoQ7w==", "Expiration": "2023-01-02T12:50:34Z", "AccessKeyId": "ASIA2ZIAW2QPAD5SRIVV" } }
-
/etc/bashrc
に以下内容を追記# For ssh list function ec2-ssh() { eval "$(aws sts assume-role --role-session-name test-ssh \ --role-arn "arn:aws:iam::${アカウントBのID}:role/ec2-ssh-accept-role" --external-id test-ssh-bastion \ --query '[Credentials.AccessKeyId, Credentials.SecretAccessKey, Credentials.SessionToken]' \ --output text | ( read AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_SECURITY_TOKEN export AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_SECURITY_TOKEN declare -p AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_SECURITY_TOKEN))" local user=`whoami` local host=$(aws ec2 describe-instances --region ap-northeast-1 --output json --filters "Name=instance-state-code,Values=16" | jq -r '.Reservations[].Instances[] | [.Tags[] | select(.Key == "Name").Value][] + "\t" + .InstanceType + "\t" + .PrivateIpAddress + "\t" + .Platform' | awk '{if ($4 != "windows") printf "%-45s %-15s %-10s\n",$1,$2,$3}' | sort | /usr/local/bin/peco | awk '{print $3}') ssh "$user@$host" }
-
/etc/bashrc
をsource
コマンドで再適用[root@bastion01 ~]# source /etc/bashrc
-
以上でセットアップ完了。
ec2-ssh
と打つとアカウントBの稼働中インスタンス一覧が表示される。
選択するとそのインスタンスにssh接続できるようになるec2-user@bastion01 ~]$ ec2-ssh QUERY> IgnoreCase [2 (1/1)] test001 t2.micro 10.100.1.133 test002 t2.micro 10.100.1.129 Last login: Mon Jan 2 11:31:47 2023 from ip-10-0-0-4.ap-northeast-1.compute.internal __| __|_ ) _| ( / Amazon Linux 2 AMI ___|\___|___| https://aws.amazon.com/amazon-linux-2/ [ec2-user@test001 ~]$
Commentary
-
SSHキーペアの作成は以下の記事を参考にすると良い。RSAかECDSAがおすすめ
[ec2-user@bastion01 ~]$ ssh-keygen -t ecdsa -b 521
Generating public/private ecdsa key pair.
Enter file in which to save the key (/home/ec2-user/.ssh/id_ecdsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/ec2-user/.ssh/id_ecdsa.
Your public key has been saved in /home/ec2-user/.ssh/id_ecdsa.pub.
The key fingerprint is:
SHA256:xeEQdi81+0C2Bv8GwOo0w4UQB0mBIc09cN6Gyu25L88 ec2-user@bastion01
The key's randomart image is:
+---[ECDSA 521]---+
| .oo*B*=+= = |
| .+o+=.=oX + |
| oooo= O |
| . o .*. o = |
| o .oSo + |
| . .. . |
| o |
| .o |
| .+E |
+----[SHA256]-----+
[ec2-user@bastion01 ~]$
[ec2-user@bastion01 ~]$ cat .ssh/id_ecdsa.pub
ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBAD96eEy8hJWAEafkmKRRjNXCTwUXClHMrz2wd4UAFCClwiqJZE6sBYsQl7VRtEZs94b4JPM/wnZZ7fNHKdY7c/KqwE6a2XyNy4i+Wgwf9QMJYPdoBgdOEDoRFKL2mrV6Kc1MMBqCCoGjlQvIBdtfLdxUQdvKESOA6Xqdnd6rMAqwbcrYw== ec2-user@bastion01
Discussion