はじめに
6/24(木)開催の「JAWS-UG CLI専門支部 #184R EC2入門」に参加した。
今回のハンズオンではユーザーデータを使ってWEBサーバの立ち上げを実施した。自分はユーザーデータを使ったのは初めてだったので、復習がてら、何かオリジナルのユーザーデータを使ってみようと思う。
といっても大層なものは思い浮かばなかったしサクッと試したかったので、タイトル通り、SSHのListenポートを変えてみることにした。
前提
今回は以下の前提で作業を実施する。
手順1. Cloud9への権限付与
Cloud9でEC2インスタンスの起動を実施するため、Cloud9用のIAMロールを作成し、"AmazonEC2FullAccess"権限を付与する。権限の付与はCloudShellで実施する。権限付与の流れはこちらの記事を参照。
手順2. ユーザーデータの作成
今回使うユーザーデータ
今回は、Amazon Linux2でSSHのListenポートを変更するスクリプトをユーザーデータとして用意した。
#!/bin/bash sed -i.old -e 's/#Port 22/Port 51512/g' /etc/ssh/sshd_config systemctl restart sshd
スクリプトと呼ぶのが憚られる簡便さだが、とりあえずユーザーデータを使った設定を試してみたいだけなのでよしとしよう。
なお、ユーザーデータはroot権限で実施されるので、sudoコマンドを使わないことに注意する。
また、Amazon Linux2では動作したが、他のディストリビューションで動くかどうかは不明。(SELinuxが有効かどうかでも変わると思うし、sshdコンフィグのパスが違う可能性もあるため)
ユーザーデータの格納
Cloud9上に上記のスクリプトを準備する。
[ec2-user@ip-10-0-0-127%]$ DIR_USER_DATA="${HOME}/environment/conf-handson-cli-ec2" [ec2-user@ip-10-0-0-127%]$ [ec2-user@ip-10-0-0-127%]$ ls -d ${HOME}/environment/conf-handson-cli-ec2 ls: cannot access /home/ec2-user/environment/conf-handson-cli-ec2: No such file or directory [ec2-user@ip-10-0-0-127%]$ [ec2-user@ip-10-0-0-127%]$ ls -d ${DIR_USER_DATA} ls: cannot access /home/ec2-user/environment/conf-handson-cli-ec2: No such file or directory [ec2-user@ip-10-0-0-127%]$ [ec2-user@ip-10-0-0-127%]$ mkdir -p ${HOME}/environment/conf-handson-cli-ec2 [ec2-user@ip-10-0-0-127%]$ [ec2-user@ip-10-0-0-127%]$ USER_DATA_NAME='ec2-ssh-port-change' [ec2-user@ip-10-0-0-127%]$ [ec2-user@ip-10-0-0-127%]$ FILE_USER_DATA="${DIR_USER_DATA}/${USER_DATA_NAME}.bash" \ > && echo ${FILE_USER_DATA} /home/ec2-user/environment/conf-handson-cli-ec2/ec2-ssh-port-change.bash [ec2-user@ip-10-0-0-127%]$ [ec2-user@ip-10-0-0-127%]$ cat << EOF > ${FILE_USER_DATA} > #!/bin/bash > > sed -i.old -e 's/#Port 22/Port 51512/g' /etc/ssh/sshd_config > > systemctl restart sshd > > EOF [ec2-user@ip-10-0-0-127%]$ [ec2-user@ip-10-0-0-127%]$ cat ${FILE_USER_DATA} #!/bin/bash sed -i.old -e 's/#Port 22/Port 51512/g' /etc/ssh/sshd_config systemctl restart sshd [ec2-user@ip-10-0-0-127%]$ ls ${FILE_USER_DATA} /home/ec2-user/environment/conf-handson-cli-ec2/ec2-ssh-port-change.bash [ec2-user@ip-10-0-0-127%]$
EC2インスタンスの起動
キーペアの作成
EC2インスタンスにSSH接続するために、キーペアを作成する。
[ec2-user@ip-10-0-0-127%]$ aws ec2 create-key-pair --key-name SampleKeyPair \ > --query 'KeyMaterial' \ > --output text > SampleKeyPair.pem [ec2-user@ip-10-0-0-127%]$
--query 'KeyMaterial'
は「暗号化されていないPEMエンコードされたRSA秘密鍵」の指定になる模様。
ちゃんと作成されているか確認してみる。
[ec2-user@ip-10-0-0-127%]$ aws ec2 describe-key-pairs --key-name SampleKeyPair { "KeyPairs": [ { "KeyPairId": "key-0d1de70fb6fa94734", "KeyFingerprint": "6e:ff:0b:0a:9c:02:81:86:92:fe:0b:6c:18:13:80:bf:85:49:c6:d1", "KeyName": "SampleKeyPair", "Tags": [] } ] } [ec2-user@ip-10-0-0-127%]$
問題なく作成されていた。作成された秘密鍵は、ローカルにダウンロードしておく。
EC2インスタンスの起動
いよいよEC2インスタンスを起動する。今回は以下のコマンド、オプションでEC2を起動する。
コマンド | 内容 |
---|---|
aws ec2 run-instances | EC2インスタンスを起動する |
--image-id <イメージID> | インスタンスのイメージIDを指定する |
--instance-type <インスタンスタイプ> | インスタンスタイプを指定する |
--tag-specifications <タグキー、値> | タグキーと値を指定する |
--user-data <ファイルパス> | ユーザーデータのファイルパスを指定する |
--associate-public-ip-address | パブリックIPアドレスの割当を行う |
--key-name <キーペア名> | キーペアを指定する |
上記の実行のために、変数を準備する。
[ec2-user@ip-10-0-0-127%]$ EC2_INSTANCE_IMAGE_NAME="amzn2-ami-hvm-2.0.20210525.0-x86_64-gp2" [ec2-user@ip-10-0-0-127%]$ [ec2-user@ip-10-0-0-127%]$ EC2_INSTANCE_TYPE="t2.micro" [ec2-user@ip-10-0-0-127%]$ [ec2-user@ip-10-0-0-127%]$ EC2_INSTANCE_IMAGE_ID=$( \ > aws ec2 describe-images \ > --filters Name=name,Values="${EC2_INSTANCE_IMAGE_NAME}" \ > --query 'Images[].ImageId' \ > --output text \ > ) \ > && echo ${EC2_INSTANCE_IMAGE_ID} ami-001f026eaf69770b4 [ec2-user@ip-10-0-0-127%]$ [ec2-user@ip-10-0-0-127%]$ EC2_INSTANCE_TAG_NAME='handson-cli-ec2-userdata_public_ip_address_default_vpc-instance' [ec2-user@ip-10-0-0-127%]$ EC2_TAG_KEY='Name' [ec2-user@ip-10-0-0-127%]$ [ec2-user@ip-10-0-0-127%]$ STRING_TAG_CONF="ResourceType=instance,Tags=[{Key=${EC2_TAG_KEY},Value=${EC2_INSTANCE_TAG_NAME}}]" \ > && echo ${STRING_TAG_CONF} ResourceType=instance,Tags=[{Key=Name,Value=handson-cli-ec2-userdata_public_ip_address_default_vpc-instance}] [ec2-user@ip-10-0-0-127%]$
変数の設定が完了したので、実際にEC2インスタンスを起動する。
[ec2-user@ip-10-0-0-127%]$ aws ec2 run-instances \ > --image-id ${EC2_INSTANCE_IMAGE_ID} \ > --instance-type ${EC2_INSTANCE_TYPE} \ > --tag-specifications ${STRING_TAG_CONF} \ > --user-data file://${FILE_USER_DATA} \ > --associate-public-ip-address \ > --key-name SampleKeyPair { "Groups": [], "Instances": [ { "AmiLaunchIndex": 0, "ImageId": "ami-001f026eaf69770b4", "InstanceId": "i-04e7cc3f33fe110c4", "InstanceType": "t2.micro", "KeyName": "SampleKeyPair", -------------- 中略 -------------- ], "OwnerId": "XXXXXXXXXXXX", "ReservationId": "r-048e604b224cb5961" } [ec2-user@ip-10-0-0-127%]$
コマンドが成功すると、EC2の情報が記述されたJSONが出力される。
セキュリティグループの更新
次に、デフォルトのセキュリティグループを更新し、ユーザーデータで指定したListenポートを許可するようにする。インバウンドルールを更新する際はaws ec2 authorize-security-group-ingress
コマンドを実施する。
コマンド | 内容 |
---|---|
aws ec2 authorize-security-group-ingress | インバウンドのセキュリティグループを更新する |
--group-name <グループ名> | セキュリティグループ名を指定する |
--protocol <プロトコル> | プロトコルを指定する |
--port <ポート番号> | ポート番号を指定する |
--cidr <CIDRブロック> | CIDRブロックを指定する |
実際にコマンドを実行する。
[ec2-user@ip-10-0-0-127%]$ EC2_SECURITY_GROUP_NAME='default' [ec2-user@ip-10-0-0-127%]$ [ec2-user@ip-10-0-0-127%]$ EC2_SECURITY_GROUP_PROTOCOL='tcp' [ec2-user@ip-10-0-0-127%]$ [ec2-user@ip-10-0-0-127%]$ EC2_SECURITY_GROUP_PORT='51512' [ec2-user@ip-10-0-0-127%]$ [ec2-user@ip-10-0-0-127%]$ EC2_SECURITY_GROUP_CIDR='0.0.0.0/0' [ec2-user@ip-10-0-0-127%]$ [ec2-user@ip-10-0-0-127%]$ aws ec2 authorize-security-group-ingress \ > --group-name ${EC2_SECURITY_GROUP_NAME} \ > --protocol ${EC2_SECURITY_GROUP_PROTOCOL} \ > --port ${EC2_SECURITY_GROUP_PORT} \ > --cidr ${EC2_SECURITY_GROUP_CIDR} [ec2-user@ip-10-0-0-127%]$
アクセス確認
EC2が立ち上がり、セキュリティグループも更新されたので、変更後のポート指定でSSH出来るか試してみる。
今回は、TeraTermを使用してSSHログインを試行する。
EC2インスタンスのグローバルIPアドレスの確認
まずはアクセスするために、EC2インスタンスのグローバルIPアドレスを確認する。
[ec2-user@ip-10-0-0-127%]$ EC2_IP_PUBLIC=$( \ > aws ec2 describe-instances \ > --filters Name=tag-key,Values=Name \ > Name=tag-value,Values=${EC2_INSTANCE_TAG_NAME} \ > --instance-ids ${ARRAY_EC2_INSTANCE_IDS} \ > --query "Reservations[].Instances[].PublicIpAddress" \ > --output text \ > ) \ > && echo ${EC2_IP_PUBLIC} 54.248.6.20 [ec2-user@ip-10-0-0-127%]$
TeraTermによるアクセス試行
続いてTeraTermでアクセスを試す。
サーバがTeraTermのknownhostsリストに未登録のため警告が出るが、問題ないので続行する。この時点で接続自体は出来ている。
あとは、事前にダウンロードした秘密鍵を使ってログインする。
問題なくログインできたので、sshdコンフィグの内容が書き換わっているか確認してみる。ついでにポートのListen状況も確認する。
[ec2-user@ip-172-31-45-52 ~]$ sudo cat /etc/ssh/sshd_config | grep Port Port 51512 #GatewayPorts no [ec2-user@ip-172-31-45-52 ~]$ [ec2-user@ip-172-31-45-52 ~]$ [ec2-user@ip-172-31-45-52 ~]$ netstat -alt Active Internet connections (servers and established) Proto Recv-Q Send-Q Local Address Foreign Address State tcp 0 0 localhost:smtp 0.0.0.0:* LISTEN tcp 0 0 0.0.0.0:sunrpc 0.0.0.0:* LISTEN tcp 0 0 0.0.0.0:51512 0.0.0.0:* LISTEN tcp 0 252 ip-172-31-45-52.a:51512 dynamic-xxx-xxx-xxx:51280 ESTABLISHED tcp6 0 0 [::]:sunrpc [::]:* LISTEN tcp6 0 0 [::]:51512 [::]:* LISTEN [ec2-user@ip-172-31-45-52 ~]$ [ec2-user@ip-172-31-45-52 ~]$
問題なさそう。あとは、このEC2インスタンスのプライベートIPアドレスが合っているかどうかも、念のためCloud9上で再確認する。
[ec2-user@ip-10-0-0-127%]$ aws ec2 describe-instances \ > --filters Name=tag-key,Values=Name \ > Name=tag-value,Values=${EC2_INSTANCE_TAG_NAME} \ > --instance-ids i-04e7cc3f33fe110c4 \ > --query "Reservations[].Instances[].PrivateIpAddress" \ > --output text 172.31.45.52 [ec2-user@ip-10-0-0-127%]$
こちらも想定通りだった。満足したので、後片付けをする。今回作成したEC2インスタンスやキーペアは全て削除し、デフォルトVPCからセキュリティグループをデタッチし、Cloud9のIAMロールから"AmazonEC2FullAccess"をデタッチする。(手順は割愛)
おわりに
今回は最低限のスクリプトを使って、ユーザーデータによる設定変更の確認が出来た。機会があれば、もう少し複雑な処理も試してみたいと思う。