【AWS】ロードバランサー+ApacheでHTTPSリダイレクトをしてみる

AWSのEC2インスタンス上に立てたApacheサーバーを、HTTPSリダイレクトできるように設定してみます。

> 環境：
> Apache2.4

# 前提：サーバー証明書

今回はHTTPSリダイレクトを実現するので、もちろんサーバー証明書が必要となります。AWSではCertification Manager（通称ACM）という無料でサーバー証明書が発行できるサービスがあるので、それを利用します。

ですがこのサーバー証明書、EC2インスタンス上に置くことはできず、CloudFrontもしくはLoadBalancerに置いてEC2インスタンスに接続するという形を取らなければなりません。

今回はこの二つのうち、より一般的そうなLoadBalancerを用いた場合の設定方法を書いていきます。

このサーバー証明書の発行に関して、またCloudFrontでの利用についてはここでは割愛します。（また今度書きます）

# 本題：環境構築

## EC2インスタンスの作成

今回はAmazon Linuxで作成します。セキュリティグループのインバウンド設定は以下のようにします。

| タイプ       |       ポート範囲 |    ソース    |
|:-----------------|------------------:|:------------------:|
| HTTP             |              80 |        0.0.0.0/0        |
| SSH             |              22 |        [マイIP]        |

ロードバランサーはHTTPSのリクエストも内部的にはHTTPとして扱っているので、EC2の設定としては80番ポートのみ開けておけばリクエストは通ります。SSHを開けてあとでApacheのセットアップをします。

これで起動します。

## ロードバランサーの作成

[Application Load Balancer](http://dev.classmethod.jp/cloud/aws/alb-application-load-balancer)を用います。

### ロードバランサーの設定

リスナーにHTTPS(443)を追加します。

![Screen Shot 2017-09-20 at 16.32.20.png](https://qiita-image-store.s3.amazonaws.com/0/203213/f7a56075-c2a3-a638-2ee1-10df07e4038d.png)

### セキュリティ設定の構成

「ACMから証明書を選択する（推奨）」を選択し、証明書を選択します。

### セキュリティグループの設定

今回は

 - HTTPのリクエストをHTTPSにリダイレクト
 - HTTPSのリクエストはそのまま通す

という設計なので、HTTP/HTTPS共に受け付けるように下のように設定します。

| タイプ       |       ポート範囲 |    ソース    |
|:-----------------|------------------:|:------------------:|
| HTTP             |              80 |        0.0.0.0/0        |
| HTTPS             |              443 |        0.0.0.0/0        |

### ルーティングの設定

ヘルスチェックの詳細設定において、成功コードをリダイレクトの301にしないといけないそうです。

![Screen Shot 2017-09-20 at 16.41.55.png](https://qiita-image-store.s3.amazonaws.com/0/203213/627d7aec-9cd3-a99f-2b23-3ab2bdf3b0b1.png)

### ターゲットの登録

先ほど作成したEC2インスタンスを**ポート80で**ターゲットグループに追加します。

以上で作成完了です。

## Apacheの設定

それでは実際にリダイレクトの設定をApacheの方で行なってみます。

### Apacheのインストール

バージョンは2.4です。

```bash
$ sudo yum install -y httpd24
$ sudo apache start
```

デフォルトでドキュメントルートは/var/www/htmlなのでそこをドキュメントルートとしてやっていきます。

### .htaccessの設定

リライトの設定はこのファイルに書いていきます。以下のように書いて、ドキュメントルート（ここでは/var/www/html）におきます。

```
RewriteEngine On

RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule ^(.*)?$ https://%{HTTP:Host}%{REQUEST_URI} [L,R=301]
```

.htaccessにおけるリダイレクトでは基本的に

```
RewriteCond
RewriteRule
...
```

という繰り返しで書くことが多く、ある条件（RewriteCond）に合致するものに対し、あるルール（RewriteRule）に基づき、アドレスのリライトを行うと考えればわかりやすいかと思います。

ここで注意していただきたいのが、**HTTP環境変数**です。「.htaccess　書き方」などのキーワードでググった結果をそのままコピペしても、この場合うまくいかない可能性が高いです。なぜなら**Apacheサーバーとクライアントの間にロードバランサーがいるから**です。

クライアントからどのようなHTTPリクエストが来たかを判別するため、AWSではX-Forwardedというプレフィックスのついたリクエストヘッダーを用いることができます。

そのため、httpsか否かの判定には%{HTTPS}や%{SERVER_PORT}ではなく**%{HTTP:X-Forwarded-Proto}**、ホスト名の判定には%{HTTP_HOST}や%{SERVER_NAME}ではなく**%{HTTP:Host}**を用います。

%{HTTPS}や%{SERVER_PORT}ではEC2インスタンスが通信に用いているHTTPが表示され、%{HTTP_HOST}や%{SERVER_NAME}ではEC2インスタンスのIPアドレスが表示されると思います。

### httpd.confの設定

先ほど.htaccessを書いてドキュメントルートに置きましたが、このままではその設定は有効になりません。

 - httpd.confで.htaccessの有効化
 - httpdの再起動

をして初めて有効になります。

httpd.conf（初期設定では/etc/httpd/conf/にある）の次のAllowOverrideをNoneからAllに変えてやります。「htaccess」とかでファイル検索をかければすぐ見つかると思います。

```
    #
    # AllowOverride controls what directives may be placed in .htaccess files.
    # It can be "All", "None", or any combination of the keywords:
    #   Options FileInfo AuthConfig Limit
    #
    AllowOverride None
```

これで変更を保存し、apacheを再起動してください。

```bash
$ sudo apache restart
```

### httpd.confの設定（追加）

mod_rewriteのログがみたかったのでついでにその設定もしてみました。検索するとRewriteLogLevelを.htaccessに書いている記事が多くあったのですが、上手くいかなかったので詳しく調べるとApache2.4系ではログは全部まとめてerror_logに吐かれるようでした。加えて、.htaccessへの記述はサポートされていないとのことだったので以下のようにhttpd.confに追記します。

```
LogLevel info rewrite:trace8
```

以上で完了です。これでロードバランサーを介してHTTPSリダイレクトが実現できました。

# 参考
https://www.crosshead.co.jp/blog/apache-alb-http-to-https
https://murashun.jp/blog/20141229-01.html
http://docs.aws.amazon.com/ja_jp/elasticloadbalancing/latest/classic/x-forwarded-headers.html
https://blog.cles.jp/item/8180
https://stackoverflow.com/questions/23054592/htaccess-loglevel-not-allowed-here