【AWS】AWS無料SSL+ELB+ec2+nginx+SES+php でhttpsサイトを構築する

aws_logo_smile_1200x630

AWS無料SSL+ELB+ec2+nginx+SES+phpでサイトを構築する前に

AWSの仕様がどんどんと変わるのでサイトのSSL化するのも一苦労ですね。
自分がやってみてつまづいた部分を重点的に残しています。

ポイントはELB(ロードバランサー)です。
AWSでSSL証明書を発行してELBで利用します。

しかし、ELBは月々2000円ほどお金がかかります。

AWSの無料SSLでサイト構築するターゲット層

  • nginx+phpでサイトを構築している
  • すでにELBやSESを利用している
  • SSL証明書の更新がめんどうだ
  • SSL証明書にお金をかけたくない
  • SSL証明書で個人情報をさらしたくない

ELBを利用していないと余計なお金がかかるため上記以外の人はおすすめしません。

SSLにするときって個人情報入力しなきゃダメ?

今回の方法は個人情報をもらさずにSSL化する方法です。
本来であればSSL証明書を発行するときに個人情報を入れる
手順があると思いますがその必要はありません。

httpsサイトを構築するために必要なもの

  • 取得したドメイン
  • ROUTE53(AWS) ドメイン設定
  • EC2(AWS) Webサーバー
  • ELB(AWS) ロードバランサー
  • SES(AWS) Eメール設定
  • S3(AWS) クラウドストレージ(きたメール保存用)
  • nginx+php

SESを使わずにドメインメールを利用してやる方法もありますが割愛します。(余裕があったら書くかも)
前提条件としEC2+nginx+phpでサイトを表示できる方対象です。

1. Route53でドメイン設定する

まずはRoute53でドメイン設定を行います。
わたしはムームードメイン取得したドメインをRoute53に設定しました。

1.  [Create Hosted Zone] 2. [Domain Name]に取得したドメインを入力して[create] 3. [Create Record Set]でTypeを[A-IPv4 address]でAliasを[No]でec2のIP or Elastic IPを設定します。
(ec2のIPは再起動や停止をすると書き換わってしまうので[Elastic IP]でIPを固定にしていくとよいです)
4. NSにかかれているネームサーバー・ドメイン名をムームードメインに設定するためメモします(NSのValueの部分です)
5. ムームードメインの[ドメイン管理]からネームサーバーの設定変更から取得したドメインの[ネームサーバ設定変更]を選択
6. 4.でメモしたものをムームドメインのネームサーバーに設定します
ネームサーバー設定

これでしばらくすればドメインの設定完了です。

2.SESでSSL証明書の確認メールを受信できる準備を整えるためSESの設定をする

SSL証明書の確認メールを受けとる準備をします。
SSL証明書の手続きを行うと下記へメールが送られてきます。

たとえばhoge.comというドメインならば下記宛先に
SSL証明書の確認メール(アクティベートメール)が届きます。

  • admin@hoge.com
  • administrator@hoge.com
  • hostmaster@hoge.com
  • postmaster@hoge.com
  • webmaster@hoge.com

5つの届いたメールのリンクをすべてクリックして
自分が本人であることを証明します。(アクティベート)

ひとつでも漏れがあるとSSL証明書は発行されませんのご注意ください。
取得したドメインサイトでもできるのですがメール作成の上限があるためSESを使っています。

メールを受けとるS3の設定

1. s3の管理画面から[バケットを作成する]で適当な名前をつけます。
(たとえばhoge.comというドメインならばmail.hoge.comなど)
2. リージョンはSESと合わせるためにオレゴンにして[作成]します。
これでメールを受信する受け皿の完成です。

SES設定方法

1. SESは日本のリージョンはないため日本に近いオレゴンを選択します
2. [Domains]で[Verify New Domain]でドメイン名を入力して[Verify This Domain]で登録します
3. [Email Receiving]→[Rule Sets]→[Create Rule]を選択
([Create Rule]が見つからないときは[View Active Rule Set]から[Create Rule])
4. [Recipients]のページで下記ドメインを登録して[Next Step](Add Recipientが追加で追加していきます)

  • admin@hoge.com
  • administrator@hoge.com
  • hostmaster@hoge.com
  • postmaster@hoge.com
  • webmaster@hoge.com

5. [Add action]で[S3]を選択(送られてきたメールをS3に格納します)し先程作成した[S3 bucket]を指定します
6. [Rule Details]の[Rule name]を適当に決めます (hoge-comなど)
7. [Review]で[Create Rule]で完成です。

これでadmin@hoge.com等に送られたメールはS3のバケットに送られます。

無料SSL証明書を取得する

1. AWS管理画面TOPの[セキュリティ、アイデンティティ、コンプライアンス]から[Certificate Manager]を選択
2. 証明書のリクエストを選択してドメイン名を入力し次へ
3. Eメールの検証を選択して青色ボタンをクリック(なぜかボタンが壊れています。。)
4. [確定とリクエスト]を押すとS3にメールが到着します。

SSL証明書のアクティベーションする

1. しばらくするとさきほど設定したS3のバケットにメールが届きます。
暗号化?っぽくなっているのでわかりにくいですが届いたファイルをとりあえず開けます。

2. ファイルを選択して[開ける]で開きます。
なぜか自分の場合はブラウザのポップアップブロックが発動したので解除しました。
      ブラウザで開くことができなく勝手にダウンロードされたので中身を開きます。

3. こんな感じのアクティベーションリンクがあるので開いて[Approval]してアクティベーションを実行します。
     ttps://ap-northeast-1.certificates.amazon.com/approvals?code=xxxx&context=xxxx

4. 到着したメールをすべてアクティベーションし先程のSSL証明書管理画面を確認すると[状況]が[発行済み]となります。

これでSSL証明書を取得OKです。

ELBにSSLの設定をする

ELBとSSLを利用したときのポートリクエストの流れ

①ユーザーリクエスト(80 or 443) → ②ELB(80) → ③ec2

この流れを理解していないとハマります。

ポイントはec2が受けとるリクエストは常に80ポートだよってことです。
ELBの設定がうまくいかないと502,503エラーが出ます。ELBの設定を見直す必要があります。

ELBにSSLを設定する

1. ec2の管理画面から[ロードバランサー]→[ロードバランサーの作成][HTTP HTTPS]の作成を選択
2. 名前は適応でOK [リスナーの追加]→[プロトコルの選択]を[HTTPS(セキュアHTTPS)]で[次の手順・・・]へ
      ここではユーザーからきたリクエストの設定をしているわけです。①ユーザーリクエスト(80 or 443) の部分です。

3. [アベイラビリティーゾーン]はとりあえず全チェックしておいて[次の手順・・・]へ
4. [ACMから証明書を選択する(推奨)]にチェック 証明書の名前はさっきSSL証明書を発行した名前 セキュリティポリシーはそのまま
5. [セキュリティグループの設定]で[新しいセキュリティグループを作成する]

6. [ルーティングの設定]の
      [ターゲットグループ][名前]適当[プロトコル] HTTP [ポート]80 [ターゲットの種類] instance
      [ヘルスチェック][プロトコル] HTTP [パス] スラッシュ(/)
7. [ターゲットの登録]でec2のインスタンスをチェックしポート80で[登録済に追加]します。
      ②ELB(80)の部分です。[登録済に追加]をしないと503エラーになるのでご注意を。
8. [次の手順・・・]で設定します
これでELBの設定は完了です。

ふたたびRoute53の設定変更

1. Route53管理画面の[Hosted zones]からドメインを選択
2. [Type]のAレコードを選択し[Alias]を[Yes]にしてAlias TargetをELBにDNS名を設定します。
      
これですべてのAWSの設定は完了です。
ec2で元からサイトを表示させている場合はhttpをhttpsに変更すればhttpsを見れます。

nginxの設定

httpをhttpsにそのままリダイレクトするとリダイレクトループが発生します。
理由はELBとSSLを利用したときのポートリクエストの流れの③でhttpでもhttpsでもポート80なので見分けがつかないためループします。

リダイレクトループを回避するためにはhttps or httpを判断するhttp_x_forwarded_protoを利用します。
ELBでec2が生きているどうか監視しています。(ヘルスチェック) ヘルスチェックにパスするために「return 200 OK;」にしています。


server {
listen 80 default_server;
listen [::]:80 default_server;

location / {
access_log off;
return 200 OK;
}
}

server {
listen 80;
listen [::]:80;
server_name hoge.com;

if ($http_x_forwarded_proto != https) {
return 301 https://$host$request_uri;
}

location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;

root /var/www/html/hoge.com;
try_files $uri $uri/ /index.php?/$request_uri;
}

if ($request_uri !~ ^/(index\.php|common|assets|files|robots\.txt)) {
rewrite ^/(.*)$ /index.php/$1 last;
}

location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;

fastcgi_index index.php;
fastcgi_param ENVIRONMENT production;
fastcgi_param SCRIPT_FILENAME /var/www/html/hoge.com$fastcgi_script_name;
include fastcgi_params;
}
}