share facebook facebook facebook twitter twitter menu hatena pocket slack

2021.01.25 MON

CloudFront + WordPress 構成の必須設定

新川 貴章

WRITTEN BY 新川 貴章

概要

はじめに

  • 本日は、AWS CloudFront + WordPress 構成を構築する上でハマった落とし穴をいくつかご紹介します。CloudFront + WordPress 構成を採用される方は、参考にして下さい。

システム構成

  • Amazon Lightsailに、WordPress環境を起動しています。WordPressのバージョンは、5.6です。WordPressのフロントにCloudFrontを設置し、CloudFrontでSSLの終端を行っています。
  • なお、今回ご紹介する落とし穴は、通常のWordPress環境およびWordPress Multisite環境の両方で発生することを確認しております。

siteurl がオリジン側のURLを向いてしまう

説明

  • Amazon LightsailにWordPressのインスタンスを起動し、CloudFront のオリジンに設定してディストリビューションを作成、CNAME設定を行います。以下の通り、CNAMEに設定したCDN側 URL にてアクセスが可能になりました。

  • しかし、CDN側 URLでアクセスできたのはトップページのみで、画面を遷移するとオリジン側URL を向いてしまいます。

  • これは、CloudFrontをWordPressのフロントに配置した構成における特有の症状です。WordPressのwp-config.php(/opt/bitnami/apps/wordpress/htdocs/wp-config.php)に下記のエントリがあり、siteurl がオリジン側 URLに変わります。
  • 理由は、CloudFrontのデフォルトのキャッシュ動作設定では、CloudFrontがHOSTヘッダを置き換えるために起こります。
define('WP_SITEURL', 'http://' . $_SERVER['HTTP_HOST'] . '/');
define('WP_HOME', 'http://' . $_SERVER['HTTP_HOST'] . '/');
  • また、WordPressの管理画面からも Site Address がオリジン側 URL となっていることが分かります。

  • 一方、CloudFrontのキャッシュ動作の設定がデフォルトであり、かつwp-config.php に以下のようにダイレクトにCDN側 URLを記載している場合は、WordPressのホスト名(siteurl)とリクエストされたHOSTヘッダが一致せず、”403 Forbidden“のエラーで管理画面にアクセスができなくなります。
define('WP_HOME','http://niikawa-wp.example.net');
define('WP_SITEURL','http://niikawa-wp.example.net');

対処方法

  • WordPressの動作にはドメイン名(siteurl)が必要となります。しかし、CloudFront のキャッシュ動作において、CloudFrontはリクエストのHOSTヘッダをオリジンのドメイン名に置き換えるため、期待通りにアクセスができません。
  • 対策は、CloudFrontのキャッシュ動作の設定を変更します。Cache Based on Selected Request Headers(選択されたリクエストヘッダーに基づいたキャッシュ)の設定を “Whitelist"に変更し、Whitelist Headersに"Host"を追加します。あるいは、"All" に変更を行います。

デフォルトのキャッシュ設定はWordPressの管理画面を使用できない

説明

  • WordPressの管理画面が正しく機能せず、Cookieのエラーでログインができなかったり、コンテンツのサイト表示が崩れたりします。これは、CloudFrontをWordPressのフロントに配置した構成における特有の症状です。
  • 以下は、Cookieのエラーが表示されログインができない画面になります。

  • 以下は、サイト表示が崩れたWordPress管理画面になります。

対処方法

  • WordPressの管理画面を使用するために、CloudFront の下記キャッシュ設定を変更します。
    • Allowed HTTP Methods をデフォルトの”GET, HEAD” → “GET, HEAD, OPTIONS, PUT, POST, PATCH, DELETE”
    • Forward Cookiesをデフォルトの”None (Improves Caching)” → “All”
    • Query String Forwarding and Cachingをデフォルトの”None (Improves Caching)” → “Forward all, cache based on all”

siteurlをhttps化できない or リダイレクト ループ

説明

  • httpでアクセスするとコンテンツが正しく表示されますが、httpsでアクセスするとコンテンツのサイト表示が崩れます。

  • また、WordPressの管理画面から Site Address を確認すると、URLがhttp となっていることが分かります。

対処方法

  • Really Simple SSLのプラグインをインストール、SSLを有効化しましたが、 ERR_TOO_MANY_REDIRECTSのエラーとなり、redirect loopが発生してしまいました。Really Simple SSLのプラグインは、CloudFront構成が考慮されておらず、代替の手段が必要であることが分かりました。
  • 代わりに、SSL Insecure Content Fixerのプラグインを使用しました。以下に対処の手順を説明します。先ず、SSL Insecure Content Fixerのプラグインをインストールします。

  • 次に、WordPress のSettings から”SSL Insecure Content”を開きます。”HTTPS detection”の設定値が”standard WordPress function” となっているため、“HTTP_CLOUDFRONT_FORWARDED_PROTO (Amazon CloudFront HTTPS cached content)”に変更、保存します。

  • 今回、siteurlがhttps化されなかった理由は、CloudFrontをWordPressのフロントに配置した構成における特有の症状です。CloudFront はリクエスト元の X-Forwarded-Protoヘッダを削除するためクライアントのプロトコルを特定できず、WordPress が制御できませんでした。
  • CloudFront のキャッシュ動作の設定を変更し、CLOUDFRONT_FORWARDED_PROTOヘッダを追加します。Cache Based on Selected Request Headers(選択されたリクエストヘッダーに基づいたキャッシュ)の設定を “Whitelist"に変更し、Whitelist Headersに"CloudFront-Forwarded-Proto"を追加します。あるいは、"All" に変更を行います。

  • 確認のため、再度、WordPress のSettings から”SSL Insecure Content”を開きます。無事に、httpsプロトコルが検出できたようです。

  • WordPressの管理画面の Site Addressは自動で修正されなかったため、wp-config.phpを手動で修正します。(WP_SITEURL, WP_HOMEのhttpをhttpsに書き替え)
  • wp-config.phpを手動で変更する以外に、wp option update コマンドを利用する方法もあります。
bitnami@ip-xx-xx-xx-xx:~$ sudo cp -p  /opt/bitnami/apps/wordpress/htdocs/wp-config.php /opt/bitnami/apps/wordpress/htdocs/wp-config.php_orig
bitnami@ip-xx-xx-xx-xx:~$ sudo vi /opt/bitnami/apps/wordpress/htdocs/wp-config.php

bitnami@ip-xx-xx-xx-xx:~$ sudo diff /opt/bitnami/apps/wordpress/htdocs/wp-config.php_orig /opt/bitnami/apps/wordpress/htdocs/wp-config.php
98,99c98,99
< define('WP_SITEURL', 'http://' . $_SERVER['HTTP_HOST'] . '/');
< define('WP_HOME', 'http://' . $_SERVER['HTTP_HOST'] . '/');
> define('WP_SITEURL', 'https://' . $_SERVER['HTTP_HOST'] . '/');
> define('WP_HOME', 'https://' . $_SERVER['HTTP_HOST'] . '/');
  • WordPressの管理画面から Site Address を確認すると、URLがhttps に変わったことが確認できました。

  • 最後に、httpsでアクセスしても、コンテンツが正しく表示されることが確認できました。

WordPressブロックエディターが使えない

  • WordPressで記事を投稿する際に、ブロックエディター(Gutenberg)でブロックの追加ができない、クラシックエディターはテキストモードしか使えない(ビジュアルモードに切り替えができない)問題に遭遇しました。詳細は、下記の記事にまとめておりますが、WordPress はUser-Agentヘッダを判別して、ビジュアルエディターを起動することが理由でした。対処として、CloudFrontでUser-Agentヘッダを置き換えせず、User-Agentヘッダをオリジンに転送するように変更を行います。
概要はじめに 本日は、AWS CloudFront + WordPress 構成を構築後に経験した事例をご紹介します。原因が特定できるまでの数日間、ブロックエディターおよびクラシックエディターのビジュアルモードが使用できず、不便な日々を過ごしておりました...。そして調査の結果...

CloudFront キャッシュ設定のまとめ

  • ここまでご紹介した対処方法をCloudFront のDefaultパスに設定すると、コンテンツのキャッシュが活かせないため、私の場合CloudFrontのキャッシュ設定にてパスパターンを追加し、WordPressの管理画面(* .php、/wp-admin/ *)とその他のコンテンツ(Default)でキャッシュ設定を区別して設定しています。WordPressの管理画面の方には、こちらで紹介した設定が必要になります。
  • 個人的には無用なトラブルに遭遇することを避けるため、CloudFrontのCache Based on Selected Request Headers(選択されたリクエストヘッダーに基づいたキャッシュ)の設定は”Whitelist”ではなく、“All” を設定しています。
  • また、”Viewer Protocol Policy”をデフォルトの”HTTP and HTTPS” から “Redirect HTTP to HTTPS” に変更します。設定変更後は、クライアントからhttp でアクセスがあった場合でも、自動的にhttps にリダイレクトを行います。

参考資料

CloudFront がカスタムオリジンサーバーのビューワーリクエストとレスポンスを処理する方法について説明します。
概要はじめに今回は、CloudFront のディストリビューションに代替ドメイン名(CNAME)を設定する方法をまとめます。代替ドメイン名の設定によって、ディストリビューションにデフォルトで割り当てられたドメイン名ではなく独自のドメイン名 (例: www.example.com) が...
概要はじめに 本日は、AWS CloudFront + WordPress 構成を構築後に経験した事例をご紹介します。原因が特定できるまでの数日間、ブロックエディターおよびクラシックエディターのビジュアルモードが使用できず、不便な日々を過ごしておりました...。そして調査の結果...

元記事はこちら

CloudFront + WordPress 構成の必須設定

cloudpack

cloudpackは、Amazon EC2やAmazon S3をはじめとするAWSの各種プロダクトを利用する際の、導入・設計から運用保守を含んだフルマネージドのサービスを提供し、バックアップや24時間365日の監視/障害対応、技術的な問い合わせに対するサポートなどを行っております。
AWS上のインフラ構築およびAWSを活用したシステム開発など、案件のご相談はcloudpack.jpよりご連絡ください。