ALB×ApacheでHSTS対応

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/417736/ea7cfeef-4508-f863-cd86-6a5d22baa08f.png" alt="js" width="80">

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/417736/dfd34892-beca-9a56-aaea-f262644e9816.png" alt="js" width="80">

## HTTP Strict Transport Security `HSTS`とは

>  HSTS とは HTTP から HTTPS へのリダイレクト途中の通信を改ざんされたり中間者攻撃を防ぐための設定です。 HTTP の通信は改ざんチェックは行われないため HTTPS のリダイレクト途中の通信でサイトに対して攻撃されてしまうと検知するすべがありません。
> HSTS を導入するとサーバ側で HTTPS にリダイレクトされるのではなくブラウザ内部で HTTPS へのリダイレクトが行われます。通信の始点であるブラウザから HTTPS 通信することによって通信の途中で HTTP 通信することがありません。
[AWS ALB 配下で HSTS の設定を行う方法](https://qiita.com/syoimin/items/db85769349d2cb9bda24)

- http:80プロトコルでアクセスしようとすると、ブラウザUAがhttpsにインターナルリダイレクトする仕組み。
- サーバーサイドのhttpsリダイレクトではフィッシング詐欺や(httpな)ブックマークによる直アクセスにおいて、リダイレクト前のhttp:80アクセスが脅威にさらされる。
- レスポンスヘッダに`HSTS`ヘッダを付記して、ブラウザUAにキャッシュさせることで実現させている。
- HSTSヘッダはhttpsプロトコル下でないとブラウザUAがキャッシュしてくれない。
- したがってあいかわらず初回のhttpアクセスでは電文は露見する。
- ただし後述のpreload仕様では初回のhttp:80アクセスさえhttpsインターナルリダイレクトを強制することができる。

## ALBのバックエンドで80ポートをフォワードしている場合の対策

- ALB単体はルールセットでhttpsリダイレクトを組めるがカスタムヘッダーを付記することができないため、バックエンドが付記してやる必要がある
- `ALB<--->バックエンド`がhttp:80プロトコルであっても、UAにとっての終端であるALBとの通信がhttps:ならが`HSTS`ヘッダをキャッシュてくれる
- バックエンドはとにかく常時HSTSヘッダを付記してやる

```apache:apacheconf
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
```

### バックエンドがhttpsリダイレクトまでやる場合

- バックエンドでHSTSヘッダを常時付記しつつ、httpsリダイレクトする
- ALBが`UA<--->ALB`のプロトコルをフォワードヘッダに付記してくれるのでhttp:80プロトコルの場合のみリダイレクトする=`RewriteCond %{HTTP:X-Forwarded-Proto} =http`

```apache:apacheconf

# HSTSヘッダを常時付記
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"

# Rewrite
RewriteEngine On
# ブラウザUA<--->ALBがhttp:80プロトコルの場合httpsにリダイレクト
RewriteCond %{HTTP:X-Forwarded-Proto} =http
RewriteRule .* https://%{HTTP:Host}%{REQUEST_URI} [L,R=permanent]
```

## 動作確認

- httpsアクセスすると、レスポンスヘッダに==strict-transport-security==がある
- httpアクセスすると、307インターナルリダイレクトしてhttps通信した

**対応済のサイト**

```sh:sh
curl -v -sS -o /dev/null -L -k https://www.rakuten-sec.co.jp
< HTTP/2 200 
< server: Apache
< strict-transport-security: max-age=31536000;
< content-type: text/html
< date: Thu, 03 Aug 2023 05:41:44 GMT
< server-timing: ak_p; desc="1691041304439_1611081229_148344902_765_433_13_0_15";dur=1 
```

**対応前**

```sh:sh
curl -v -sS -o /dev/null -L -k https://my.host.jp

< HTTP/2 200 
< date: Thu, 03 Aug 2023 05:55:41 GMT
< content-type: text/html; charset=UTF-8
< server: Apache
< expires: Thu, 19 Nov 1981 08:52:00 GMT
< last-modified: Thu, 03 Aug 2023 05:55:41 GMT
< cache-control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
< pragma: no-cache
< set-cookie: PHPSESSID=n4b6a8cfjjn5u6tnn0qrob1d07; path=/; SameSite=None; secure; HttpOnly
< vary: Accept-Encoding
```

```sh:sh
curl -v -sS -o /dev/null -L -k https://my.host.jp

< HTTP/2 200 
< date: Thu, 03 Aug 2023 05:57:02 GMT
< content-type: text/html; charset=UTF-8
< server: Apache

# 追加された
< strict-transport-security: max-age=31536000; includeSubDomains; preload

< expires: Thu, 19 Nov 1981 08:52:00 GMT
< last-modified: Thu, 03 Aug 2023 05:57:02 GMT
< cache-control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
< pragma: no-cache
< set-cookie: PHPSESSID=kn8p8th7l9h79g8msd4nhrf1e6; path=/; SameSite=None; secure; HttpOnly
< vary: Accept-Encoding
```

307 Internal Redirectが発生していればOK

## HSTSプリロード

> * ユーザがWebサイトにHTTPで初回アクセスした場合でもHSTSが有効になり、初回から必ずHTTPSでアクセスを行うための仕組みのことです。事前に自身の所持するWebサイトのドメインをHSTS preloadリストに登録する必要があります。
> - HSTS preloadリストとは主要ブラウザ（Chrome、Firefox、Safari、IE11、Edge、Opera）が参照するHSTS対応サイトリストのことです。HSTS preloadリストに登録されているWebサイトは、ブラウザが予めSSL/TLSを使用することが分かるようになるため、初回からHSTS機能が有効になります。
[AWSのCLB（Classic Load Balancer）配下にHSTSとPreload設定を行う方法 | N-LAB](https://n-laboratory.jp/articles/aws-clb-hsts)

[HSTS Preload List Submission](https://hstspreload.org/)にhstsサイトとして登録してもらうことで、初回のhttp通信をブラウザで抑止できるようになる。

- HSTS対応完了していること
- 検査対象のDNSとしてサブドメインは不可。ネイキッドドメインであること。