CloudFrontはS3に設置したJS, CSS, 画像といった静的コンテンツに適したCDNの利用が王道だけれど、WordPressのような参照の多いサイトでのページキャッシュに利用することも効果的です!
もくじ
環境
- AWS
- Amazon Linux2
この構成の意図
- Nginxでのリバースプロキスにページキャッシュの場合は単一障害点になりますが、リバースプロキシの役割をCloudFrontに持たせることによってスケールすることが出来ます。
キャッシュのTTLは任意で設定して下さい、また任意のタイミングで【invalidation】機能によりパス単位でのキャッシュ削除が可能です。
CloudFrontページキャッシュ構成の良いところ
- CDNとして詳細設定が可能
Cookieのキーを指定することで、ログイン中はキャッシュしないといったことが手軽に設定出来る - ALBと組み合わせてスケール、メンテナンス性の向上
更にALBを間に挟むことで、EC2のメンテナンス性向上し将来的なスケールが容易になります。 - Cloudfront転送料金 13円/1GB
EC2から配信する場合と転送料金はほとんど大差ない、
CloudFrontを挟めるなら挟もう
一時的なキャンペーンであれば
事前にCloudFrontのキャッシュ保持を行うTTLを長くして、CloudFrontにページキャッシュを十分にストックしておけばOK!
万が一CloudFrontのバックエンドに流れることが不安なら、ALB配下にEC2サーバを任意の数で待機しCPU監視によるオートスケール設定をかけておけばよいでしょう。
注意
- ネイキッドドメイン(example.net等)でWEBを運用している場合は利用できない
CloudFlare等ネイキッドドメインでも運用できるCDNがあるがRFC違反なので、メールなどで異常動作がでるかも?ハック的な実装になる。
不具合が出た場合に常にこのネイキッドドメイン+CDNの実装が原因であるという疑惑が払拭できないので私はやらない。 - 設計はシンプルにまっすぐいくべきと考えています。
プロトコルの流れ
USER →(HTTPS)→ CloudFront →(HTTPS)→ ELB →(HTTP)→ EC2(Apache&WordPress) www.example.net alb.example.net www.example.net
USER → 443 → CloudFront → 443 → ALB → 80 → EC2
こういう流れになります。ALBとEC2の通信を80にすることで、AWS ACMを利用した証明書自動更新環境が作れます。
条件
下記ドメインの証明書をAWS ACM ヴァージニアリージョンで取得しておく
- CloudFront適用/EC2 Apache設定用ドメイン
www.example.net - ALB適用ドメイン
alb.example.net
EC2設定
必要モジュールのインストール
# amazon-linux-extras install php7.2 # yum localinstall https://dev.mysql.com/get/mysql80-community-release-el7-1.noarch.rpm -y # yum-config-manager --disable mysql80-community # yum-config-manager --enable mysql57-community # yum install -y httpd php mysql-community-server
起動、自動起動設定
# systemctl start httpd mysqld # systemctl enable mysqld httpd
WordPress DB作成
# mysql -u root -p Enter password:<パスワード入力> rootパスワード再設定 mysql> ALTER USER 'root'@'localhost' IDENTIFIED BY 'DSFakjo45@f'; DB作成 mysql> CREATE DATABASE wpdb; DBユーザ作成 mysql> GRANT ALL PRIVILEGES ON wpdb.* TO wpdbuser@localhost IDENTIFIED BY 'TAeesfjk@4' WITH GRANT OPTION; mysql> exit Bye
WordPressのダウンロード
# cd /var/www/html/ # wget https://ja.wordpress.org/latest-ja.tar.gz # tar -xzvf latest-ja.tar.gz # rm -rf latest-ja.tar.gz
バーチャルホスト設定
# vi /etc/httpd/conf.d/Globalsetting.conf <VirtualHost *:80> ServerName www.example.net DocumentRoot /var/www/html/wordpress ErrorLog logs/www.example.net-error.log CustomLog logs/www.example.net-access.log elb-customlog env=!nolog ## ALB httpで来たらhttpsにリダイレクトする <IfModule mod_rewrite.c> RewriteEngine On RewriteCond %{HTTP:X-Forwarded-Port} !^443$ RewriteCond %{HTTP_USER_AGENT} !^ELB-HealthChecker RewriteRule ^(.*)?$ https://www.example.net$1 [R=301,L] </IfModule> <Directory "/var/www/html/wordpress/"> # 2.2系 #AllowOverride All #Order allow,deny #Allow from all # 2.4系対策 AllowOverride All Require all granted </Directory> </VirtualHost> # alb.example.netをwww.example.netにリダイレクト <VirtualHost *:80> ServerName alb.example.net ServerAlias www.example.net DocumentRoot /var/www/html/wordpress/ RedirectMatch 301 .* https://www.example.net/ </VirtualHost>
ヘルスチェックファイル設定
# vi /var/www/html/healthcheck.php <?php echo "<h1>Don'T Remove!!</h1><br/>"; echo "<h2>LoadBalanser HealthCheck File</h2><br/>"; echo "このファイルを削除するとLBの死活監視で\"unhealthy\"となり、<br/>"; echo "アクセス障害が発生します。<br/>";
ヘルスチェックファイル サーバ内パス設定
# vi /etc/httpd/conf.d/healthcheck.conf # ヘルスチェックURL Alias /healthcheck.php /var/www/html/healthcheck.php # ヘルスチェックのALBのアクセスはログを取らない SetEnvIf User-Agent "ELB-HealthChecker.*" nolog
# chmod 444 /var/www/html/healthcheck.php
サーバログのパラメータ
%{X-Forwarded-For}i アクセス元IP %h ホスト名 %l クライアント情報 %u 認証ユーザ %t リクエスト日時 %r リクエスト Request %s ステータス %b バイト数 %{Referer}i リファラ %{User-Agent}i ユーザエージェント %{X-Forwarded-Proto}i プロトコル %{Hoge}i リクエストヘッダのHogeの中身を出力 %{Hoge}o レスポンスヘッダHogeの内容 %{FOOBAR}e 環境変数FOOBARの値
remoteipモジュールの確認
# httpd -M | grep remoteip remoteip_module (shared)
これがないとクライアントIPが取得できない。
ログフォーマット設定
# vi /etc/httpd/conf/httpd.conf <IfModule log_config_module> # # The following directives define some format nicknames for use with # a CustomLog directive (see below). # LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined LogFormat "%h %l %u %t \"%r\" %>s %b" common LogFormat "%{X-Forwarded-For}i %h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" \"%{X-Forwarded-Proto}i\"" elb-customlog ←追加
反映
# systemctl restart httpd
WordPress設定ファイルをサンプルからコピーして有効化
# cp /var/www/html/wordpress/wp-config-sample.php /var/www/html/wordpress/wp-config.php
WordPress設定ファイルの編集
- DBの設定
- リダイレクトループ対応
- サイト名対応
コンフィグファイル設定
- DB設定
- ALBのリダイレクトループ対策
- サイトURL定義
# vi /var/www/html/wordpress/wp-config.php // ** MySQL 設定 - この情報はホスティング先から入手してください。 ** // /** WordPress のためのデータベース名 */ define('DB_NAME', 'wpdb'); /** MySQL データベースのユーザー名 */ define('DB_USER', 'wpdbuser'); /** MySQL データベースのパスワード */ define('DB_PASSWORD', 'TAeesfjk@4'); /** MySQL のホスト名 */ define('DB_HOST', 'localhost'); /** データベースのテーブルを作成する際のデータベースの文字セット */ define('DB_CHARSET', 'utf8'); /** データベースの照合順序 (ほとんどの場合変更する必要はありません) */ define('DB_COLLATE', ''); # AWS ELB(ALB) リダイレクトループ対策 if ( ! empty( $_SERVER['HTTP_X_FORWARDED_PROTO'] ) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https' ) { $_SERVER['HTTPS']='on'; } ※下記を挿入する # AWS ELB(ALB) リダイレクトループ対策 if ( ! empty( $_SERVER['HTTP_X_FORWARDED_PROTO'] ) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https' ) { $_SERVER['HTTPS']='on'; } # WP_SITEURL, WP_HOME設定 define( 'WP_SITEURL', 'https://www.example.net' ); define( 'WP_HOME', 'https://www.example.net' );
CloudFront初期設定
Origin Domain Name alb.example.net Origin Path ※空白 Origin ID Custom-alb.example.net/alb.example.net ※自動入力される Minimum Origin SSL Protocol TLSv1 Origin Protocol Policy HTTPS Only Origin Response Timeout 30 Origin Keep-alive Timeout 5 HTTP Port 80 HTTPS Port 443 Path Pattern Default (*) Viewer Protocol Policy Redirect HTTP to HTTPS Allowed HTTP Methods GET, HEAD, OPTIONS, PUT, POST, PATCH, DELETE Cache Based on Selected Request Headers Whitelist Authorization 管理画面にベーシック認証を入れる時などに必要です。 CloudFront-Forwarded-Proto Origin側へプロトコルを通知します。 Host Origin側へアクセス先ホスト名を通知します。 Object Caching Customize Minimum TTL 60 Maximum TTL 60 Default TTL 60 Forward Cookies whitelist Whitelist Cookies wp-settings* wordpress_logged_in* Query String Forwarding and Caching Forward all, cache based on all Alternate Domain Names(CNAMEs) www.example.net SSL Certificate Custorm SSL Certificate www.example.net ←証明書(ヴァージニアで取得)を選択 Logging On Bucket for Logs ※自動指定
CloudFront作成後、[Behaviors]-[Create Behavior]から
指定したパスに対してTTL=0, メソッドをCloudFrontにスルーさせてキャッシュをしないようにする
- /wp-login.php
このままだとログインが出来ない、ログイン出来るようにしよう。 - /wp-admin/*
管理系の情報をキャッシュしてはいけない - *.php
動的なスクリプトをキャッシュさせてはいけない
・/wp-admin/* ・/wp-login.php ・*.php Viewer Protocol Policy Redirect HTTP to HTTPS Allowed HTTP Methods GET, HEAD, OPTIONS, PUT, POST, PATCH, DELETE Object Caching Customize Minimum TTL 0 Maximum TTL 0 Default TTL 0 Forward Cookies All Query String Forwarding and Caching Forward all, cache based on all
ErrorのTTLを短く!Error Caching Minimum TTL
4xx, 5xx系のエラーキャッシュのデフォルトのTTLはなんと5分!
- 各10秒程度に変更するのが良い
これをやっておかないと、復旧してもキャッシュされたエラーページが5分もクライアントに返すことになる。
ALB
【ターゲットグループ】 → 【ヘルスチェック】
- プロトコル: http
- ヘルスチェックパス:healthcheck.php
アクセスして表示されるか確認しよ~!
CloudFront動作確認
通常のアクセス(2回目)
x-cacheヘッダーにて「Hit from cloudfront」を確認 → キャッシュされている
ログイン中
x-cacheヘッダーにて「Miss from cloudfront」を確認 → キャッシュなし
キャッシュされてちゃだめですよ!
お疲れ様です。