AWS EC2でHTTPS通信を行えるようになるまでのセッティング手順
November 15, 2020
自分の覚え書き用のメモです。手順だけでなく用語の理解など気になった点も含めて記録しています。
なお、本記事は下記の前提で記載しています。といってもたいした前提ではないので、自分の環境に応じて適宜読み替えていただければ大丈夫です。
- AWS のアカウントを取得済み
- お名前.com でドメインを取得済み
- EC2 には Node.js のアプリをデプロイする
- ローカルの環境は MacOS
1. EC2 のインスタンスを作成する #
EC2(Amazon Elastic Compute Cloud)のサービスのページから、インスタンスを起動を選択。
1-1. マシンイメージを選択 #
今回は、Amazon Linux 2 AMI (HVM)を選択(CPU は 64 ビット (x86)を選択)。
メモ:EC2 の仕組みについて #
Xen を用いて仮想化している。ヴァーチャルマシンと呼ばれるサーバインスタンスを作成して希望するソフトウェアを実行する。サーバインスタンスは必要に応じ作成、実行および停止が可能で、起動サーバの使用時間に応じ対価を支払うため"elastic"と呼ばれる。
メモ:Amazon Linux 2 について #
Amazon 独自の Linux ディストリビューション。正式な情報は非公開だが、RHEL7/CentOS7 をベースとしていると言われているので、CentOS と操作感覚はほぼ同じ。システム管理デーモンは Systemd で、パッケージマネージャは yum。
1-2. インスタンスタイプの選択 #
今回は「t2.micro」を選択
1-3. インスタンスの詳細の設定 #
デフォルトのまま次のステップへ
1-4. ストレージの追加 #
デフォルトのまま次のステップへ
1-5. タグの追加 #
管理しやすいように適当な名前を設定しておく。キーを「Name」とし、バリュー(値)に適当な名前を入力して次へ。
1-6. セキュリティグループの設定 #
以前に EC2 を利用したことがあり、同一のセキュリティグループを適用するのであれば、「既存のセキュリティグループを選択する」から選べば OK だが、今回は「新しいセキュリティグループを作成する」を選択する。
SSH が設定されていることを確認する。HTTP や HTTPS は後で別途設定変更するので、今はデフォルトのまま次に進む。
1-7. インスタンス作成の確認 #
内容を確認後、起動を押下すると、既存のキーペアを選択するか、新しいキーペアを作成するか聞かれる。以前に EC2 を利用したことがあり、キーペアを作成済みであればそれを使用する。今回は新しいキーペを作成するを選択。
キーペアをダウンロード後、インスタンスの作成が始まる。
2. EC2 に SSH 接続する #
ダウンロードしたキーペアを使用して SSH 接続する。キーペアの名前で aws を入力し、aws.pem がダウンロードされているとして、それを「/.ssh/」の配下に格納しておく(保存場所は自由。自分が管理しやすい好みの場所で)。格納後のキーペアの場所は次の通り。「/.ssh/aws.pem」
作成したインスタンスの概要ページにて、パブリック IPv4 アドレスを確認する。
ローカルでターミナルを開き、次のコマンドを入力。
ssh -i ~/.ssh/aws.pem [email protected](各自のIPアドレス)
そうすると、以下のメッセージが出て怒られた後、接続が拒否されるはず。
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: UNPROTECTED PRIVATE KEY FILE! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Permissions 0644 for '/Users/xxxxxxxx/.ssh/aws.pem' are too open.
It is required that your private key files are NOT accessible by others.
This private key will be ignored.
pem の権限をもっと絞れというメッセージなので、適当に権限を絞る。ターミナルで以下を実行。
chmod 400 ~/.ssh/aws.pem
その後再び SSH 接続を行ってみる。なお、ec2-user というユーザがデフォルトで作成されており、そのユーザを使用してログインしている。
ssh -i ~/.ssh/aws.pem [email protected](各自のIPアドレス)
下記のウェルカムメッセージが表示されれば無事に接続できたということ。
__| __|_ )
_| ( / Amazon Linux 2 AMI
___|\___|___|
Run “sudo yum update” to apply all updates.と表示されるはずなので、指示に従う。
sudo yum update
上記実行後、アップデート内容を確認後、よければ「y」を入力。
3. EC2 に Node.js をインストールする #
基本的に AWS 公式のチュートリアルに準拠して作業すれば大丈夫。
チュートリアル: Amazon EC2 インスタンスでの Node.js のセットアップ - AWS SDK for JavaScript
今回は root ユーザにスイッチして進める。
sudo su -
なお、最後のハイフンをつけると、root ユーザにスイッチしつつ自動で root ユーザのホームディレクトリに移動してくれる。ハイフンを入れないと、カレントディレクトリのまま root ユーザにスイッチする。それだけのことなので、ハイフンを付けても付けなくてもスイッチ自体の動きに違いはない。
- メモ:ちなみに初期状態だと root ユーザはパスワードが設定されていないので、必要であれば設定を。
スイッチ後、以下を実行。
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.34.0/install.sh | bash
. ~/.nvm/nvm.sh
nvm install node
node -e "console.log('Running Node.js ' + process.version)"
最後のコマンド実行時に、「Running Node.js v15.2.0」などと返ってくれば OK.
これで Node.js のインストールは終わり。exit を入力して一旦 EC2 から抜ける。
4. Elastic IP アドレスを適用する #
EC2 はダイナミック IP のため、インスタンスの再起動などにより IP アドレスが変動する。IP アドレスを固定しておくために Elastic IP アドレス(EIP)というサービスを利用する。
Elastic IP アドレス - Amazon Elastic Compute Cloud
EC2 のページのネットワーク&セキュリティから Elastic IP を選択。
「Elastic IP アドレスの割り当て」を押下。「Amazon の IPv4 アドレスプール」を選択して割り当てを実行。
割り当てられた Elastic IP のページから、「Elastic IP アドレスの関連付け」を押下。インスタンスから、先ほど作成したインスタンスを選択し、「関連付ける」を実行。
- メモ:インスタンスに関連付けられている限り Elastic IP の利用は無料だが、関連付けしないままの場合は使用料が発生するので注意。
Elastic IP アドレスを効率的に使用するため、Elastic IP アドレスが実行中のインスタンスに関連付けられていない場合や、停止しているインスタンスやアタッチされていないネットワークインターフェイスに関連付けられている場合は、時間毎に小額の料金が請求されます。
5. アプリをデプロイする #
ターミナルから EC2 にログインし、アプリをデプロイする。私の場合はデプロイするアプリのディレクトリを zip で固めて、scp や sftp でアップロードした後、EC2 上で unzip(解凍)。
6. EC2 のポート開放する(セキュリティグループの編集) #
EC2 の作成したインスタンスのページのセキュリティタブにて、そのインスタンスが所属しているセキュリティグループを確認する。
EC2 のページのネットワーク&セキュリティからセキュリティグループを選択。インスタンスが所属しているセキュリティグループを押下し、インバウンドルールを編集に進む。
インバウンドルールを下記のように編集する。
TYPE | PROTOCOL | PORT | SOURCE |
----- | -------- |----- | --------- |
SSH | TCP | 22 | 0.0.0.0/0 |
HTTP | TCP | 80 | 0.0.0.0/0 |
HTTP | TCP | 80 | ::/0 |
HTTPS | TCP | 443 | 0.0.0.0/0 |
HTTPS | TCP | 443 | ::/0 |
初期設定は SSH のみが記載されていたはずなので、そこに HTTP と HTTPS を追加する形。
これにより HTTP および HTTPS 接続ができるようになる。
7. ブラウザからアプリに接続できるか確認する #
http://xx.xxx.xxx.xxx
(割り当てられた Elastic IP)」を入力して、アプリのページが表示されることを確認する。
以降では、HTTPS を適用する作業を行う。
8. Route 53 をネームサーバとして利用する #
Amazon Route 53 は AWS の DNS のサービス。53 は、DNS サーバーが 53 番ポートで動作することに由来。
以下の Qiita の記事を参考に進めれば大丈夫。先にドメインを取得済みであれば、「AWS の設定」の部分からで。
「【ドメイン取得】お名前.com と aws でドメイン取得 - https://qiita.com/nakanishi03/items/25278fb4dfad60ebfac4」
9. Certificate Manager で証明書を発行する #
AWS Certificate Manager は証明書の発行サービス。
以下の Qiita の記事を参考に進める。「Certificate Manager」の項目を実施する。
AWS で SSL 化する方法を伝授!!!」 - https://qiita.com/nakanishi03/items/3a514026acc7abe25977
なお、DNS の検証の部分については、今回のように DNS に Route 53 を利用しているのであれば、自動で検証用の設定を加えてくれる「Route 53 でのレコードの作成」というオプションがある。もちろん上記の記事のように手動で設定しても構わないが、作業ミスを減らすためにもこのオプションを利用した方が良いかと。「Route 53 でのレコードの作成」については以下の Qiita 記事で触れられている。
10. Elastic Load Balancing の設定をする #
Elastic Load Balancing(ELB)は AWS のロードバランサーのサービス。
先ほども参照した以下の Qiita 記事をもとに作業を進める。「ロードバランサー」および「エイリアスの設定」の項目を実施する。
「AWS で SSL 化する方法を伝授!!!」 - https://qiita.com/nakanishi03/items/3a514026acc7abe25977
- メモ:ELB と EC2 間の通信について
クライアントがアプリに接続しようとした時、最初に接続されるのは ELB。その後 ELB が EC2 にアクセスを振り分けている。ELB に SSL を置き、https アクセスは ELB で引き受けて、その後ろの EC2 には http で転送される形となっているため、ELB と EC2 の間の通信は http になっており、SSL 化されてはいない(…が、そこは AWS のネットワーク内での通信なので大丈夫)。注意点としては、アプリ側で http を https にリダイレクトさせる処理を書いている場合、https アクセスでもアプリ側は http で来たと思って https リダイレクトしようとするので、リダイレクトループが発生することになるので気をつけること。
11. HTTPS 接続できることの確認 #
http://example.com
(取得したドメイン)で、HTTPS でアプリのページが表示されることを確認する。
以上で終了。
99. 補足 #
ここまで手順通りに進めていれば問題なくできるはずなのだが、私の場合は ELB と EC2 の間のヘルスチェックに失敗しており、開通ができていない状況が発生していた(かつ、これに気づくのにかなり時間がかかってしまった)。
ヘルスチェックの結果は以下で確認できる。
EC2 のページのロードバランシングからターゲットグループを選択。対象のターゲットのページの、ターゲットタブを開くと、ステータスが表示される。これが「healthy」になっていれば、ヘルスチェックは成功している。
ヘルスチェックはデフォルトだと、EIP のルート("/")に対して行われるが、私の場合は Node.js で API を作成していたため、ルートに関する処理は用意しておらず、ルートに対するアクセスに対して 200 のレスポンスを返す状態にはなっていなかった。そのためにヘルスチェックに失敗し、開通できない状態ととなっていた。
ヘルスチェックの対象パスは自分で設定できるため、ルートではないパスを利用してヘルスチェックしたい場合は忘れずに。
以上 #
以上で手順は完了です。今回、ドメインの取得にはお名前.com を利用しましたが、Route 53 でドメインを取得することもできます。そうすると、全ての作業が AWS 内で完結しますね。AWS、すべてを網羅していてホントすごいです。