社内の初心者向けAWS勉強会で実施している最初のテーマ「LAMP環境を構築しよう」のほぼ前段にあたるネットワークとアクセス中継用の踏み台サーバの構築の手順について。
「これが正解」というものでなく、「私はこうやって構築した」という手順です。
2020.06.19追記: 本記事の内容をTerraformで作成したパターンを以下にアップしました。
[Terraform / AWS] 勘と雰囲気と勢いでEC2インスタンス作成してsshアクセスまで入門 - zaki work log
2021.04.17追記: Terraform v0.15の場合を以下にアップしました。
Terraformをv0.15に更新してAWSにEC2を作成するサンプルを動作 - zaki work log
踏み台サーバとネットワークの作成
サービス全体のネットワークと踏み台サーバを作成する。
このページまでの完成予定図は以下の通り。
ネットワークの設定
まず、EC2を作る際に設定するネットワークから作成する。
コンソールはEC2と別のVPCのところだ!
ダッシュボードはこんな感じ
VPCの作成
メニューからVPCを選択。
デフォルトで1件あるけど勉強会用に1件作成する
ネットワークアドレスはわかりやすいものを。
雑魚なので計算しやすいようにサブネットマスクは16ビットで(
設定項目 | 値 |
---|---|
名前タグ | vpc-aws-study-example |
IPv4 CIDR block | 172.26.0.0/16 |
IPv6 CIDR block | なし |
テナンシー | デフォルト |
テナンシーって知らない。info見る感じでは「これを設定したVPCに属するインスタンスはハードウェア専有」するっぽい。インスタンス単位に設定(?)されるDedicatedインスタンスに比べて、サービス全体をまとめて専有させる感じかな? (未確認)
サブネットの作成
作成するサブネットは3つ
- 踏み台サーバ(public)
- Webサーバ用(x2)(private)
サブネットの作成画面で必要事項を入力。
[VPC]は作成したVPCを選択する。
[IPv4 CIDR ブロック]は、VPCで作成したアドレスと矛盾がないものを入力する。
ちなみにアドレスがおかしい場合はエラーになる
この要領で3つのサブネットを作成する。
ポイントは以下の
- 全てVPCのアドレス内であること
- ネットワークをすべて分けること
- privateの1と2は異なるAZにすること
名前 | AZ | IPv4 CIDR block |
---|---|---|
public-subnet-aws-study | ap-northeast-1a | 172.26.10.0/24 |
private1-subnet-aws-study | ap-northeast-1a | 172.26.20.0/24 |
private2-subnet-aws-study | ap-northeast-1c | 172.26.30.0/24 |
ちなみにこの時点では、サブネットがpublicなのかprivateなのかの設定は存在しない。
インターネットゲートウェイ(IGW)の作成
このままだとインターネットから繋がらないので。
メニューはルートテーブルが先にあるが、ルートテーブルの設定でIGWの選択があるのでこちらを先に実施する。
設定は名前のみ
detached状態で作成される
[アクション]から[VPCにアタッチ]を選択
作成したVPCを選択して[アタッチ]する
ルートテーブルの作成
VPCとサブネットの作成で、メインのデフォルト設定のルーティングが作成されている。
関連付けられているサブネット
ルートテーブルは変更・削除不能のデフォルト設定がある(AWS認定ソリューションアーキテクト(アソシエイト) p.27-28)ため、勝手に作られたこのルートテーブルをprivate通信用に設定する(タグ付け)
このデフォルトのルートテーブルと別に、IGWへのルーティングを持つルートテーブルを作成する。
インターネットゲートウェイをデフォルトゲートウェイとして追加するため[編集]押下
[別のルートを追加]を押下
送信先に0.0.0.0/0
を入力、ターゲットに作成済みインターネットゲートウェイを選択して[保存]
作成されました
※ 作成後すぐはステータスが空欄になっているが、しばらく経てばアクティブになる
サブネットの関連付けで[編集]を押下し、パブリックサブネットとして作成したサブネットを追加する
パブリックサブネットだけを追加する
これでインスタンス作成時のサブネットの設定でpublic-subnet-aws-study
を使えばインターネットからアクセスでき、private1-subnet-aws-study
かprivate2-subnet-aws-study
を選択するとアクセスできない設定ができる。(グローバルIPの割り当ては設定で可能だが、インターネットからは接続できない状態になる。同じサブネット(や、VPC内)の別ホストからなら当然接続できる。)
と思いきや、これでEC2インスタンス作成してもDNSでホスト名が割り当てられない。VPC作成したあとに「DNSホスト名」の項目を有効にする必要があった。(IPアドレスでアクセスはできるけど)
セキュリティグループの設定
デフォルトのセキュリティグループは「同一セキュリティグループ内の制限なしアクセス」が定義されているだけなので、踏み台サーバに必要な「外部(internet)からのssh接続を許可」するルールを作成する。ついでにpingも。
[セキュリティグループの作成]から
[インバウンドのルール]を開き、sshとicmpのルールを追加、ソースを0.0.0.0/0
とする(アクセス元を限定できるなら絞ってよいし、pingしないならicmpは追加しなくてもよい)
これでこのEC2のセキュリティグループ設定でこれを選択すれば、sshとicmpのみアクセス可のホストが稼働する。
踏み台サーバの作成と疎通確認
踏み台サーバとなるEC2作成
EC2ダッシュボードのインスタンスから[インスタンスの作成]
AMIの選択で[Amazon Linux AMI 2018.03.0 (HVM), SSD Volume Type
]を選択 (「無料利用枠の対象」の中から自分が使いやすいものを選べばよいはず)
インスタンスタイプの選択は無料利用枠の対象になっているものを選択
インスタンスの詳細の設定で、今まで作成したVPCなどの設定を入力。
特に「自動割り当てパブリックIP」は、デフォルト値が「サブネット設定を使用 (無効)」になっている場合は、そのままではグローバルIPが割り振られないため、「有効化」に変更する (ここに気付かずにハマったw)
ストレージの追加はデフォルトのままでよい。
タグは何かわかりやすいものを(後から追加しても良い)
セキュリティグループの設定は、作成した「ssh+icmp」の設定と、デフォルトのセキュリティグループを両方追加する。
デフォルトのセキュリティグループを追加するのは、VPC内の他のホストとの通信を許可するため。(作成済みの「ssh+icmp」のルールは、それ以外の通信は許可していない)
最後にキーペアの設定で、既存のキーペア(手元に作成済み秘密鍵があること)があればそれを、なければ新規作成する。
作成が始まったら、IPv4 パブリックIP(グローバルIP)が割り振られていることを確認する。
起動が完了(ステータスチェックが2/2 のチェックに合格しました
)したらsshしてみる
zaki@wensley% ssh -i ~/.ssh/aws-practice.pem ec2-user@13.*.*.*
The authenticity of host '13.*.*.* (13.*.*.*)' can't be established.ECDSA key fingerprint is SHA256:2BazoYSh48BRw6PzFJp6kllzugOPKcFzuqSX6ec9NcA.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '13.*.*.*' (ECDSA) to the list of known hosts.
__| __|_ )
_| ( / Amazon Linux AMI
___|\___|___|
https://aws.amazon.com/amazon-linux-ami/2018.03-release-notes/
[ec2-user@ip-172-26-10-233 ~]$
[ec2-user@ip-172-26-10-233 ~]$
[ec2-user@ip-172-26-10-233 ~]$ uname -a
Linux ip-172-26-10-233 4.14.62-65.117.amzn1.x86_64 #1 SMP Fri Aug 10 20:03:52 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
[ec2-user@ip-172-26-10-233 ~]$
[ec2-user@ip-172-26-10-233 ~]$
[ec2-user@ip-172-26-10-233 ~]$
[ec2-user@ip-172-26-10-233 ~]$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc pfifo_fast state UP group default qlen 1000
link/ether 06:57:3e:1b:d4:c6 brd ff:ff:ff:ff:ff:ff
inet 172.26.10.233/24 brd 172.26.10.255 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::457:3eff:fe1b:d4c6/64 scope link
valid_lft forever preferred_lft forever
[ec2-user@ip-172-26-10-233 ~]$
プライベートサブネットのEC2作成
手順は踏み台サーバと同じ。
選択するサブネットの選択で、private2-subnet-aws-study
を選択する(プライベートでかつ、AZも踏み台サーバと異なるものでも接続できることを確認する)。
自動割り当てパブリックIPは無効化
また、セキュリティグループは外部からのssh接続は許可しない(というより、そもそもネットワークが繋がっていないが)ので、デフォルト(同一セキュリティグループ内のみアクセス制限なし)のみ選択
踏み台サーバもデフォルトのセキュリティグループを割り当てているため、踏み台サーバとの通信はこれで確保される。
パブリックIPの割り当てを無効にしているので、IPv4 パブリックIPが空欄になっている。(仮に割り当てても、グローバルIPは割り当てられるが、通信は繋がらない)
踏み台サーバからpingを飛ばして生きていることを確認
[ec2-user@ip-172-26-10-233 ~]$ ping 172.26.30.108
PING 172.26.30.108 (172.26.30.108) 56(84) bytes of data.
64 bytes from 172.26.30.108: icmp_seq=1 ttl=255 time=2.74 ms
64 bytes from 172.26.30.108: icmp_seq=2 ttl=255 time=2.65 ms
64 bytes from 172.26.30.108: icmp_seq=3 ttl=255 time=2.75 ms
--- 172.26.30.108 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2003ms
rtt min/avg/max/mdev = 2.656/2.717/2.756/0.074 ms
[ec2-user@ip-172-26-10-233 ~]$
踏み台サーバ経由でプライベートサブネットのEC2にsshアクセス
ウィザードに沿ってEC2を構築すると、秘密鍵はサーバ内には配置されないので、このままでは踏み台サーバから直接sshアクセスはできない。
[ec2-user@ip-172-26-10-233 ~]$ ssh ec2-user@172.26.30.108
The authenticity of host '172.26.30.108 (172.26.30.108)' can't be established.
ECDSA key fingerprint is SHA256:3RtRrtt6xi+cQD6a+bCBqflJyedjoffDu0zsqRi0yv0.
ECDSA key fingerprint is MD5:df:66:2d:1f:8a:4e:40:94:98:fe:77:47:d5:3e:6e:24.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '172.26.30.108' (ECDSA) to the list of known hosts.
Permission denied (publickey).
[ec2-user@ip-172-26-10-233 ~]$
アクセスするには基本的に以下の2パターン
- 踏み台サーバに秘密鍵をアップロードし、その秘密鍵で認証する
- 「踏み台サーバ経由でアクセス」するためのsshのProxyCommandオプションで、外部(インターネットから)一気にアクセスする
ProxyCommandオプションを使ったsshアクセス方法
- 踏み台サーバのアドレス(グローバル):
13.*.*.*
- プライベートサブネットのEC2のアドレス(ローカル):
172.26.30.108
実行するコマンドは
ssh -o ProxyCommand='ssh -i <aws-practice.pem> ec2-user@<踏み台サーバのパブリックIP> -W <プライベートサーバのローカルIP>:22' -i <aws-practice.pem> ec2-user@<プライベートサーバのローカルIP>
zaki@wensley% ssh -o ProxyCommand='ssh -i ~/.ssh/aws-practice.pem ec2-user@13.*.*.* -W 172.26.30.108:22' -i ~/.ssh/aws-practice.pem ec2-user@172.26.30.108
The authenticity of host '172.26.30.108 (<no hostip for proxy command>)' can't be established.
ECDSA key fingerprint is SHA256:3RtRrtt6xi+cQD6a+bCBqflJyedjoffDu0zsqRi0yv0.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '172.26.30.108' (ECDSA) to the list of known hosts.
__| __|_ )
_| ( / Amazon Linux AMI
___|\___|___|
https://aws.amazon.com/amazon-linux-ami/2018.03-release-notes/
[ec2-user@ip-172-26-30-108 ~]$
[ec2-user@ip-172-26-30-108 ~]$
[ec2-user@ip-172-26-30-108 ~]$ uname -a
Linux ip-172-26-30-108 4.14.62-65.117.amzn1.x86_64 #1 SMP Fri Aug 10 20:03:52 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
[ec2-user@ip-172-26-30-108 ~]$
[ec2-user@ip-172-26-30-108 ~]$
[ec2-user@ip-172-26-30-108 ~]$
[ec2-user@ip-172-26-30-108 ~]$
[ec2-user@ip-172-26-30-108 ~]$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc pfifo_fast state UP group default qlen 1000
link/ether 0a:55:85:c5:f0:1a brd ff:ff:ff:ff:ff:ff
inet 172.26.30.108/24 brd 172.26.30.255 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::855:85ff:fec5:f01a/64 scope link
valid_lft forever preferred_lft forever
[ec2-user@ip-172-26-30-108 ~]$
踏み台サーバ経由でプライベートサブネットのEC2にsshアクセスできました。
ここまででできているのはこんな感じ