ちょっと話題の記事

Amazon Lightsail(VPS)で独自ドメイン・SSL対応したWordPressを構築($3.50〜/月)

Amazon Lightsail、Amazon CloudFront,ACM を使い、独自ドメイン・SSL対応したWordPressをシュッと構築する方法を紹介します。
2019.03.05

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

はじめに

AWSの技術スタックを利用し、独自ドメイン、SSL対応したWordPressをシュッと構築する方法を紹介します。

操作はすべてブラウザから行います。

前提として、AWSの基本的な使い方は理解しており、独自ドメインは取得済みとします。

アーキテクチャ

以下の AWS サービスを利用します

  • Amazon Lightsail : AWSの提供するVPSサービス。WordPressの実行、DNS
  • Amazon CloudFront : CDN
  • AWS Certificate Manager : 無料の SSL 証明書発行サービス

大きな特徴は以下です。

  • WordPress をインストール済みの Lightsail インスタンスを利用。Bitnami が提供
  • Client <-> CloudFront 間は HTTPS, CloudFront <-> LightSail間はHTTP通信
  • サーバーの負荷軽減のため、CDN(Amazon CloudFront) を利用
  • SSL 証明書を CloudFront にインストール

サイトへは CloudFront 経由で www.example.com のドメイン名でアクセスし、Lightsail インスタンスに直接アクセスしたいときは、 wp.example.com のドメイン名でアクセスするものとします。

AWS 利用費

この構成で構築した場合の費用感を確認します。

結論から言うと、最小構成の場合、月額の利用費は $4 弱に抑えられます。

Amazon Lightsail

必ず発生するのが Amazon Lightsail の利用費です。

  • 512 MB Memory
  • 1 Core Processor
  • 20 GB SSD Disk
  • 1 TB データ転送

という一番低いスペックの場合、$3.50/月 です。

アクセスがあまりないサイトであれば、このスペックで十分です。

Amazon CloudFront

CDN 経由のトラフィックに応じて、Amazon CloudFront の利用費が発生します。

CloudFrontからインターネットへのデータ転送がCloudFront利用費の多くを占めることが多く、東京エリアのこの単価は $0.114/GB です。 仮に月に10GBのインターネットへの配信がある場合、$1.1/月 程度の利用費が発生します。

AWS Certificate Manager

SSL 証明書は、初回取得時も更新時も費用は発生しません。

構築

費用感を確認したところで、実際に構築します。

以下の流れで行います。

  1. Amazon LightSal インスタンスを起動
  2. 独自ドメインでWordPressにアクセスする
  3. SSL 証明書の取得
  4. CloudFront の構築
  5. Lightsail インスタンス内の作業
  6. WordPress に独自ドメイン・HTTPSでアクセス

1. Amazon LightSal インスタンスを起動

インスタンスの起動

Amazon の提供する VPS サービス Amazon Lightsail で WordPress サーバーを構築します。

Lightsail で機能可能なインスタンスは以下の種類があります。

  • OS のみ
  • Linux/Unix系
  • Windows系
  • OS + アプリ
  • WordPress(Bitnami が提供)
  • LAMP (PHP 7)
  • SQL Server 2016 Express

インストールの手間を軽減するため、今回は Bitnami が提供する WordPress をインストール済みのインスタンスを利用します。

Lightsail 管理画面の Create instance リンクから、インスタンス起動画面に遷移し

  • Instance location(インスタンスを起動するリージョン。)
  • Instance image(Linux/Unix の WordPress 4.9.8 を選択)
  • Instance Plan(インスタンスのスペック)
  • Instance Name(インスタンス名)

を設定・入力し、「Create instance」ボタンをクリックします。

インスタンス作成後、インスタンスの状態が「Running」になると、利用可能です。

起動した WordPress にアクセス

インスタンスの詳細画面から、インスタンスの Public IP アドレスを確認します。

公開サイト

この IP アドレスにアクセスし、WordPress のトップページが表示されることを確認します。

http://WordPress-Public-IP/

管理サイト

次に、WordPress の管理画面にアクセスします。

WordPress のクレデンシャル情報はインスタンスの bitnami ユーザーのホームディレクトリ直下のファイル「bitnami_credentials」にあります。

Lightsail インスタンス詳細ページの 「Connect using SSH」ボタンから、インスタンスに接続し、ファイルの中身を確認します。

この情報を利用し、次の URL から WordPress の管理画面にログインできることを確認します。

http://WordPress-Public-IP/wp-admin/

2. 独自ドメインでWordPressにアクセスする

Amazon Lightsailには権威DNSサーバ機能があります。 この機能を利用して、専用ドメインで先程作成した WordPress インスタンスにアクセスします。 なお、ドメインの取得は完了していることが前提となります。

以下の流れで行います。

  1. Lightsailインスタンスに静的IPアドレスを設定
  2. LightsailでDNS ゾーンを作成
  3. Lightsailインスタンス用のAレコードを登録
  4. 独自ドメインのネームサーバーをLightsailのものに変更
  5. 独自ドメインでアクセス

2-1. Lightsailインスタンスに静的IPアドレスを設定

Lightsail インスタンスがデフォルトで利用する IP アドレスは、インスタンスを一度停止すると、再起動後は別のものに変わります。

Lightsail インスタンスの Networking メニューから「Create static IP」をクリックし、静的IPアドレスを設定します。

2-2. LightsailでDNS ゾーンを作成

Lightsail 管理画面トップページの Networking メニューから「Create DNS zone」を選択し、登録済みドメイン(example.com など)向けのゾーンを作成します。

2-3. Lightsailインスタンス用のAレコードを登録

以下のレコードを作成します。

  • レコードタイプ : A
  • サブドメイン : wp
  • 解決先 : ステップ1 で割り当てた静的IPアドレス (補完機能により、選択肢として表示されます

ここで設定するサブドメイン(wp.)はCloudFront用に利用するものです。 サイト公開時に利用するサブドメイン(www. など)は設定しないでください。

名前解決してみます。

$ dig wp.example.com

; <<>> DiG 9.10.3-P4-Ubuntu <<>> wp.example.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 12568
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;wp.example.com.			IN	A

;; ANSWER SECTION:
wp.example.com.		60	IN	A	3.122.208.48

;; Query time: 11 msec
;; SERVER: 172.26.0.2#53(172.26.0.2)
;; WHEN: Mon Mar 04 14:44:20 UTC 2019
;; MSG SIZE  rcvd: 57

期待どおりです。

2-4. 独自ドメインのネームサーバーをLightsailのものに変更

ドメインプロバイダーがLightsailのネームサーバーを使用するように、設定します。

Lightsail のネームサーバー一覧は、DNSゾーン詳細画面の最下部に表示されます。

設定方法はドメインプロバイダーのドキュメントを参照ください。

2-5. 独自ドメインでアクセス

ネームサーバーの変更完了後、Lightsail インスタンスに割り当てたドメインでアクセスできることを確認してください。

3. SSL 証明書の取得

AWS が提供する SSL 証明書発行サービス(AWS Certificate Manager。以下 ACM)を利用して、SSL証明書を無料で取得します。

証明書は CloudFront に設定するため、北部バージニアリージョンを利用します。

今回はドメイン配下の任意のサブドメインでも利用できるように、ワイルドカード証明書を取得します。

証明書リクエストは

  • DNS
  • Email

の2方式で検証されます。今回は DNS 検証を利用します。

証明書をリクエストすると、DNS 検証のためにNameとVaueのペアが生成されます。

この値を Lightsail の DNS にCNAMEレコードとして追加します。

検証が終わると Validation statusPending validation から Success に遷移します。

詳細は、次のドキュメントを参照ください。

DNS を使用したドメインの所有権の検証

4. CloudFront の構築

次に、CDN および、 SSL 証明書のインストール先として利用する Amazon CloudFront を構築します。

以下の設定で Web ディストリビューションを作成します。

General 設定

| Delivery Method | Web | | --- | --- | | Alternate Domain Names (CNAMEs) | www.example.com | | SSL Certificate | Custom SSL Certificate プルダウンからACMで取得した証明書を設定 | | Origin Domain Name | wp.example.com |

ポイント

  • Origin Domain Name にはオリジンサーバーである WordPress インスタンスのドメインを指定
  • Alternate Domain Names (CNAMEs) にはサービスを提供するドメインを指定
  • ACM で取得した SSL 証明書を紐付ける

Behavior 設定

| Path Pattern | Default() | /wp-login.php | /wp-admin/* | | --- | --- | --- | --- | | Viewer Protocol Policy | Redirect HTTP to HTTPS | same | same | | Allowed HTTP Methods | GET, HEAD, OPTIONS, PUT, POST, PATCH, DELETE | same | same | | Cache Based on Selected Request Headers | Whitelist | same | same | | Whitelist Headers | CloudFront-Forwarded-Proto Host | same | same | | Object Caching | Default | Customize(すべて0。キャッシュしない) | same | | Forward Cookies | comment_author_* wordpress_logged_in_* wordpress_test_cookie wp-settings-* | All | All | | Query String Forwarding and Caching | Forward All, cache based on all. | same | same |

ポイント

  • 公開系と管理系の2種類、3つのBehaviorを用意
  • HTTP から HTTPS へのリダイレクトはこの CloudFront レイヤーで実施
  • 全ての HTTP メソッドを許可(公開サイトには検索機能があるため POST リクエストなども行われる)
  • キャッシュに関し、公開系Behavior(Default(*)) はデフォルト通りにキャッシュ。管理系Behavior(/wp-login.php*//wp-admin/*) はキャッシュしない
  • Cookie に関し、WordPress で認証済みの場合、コンテンツの見え方が異なるため、WordPress 系 Cookie をキャッシュキーに利用

Cache Based on Selected Request Headers とそのホワイトリストについて補足します。

Host ヘッダー

オリジンサーバーでは、CloudFront にリクエストされたホスト名で処理したいため、Host ヘッダーをホワイトリストに追加しています。

この設定を行わない場合、リダイレクト先やリソースのホスト名がオリジンのホスト名(wp.exampel.com)になる、といった問題が発生します。

CloudFront-Forwarded-Proto ヘッダー

今回の構成では、CloudFront で SSL ターミネーションを行い、オリジンサーバーには HTTP で通信します。

CloudFront にアクセスしているプロトコルをオリジンサーバーから取得できるように、このヘッダーをホワイトリストに追加します。

そのような目的のために X-Forwarded-Proto ヘッダーが広く使われますが、CloudFront はオリジンへのリクエスト時にこのヘッダーを(ホワイトリストに登録しても)削除するため、代わりに CloudFront-Forwarded-Proto ヘッダーを利用します。

この設定を行わないと、HTTP から HTTPS への無限リダイレクトといった現象が発生します。

詳細は、次のドキュメントを参照ください。

Request and Response Behavior for Custom Origins

CloudFront用のCNAMEレコードを登録

サービス提供用ドメインをCloudFrontのドメインで解決するように、以下のレコードを追加します。

  • レコードタイプ : CNAME
  • サブドメイン : www ※ サービス提供用ドメイン
  • 解決先 : CloudFront のドメイン名(例:xxx.cloudfront.net)

最終的な DNS レコード一覧

名前解決してみます。

$ dig www.example.com

; <<>> DiG 9.10.6 <<>> www.example.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 33542
;; flags: qr rd ra; QUERY: 1, ANSWER: 5, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;www.example.com.			IN	A

;; ANSWER SECTION:
www.example.com.		60	IN	CNAME	d36vgoest8ofuc.cloudfront.net.
d36vgoest8ofuc.cloudfront.net. 60 IN	A	52.222.250.141
d36vgoest8ofuc.cloudfront.net. 60 IN	A	52.222.250.226
d36vgoest8ofuc.cloudfront.net. 60 IN	A	52.222.250.189
d36vgoest8ofuc.cloudfront.net. 60 IN	A	52.222.250.199

;; Query time: 43 msec
;; SERVER: 172.26.0.2#53(172.26.0.2)
;; WHEN: Mon Mar 04 14:43:33 UTC 2019
;; MSG SIZE  rcvd: 149

期待通りです。

5. Lightsail インスタンス内の作業

最後に、Lightsail インスタンス内で最小限のサーバー設定を行います。

WordPress のクレデンシャルを取得したときと同じく、ブラウザからインスタンスに接続し、設定ファイル(/opt/bitnami/apps/wordpress/htdocs/wp-config.php)を修正します。

修正内容

以下のコードを追記します。

/opt/bitnami/apps/wordpress/htdocs/wp-config.php

// URL のプロトコルを http から https に変更
define('WP_SITEURL', 'https://' . $_SERVER['HTTP_HOST'] . '/');
define('WP_HOME', 'https://' . $_SERVER['HTTP_HOST'] . '/');

// 以下を新規追加
// CloudFront に HTTPS でアクセスされたときは、フラグを立てる
if (strpos($_SERVER['HTTP_CLOUDFRONT_FORWARDED_PROTO'], 'https') !== false) {
  $_SERVER['HTTPS'] = 'on';
}

_SERVER 変数から取得している値

  • HTTP_HOST
  • HTTP_CLOUDFRONT_FORWARDED_PROTO

は CloudFront の Cache Based on Selected Request Headers 設定でホワイトリストに追加したものです。

6. WordPress に独自ドメイン・HTTPSでアクセス

コマンドラインから HTTP リクエストが HTTPS にリダイレクトされることを確認します。

$ curl -I http://www.example.com/
HTTP/1.1 301 Moved Permanently
Server: CloudFront
Date: Mon, 04 Mar 2019 14:45:57 GMT
Content-Type: text/html
Content-Length: 183
Connection: keep-alive
Location: https://www.example.com/
X-Cache: Redirect from cloudfront
Via: 1.1 3f146fa6bc6607097fc0d9bc7e6d4947.cloudfront.net (CloudFront)
X-Amz-Cf-Id: R4pJYSJCTBhXb16Brqc6x4mVAB2NPQCOh0_rUBwawdxO6GcLf3_WKg==

確かに、HTTPS に 301 リダイレクトされています。

ブラウザからも同様の動作を確認し、公開サイトの表示や管理画面のログイン・操作などに問題がなければ、動作確認終了です。

改善ポイント

この構成をカスタマイズするポイントを簡単にご紹介します。

SSL証明書のインストール場所を変更

今回は、CloudFront にインストールしました。

CloudFront 以外にも

などにインストール可能です。

要件に合わせて、使い分けてください。

バックアップを取る

Lightsail のスナップショット機能を利用し、定期的にバックアップを取得してください。

WAF を追加

本構成のように Amazon CloudFront でコンテンツ配信している場合、WAF として AWS WAF を簡単に追加できます。

例えば、サブスクリプションモデルの Managed Rule を利用する場合、$5/月 程度から WAF を利用できます。

最後に

Amazon Lightsail、Amazon CloudFront,ACM を使い、独自ドメイン・SSL対応したWordPressを構築する方法を紹介しました。

Lightsail + WordPress の組み合わせなので、できるだけ楽をしてさくっと構築するはずだったのに、いざ構築してみると、期待通りに動かなかったり、設定で悩む箇所が多々あったりと、想定よりも多くの時間がかかりました。

本ブログが、どこかの誰かの為になれば幸いです。

参考