AWS HTTPS通信でアクセス / CloudFront

#【AWS HTTPS通信でアクセス / CloudFront】
HTTPS通信でアクセスのハンズオンメモとCloudFrontを基礎。
今後に備えて、今はあまり実務で使っていないCloudFrontを基礎から学習。

##S3をHTTPS化！自分のドメインで配信したい。
- **本番サービスでは、よりセキュアなHTTPS通信が最低限求められる。**
- 前提：
    - EC2インスタンスが立ち上がっていること。
    - RDSが起動していること。
    - ドメイン名でアクセス可能であること。
- 手順：
    - ELBロードバランサーの方でリスナーを追加。
    - マネジメントコンソールから「ロードバランサー」>「リスナー」>「リスナーの追加」
    - プロトコルに「HTTPS」　> 転送先に「作成したターゲットグループ」を選択
    - 「新しいACM証明書をリクエスト」> ドメイン名の追加で、ドメイン名を入力
    - 検証方法の選択、「DNSの検証」> 証明書のタグは必要に応じて作成 >「次へ」
        - 本人確認のような確認。
    - 検証画面、検証準備中となっている（検証作業をおこなうと準備完了に。）
    - 「Route53でのレコード作成」> CNAMEのDNSレコードを作成したRoute53のホストゾーンに追加
        - 検証完了
    - ELB リスナー追加画面「デフォルトのSSL証明書」で、作成したACM証明書を選択 > 更新
    - HTTPSのリスナーの作成が完了
- ELBのセキュリティグループで、HTTPS通信を許可する。
    - インバウンドルールで、全てのIP（0.0.0.0/0)からのHTTPS通信を許可
- **ELBがHTTPS通信を受け付けられるようになった!!**
    - ブログのURLに鍵マークがついていることで確認する。 
- HTTPS通信のみ可能に変更する。
    - HTTP通信を許可した状態だとセキュリティ上問題があるため。
    - ELBのセキュリティグループ・リスナーにて、既存のHTTP通信の許可設定を削除する。

>HTTPで受信した通信はHTTPSへリダイレクトする設定をWebサーバーに入れるケースも良くありますね。

くろかわさんにコメント頂きました。
確かにその通りだと思いました。
このQiitaの記事を投稿後、CloudFrontをCFnで作成しましたが、HTTPをHTTPSをリダイレクトする設定を記述しました。
実務ではよくあるのかなと思っています。

##AWS Edge Services
- AWSのエッジロケーションから提供されるサービス群
- AWSのサービスへのアクセスをユーザーに近い場所から提供

###Edge Location と AWS Region
- Edge Location
    - **[Amazon CloudFront](https://qiita.com/haruki_uejima/items/51d87a73504063290e87#cloudfront-aws%E3%81%AE%E3%83%95%E3%83%AB%E3%83%9E%E3%83%8D%E3%83%BC%E3%82%B8%E3%83%89%E5%9E%8Bcdn%E3%82%B5%E3%83%BC%E3%83%93%E3%82%B9)**
    - Amazon Route 53
    - AWS Global Accelerator
    - AWS WAF
    - AWS Shield
    - AWS Lambda@Edge
- AWS Region
    - Amazon EC2
    - Amazon VPC
    - Amazon RDS
    - Amazon S3（Simple Storage Service）

##Webアクセスの課題
- レスポンスの遅延、不安定なレスポンス
    - インターネット経由でのアクセスにおけるネットワーク遅延の影響
        - ネットワーク遅延は、（物理的、ネットワーク的な）距離に依存
        - コンテンツの元サーバー（オリジン）が遠いと、応答に時間がかかる。
        - 応答時間の多くが、ネットワーク転送の待ち時間を占める場合もある。
- 大量アクセスへの対応
    - 不要なトラフィックをオリジンに到達させない効率的な仕組みが必要
        - Webコンテンツには、あまり変化しない静的なデータが多く含まれる。
            - 例）画像、動画、CSS、JavaScript等のファイル
        - 同じデータを何度も取得するのは、ネットワーク帯域、サーバーリソースの無駄な消費

##CloudFront 【AWSのフルマネージド型CDNサービス】
- 大容量キャパシティを持つ地理的に分散したサーバー群(エッジ)からコンテンツをキャッシュしたり代理配信をするサービス
    - 高性能な分散配信
    - 高いパフォーマンス（高いパフォーマンスの実績）
    - キャパシティアクセスからの解放（予測不可能なスパイクアクセスへの対応）
    - ビルトインのセキュリティ機能（WAF連携、DDoS対策）
        - パフォーマンスと並んで、CloudFrontの大きな導入メリット
    - 設定が容易で即時利用可能（GUIからの設定で15分程度でサービス利用可能）
    - 充実したレポーティング（ログ、ダッシュボード、通知機能）
    - 完全従量課金（初期費用がなく安価、一時的な利用も可能）
- CloudFront導入の利点
    - **ユーザーエクスペリエンスの向上**
    - ユーザーを一番近いエッジロケーションに誘導することで配信を高速化
        - DNSを応用した仕組みで最適なエッジロケーションを割り当てる。
    - エッジサーバでコンテンツのキャッシングを行いオリジンの負荷が減る。
    - CloudFrontを開始してデータの配信元を指定すると、世界中のエッジロケーションデータがコピーされる。
    - **AWS WAFとの組み合わせや、組み込みのDDoS対策により、高いセキュリティを実現**
    - ログ・レポート機能でアクセス傾向分析も可能
    - 大容量の配信や大量アクセスがあるサイトでの活用が有用
    - 小規模でも、WAF/DDoS等のセキュリティ対策が必要なサイトで有用

>必要な荷物を取りに行く場合、自宅まで取りに行くのは距離が遠く面倒なので途中に倉庫を設置してよく使う荷物は倉庫に保管することで時間を短縮できる。
Webページでも同様でキャッシュサーバーという中間地点にWebページを保存しておくことでより高速にユーザーに配信することができます。

>CloudTechより、引用しました。

###CloudFront コンテンツ配信設定の流れ
1. S3バケット, ALB, EC2, オンプレミスにある独自のHTTPサーバーなどのオリジンサーバーを設定
1. ファイルをオリジンサーバーにアップロード
1. CloudFrontディストリビューションを作成
1. CloudFrontがドメイン名を割り当て
1. ディストリビューションの構成を全てのエッジロケーションに送信

###CloudFrontディストリビューション
- ドメイン毎に割り当てられるCloudFrontの設定
- AWS Management Console、APIで即時作成可能
- HTTP/1.0, HTTP/1.1, HTTP/2, WebSocket対応
- IPV6にも対応
- **デフォルト：xxxx.cloudfront.net**
    - ディストリビューションのドメイン名として割り当てられる。
    - CNAMEエリアスを利用して独自ドメイン名の指定が可能
        - 有効な、SSL/TLS証明書の対象であることが必要
    - CNAMEエリアスのワイルドカード指定もサポート
        - 例）*.example.com
    - **Route53と組み合わせた、Zone Apexが利用可能**
        - 例） example.com

###エッジでのgzip圧縮機能
- CloudFrontエッジでコンテンツをgzip圧縮し、高速にコンテンツを配信
    - **S3はgzip 圧縮をサポートしていないため、有効なオプション**

###キャッシュ
- キャッシュコントロール機能
    - キャッシュヒット率を向上させることがCDN導入におけるポイント
    - GET/HEAD/OPTION(選択可能)のリクエストが対象
    - 単一ファイルサイズのキャッシングは最大20GBまで。
    - URLパス毎にキャッシュ期間指定が可能
    - フォワードオプション機能による動的ページ配信
        - Header/Cookie/Query Strings
    - **URLおよび有効化したフォーワードオプション機能のパラメータ値の完全一致でキャッシュが再利用される。**
- キャッシュコントロールヘッダー
    - キャッシュ時間のコントロールが可能
    - オリジン側がHTTPキャッシュコントロールヘッダーを付与しない場合でも上書きが可能
    - **キャッシュ動作（Behavior）**毎にキャッシュ設定を行うことで、URLパス毎にキャッシュ期間を変える。
        - デフォルトTTL：24時間
- キャッシュファイルの無効化（Invalidation）
    - コンテンツ毎の無効化パス指定（同時に最大3,000個）
    - ワイルドカードを利用した無効化パス指定（同時に最大15個）
        - オブジェクト数の制限無し
    - AWS Management Console、APIで実行可能
- 動的コンテンツキャッシュへの対応
    - オリジンサーバに対して Header, Cookie, Query Strings 情報をフォワードすることで、動的なページの配信にも対応
    - URLパス（Behavior）と組み合わせ、きめ細かなキャッシュコントロールを実現
    - Whitelistを利用して、必要最低限のパラメータのみをフォワード設定することで、キャッシュを有効活用する。
    - キャッシュしないコンテンツでも、オリジンとの通信の最適化により配信の高速化を実現
    - 必要最小限のヘッダーを指定することが推奨されている。
    - Cookieを**オリジン**へ転送
    - クエリ文字列パラメータの値を**オリジン**へ転送
        - パラメータの順序を常に統一する。
        - パラメータ名とパラメータ値の大文字と小文字を常に統一する。
        - これらを統一しないと、それぞれにキャッシュされてしまう。

>TTLの設計：
どのデータをキャッシュするか。それを何秒間キャッシュするかが重要です。
一般的にSNSサイトのプロフィールなどのようなデータなど一定の間隔で頻繁にアクセスされデータが多少古くても問題とならないデータなどは向いているデータとなります。
変化の激しいデータ。株価のデータ、アクセスが殆どないデータなどは向いていないデータになります。

>CloudTechより、引用しました。

###カスタムエラーページの生成
- S3と組み合わせた構成例
    - 4XX系はCloudFront側ですべてをハンドリングしていないかつ、クライアント要求のエラーのため、オリジン側で対処
        - Webサーバ側で4XXエラー時のページ設定
    - 5XX系はオリジン側のエラーのため、CloudFront側で対処
        - 5XXのカスタムエラーページをS3に設定(4XXはオプション)

※ エラーキャッシュ期間(Error Caching Minimum TTL) はデフォルト5分

###オリジン
- オリジンの読み取りタイムアウト
    - CloudFrontがカスタムオリジンからの応答を待つ時間を指定
    - デフォルトのタイムアウトは 30秒（4~60秒の範囲）
- キープアライブタイムアウト
    - 接続を閉じる前にCloudFrontがカスタムオリジンサーバーとの持続的接続を維持する最大時間を指定
    - デフォルトは、5秒（1~60秒の範囲）
- CloudFrontオリジンフェイルオーバーによる高可用性
    - オリジングループを作成し、プライマリオリジン·セカンダリオリジンを指定
    - エラーHTTPステータスコードを返した場合や接続タイムアウトした場合にバックアップオリジンにルーティング
    - カスタムエラーページでもオリジンフェイルオーバー可能

###地域制限
- 地域指定によるアクセス制御
    - 接続されるクライアントの地域情報を元にエッジでアクセス判定
    - Blacklist、Whitelistで指定可能
    - ディストリビューション全体に対して適用される

###署名付きURL/Cookieを利用したプライベートコンテンツ配信
- Restricted Viewer Access を有効にするだけで、署名のないアクセスを全てブロック
    - 単一コンテンツアクセスの場合は、署名付きURLの利用が推奨
    - 複数コンテンツアクセスの場合は、署名付きCookieの利用が推奨

###オリジンサーバの保護
- オリジンがS3の場合
    - Origin Access Identity（OAI）を使用。
    - **S3バケットへのアクセスをCloudFrontからのみに制限**
- カスタムオリジンの場合、下記の2種類が選択可能
    - オリジンカスタムヘッダーを利用し、CloudFrontで指定された任意のヘッダーをオリジンでチェック
    - オリジン側のアドレスを公開しないとともに、CloudFrontが利用するIPアドレスのみを許可させる。

###AWS WAF連携
- AWS WAFで定義したWeb ACLをCloudFrontディストリビューションに適用
    - **CloudFrontをサービスの前段に配置することでサイトの保護を実現** 
        - XSS/IPアドレス制限/SQLインジェクション/正規表現マッチング ...etc
    - AWS WAFの内容が即時反映

###AWS Shieldによる、DDoS攻撃対策
- Amazonのノウハウを詰め込んだDDoS攻撃を緩和するサービス
    - デフォルトで有効
    - 無料で利用できるものもある。
        - AWS Shieldには無料版と、追加料金が必要なAdvancedがある。
    - 他ユーザートラフィックは、インラインシステムが可用性、スループット、レイテンシに影響を与えずに迅速に対応

##今後
- CloudFrontをCFnテンプレートで作成予定
    - そのコードを記載できたらなと。
- CloudFormationスキルのアップに注力する。

##参考
- [CloudTech](https://aws-cloud-tech.com)
- [【AWS Black Belt Online Seminar】 Amazon CloudFrontの概要](https://www.youtube.com/watch?v=mmRKzzOvJJY&list=LL&index=2)

##おわりに。
この記事はAWS初学者を導く体系的な動画学習サービス
「AWS CloudTech」の課題カリキュラムで作成しました。
https://aws-cloud-tech.com
![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f3436353930362f30303633376536332d353333392d316238332d633363312d3732306539353137346563302e706e67.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/472549/ecaf8e94-37a6-cf4c-fb6d-1c106e0034c1.png)