LoginSignup
2
1

More than 3 years have passed since last update.

WordPress on Lightsail をシェルスクリプト一撃で SSL 化 (証明書自動更新、HTTP からのリダイレクト付き)

Last updated at Posted at 2019-07-03

はじめに

Amazon Lightsail を使うと WordPress を簡単に構築できます。
しかし、SSL 化しようとすると以下のような設定が必要で少し面倒です。

  • Let's Encrypt で証明書を作成して配置1
  • 証明書は定期的に自動更新
  • HTTP から HTTPS へのリダイレクト
  • 内部リンクの http://~ から https://~ への置き換え

そこで、シェルスクリプト一撃 (+ ちょっと) でここまでセットアップできるようにしました。

※ Let's Encrypt には証明書の発行に制限数があります。ご注意ください (参考: Rate Limits)
※ パッケージのロックファイルによるエラーの対応として、ロックファイルを無理やり削除しています。ご注意ください

WordPress 構築 & SSL 設定手順

インスタンス作成

Lightsail で WordPress を構築するのは非常に簡単です。
プラットフォームで「Linux / Unix」を選択し、設計図で「WordPress」を選択するだけです。
インスタンス名を適当に入力してしばらく待てば、WordPress インストール済みのインスタンスが起動します。

DNS 設定

インスタンスが起動したら、「ネットワーキング」の設定から静的 IP を付与します。
付与された IP に対して、DNS の A レコードを設定します。2

SSL 化スクリプト実行

シェルスクリプト実行のため、Lightsail のインスタンスに SSH 接続します。

$ ssh -i xxx.pem bitnami@xxx.xxx.xxx.xxx

curl で Gist からシェルスクリプトを取得して実行します。

$ curl -LO https://gist.githubusercontent.com/os1ma/ac6f8e39ec8d01ee01b79aacf2e07f39/raw/f9824aeda4208d15f7380b25bf276e2b5e60295a/setup_lightsail_wordpress_letsencrypt.sh
$ chmod +x setup_lightsail_wordpress_letsencrypt.sh
$ ./setup_lightsail_wordpress_letsencrypt.sh www.example.com mail@example.com

※ 3 つ目のコマンドのドメインとメールアドレスは適切に書き換えてください

WordPress の管理画面で SSL 有効化

以下のコマンドで WordPress 管理画面のパスワードを確認します。

$ cat "${HOME}/bitnami_application_password"

https://<設定したドメイン>/wp-login.php から WordPress の管理画面にログインします。

※ デフォルトのユーザ名は user です。

ダッシュボードの「Go ahead, activate SSL」ボタンをクリックすれば、SSL 化完了です。

最後に忘れずに

サーバ上で以下のコマンドを実行し、wp-config.php を編集できないようにします。

chmod g-w "${HOME}/apps/wordpress/htdocs/wp-config.php"

Lightsail の管理画面からファイアウォールの設定を変更して、SSH を接続不可にすることも忘れずに。

スクリプトの内容

スクリプトの主な処理を説明します。
全文は記事の最後または Gist を参照してください。

※ スクリプトの書き方は、Shell Style Guide - Google を参考にしています。

パッケージロックファイルを削除

私が試した限りでは、Let's Encrypt をインストールして証明書を発行する際に apt と dpkg 関係のロックファイルが原因でエラーが発生しました。
どれだけ待ってもロックファイルが消えず、ps aux | grep apt などで引っかかるプロセスなどもなかったため、諦めてロックファイルは削除することにしています。

#
# パッケージロックファイルを削除
#
delete_package_lock_files() {
  local package_lock_files=(
    '/var/lib/apt/lists/lock'
    '/var/cache/apt/archives/lock'
    '/var/lib/dpkg/lock'
    '/var/lib/dpkg/lock-frontend'
  )

  for lock_file in "${package_lock_files[@]}"; do
    if [[ -e "${lock_file}" ]]; then
      sudo rm "${lock_file}"
    fi
  done
  sudo dpkg --configure -a
}

参考
Lightsail Launch Script vs. DPKG Lock
E: Could not get lock /var/lib/dpkg/lock-frontend - open (11: Resource temporarily unavailable) [duplicate]

Let's Encrypt で SSL 証明書をセットアップ

証明書のセットアップとしては、関数内で以下の手順を実行しています。

  • Let's Encrypt のクライアントインストール
  • SSL 証明書の発行
  • 証明書を Apache の設定ディレクトリに配置
  • Apache を再起動
#
# Let's Encrypt で SSL 証明書をセットアップ
#
setup_cert_with_letsencrypt() {
  local letsencrypt_home="${SCRIPT_DIR}/letsencrypt"

  if [[ ! -e "${letsencrypt_home}" ]]; then
    git clone https://github.com/letsencrypt/letsencrypt
  fi

  "${letsencrypt_home}/letsencrypt-auto" certonly \
    --webroot \
    -w /opt/bitnami/apps/wordpress/htdocs/ \
    -d "${DOMAIN_NAME}" \
    -m "${EMAIL}" \
    --agree-tos \
    --non-interactive

  sudo cp "/etc/letsencrypt/live/${DOMAIN_NAME}/fullchain.pem" /opt/bitnami/apache2/conf/server.crt
  sudo cp "/etc/letsencrypt/live/${DOMAIN_NAME}/privkey.pem" /opt/bitnami/apache2/conf/server.key

  sudo /opt/bitnami/ctlscript.sh restart apache
}

参考
Let's Encrypt 総合ポータル - コマンド解説(コマンドリファレンス)
LightsailでWordPress(SSL化もする)

証明書更新の cron 設定

証明書の更新スクリプトの作成と、そのスクリプトの cron への登録を実施しています。

#
# 証明書更新用スクリプトを作成し、cron で毎週日曜日の朝4時に実行されるよう設定
#
set_cert_update_cron() {
  local cert_update_script_dir="${HOME}/bin"
  local cert_update_script="${cert_update_script_dir}/update_cert.sh"

  mkdir -p "${cert_update_script_dir}"

  cat << EOT > "${cert_update_script}"
#!/bin/bash

# --force-renewal をつけていないため、期限まで30日以内の場合に更新される
sudo /home/bitnami/letsencrypt/certbot-auto renew
sudo cp /etc/letsencrypt/live/${DOMAIN_NAME}/fullchain.pem /opt/bitnami/apache2/conf/server.crt
sudo cp /etc/letsencrypt/live/${DOMAIN_NAME}/privkey.pem /opt/bitnami/apache2/conf/server.key
sudo /opt/bitnami/ctlscript.sh restart apache
EOT

  chmod +x "${cert_update_script}"
  echo "0 4 * * 0 ${cert_update_script}" | crontab
}

参考
Amazon Lightsail に SSL 証明書設置 with Let’s Encrypt(自動更新)

Really Simple SSL プラグインインストール

WordPress の SSL 化に関しては、様々なプラグインがあります。
その中でも Really Simple SSL というプラグインが

  • HTTP から HTTPS へのリダイレクト
  • 内部リンクの http://~ から https://~ への置き換え

といったものを全部やってくれるようだったので、このプラグインを使うことにしました。

プラグインは wp コマンドを使えば CLI でインストール可能ということだったので、シェルスクリプト内で wp コマンドを使っています。3

#
# Really Simple SSL プラグインのインストール
#
install_ssl_plugin() {
  local wp_config="${HOME}/apps/wordpress/htdocs/wp-config.php"

  chmod g+w "${wp_config}"
  wp plugin install really-simple-ssl
  wp plugin activate really-simple-ssl
}

参考
WordPressを一瞬でHTTPS化するプラグイン「Really Simple SSL」の使い方
プラグインで簡単!WordPressの常時SSL対応
wp-cli コマンド一覧

おわりに

シェルスクリプトは楽しい !

スクリプト全文

#!/bin/bash
#
# Lightsail WordPress の Let's Encrypt による SSL 化スクリプト
#
# 第 1 引数: ドメイン
# 第 2 引数: メールアドレス
#
# 使用例) ./setup_lightsail_wordpress_letsencrypt.sh example.com mail@example.com
#

set -o errexit
set -o nounset
set -o pipefail
set -o xtrace

readonly DOMAIN_NAME="$1"
readonly EMAIL="$2"

readonly SCRIPT_DIR="$(cd "$(dirname "$0")"; pwd)"

#
# パッケージロックファイルを削除
#
delete_package_lock_files() {
  local package_lock_files=(
    '/var/lib/apt/lists/lock'
    '/var/cache/apt/archives/lock'
    '/var/lib/dpkg/lock'
    '/var/lib/dpkg/lock-frontend'
  )

  for lock_file in "${package_lock_files[@]}"; do
    if [[ -e "${lock_file}" ]]; then
      sudo rm "${lock_file}"
    fi
  done
  sudo dpkg --configure -a
}

#
# Let's Encrypt で SSL 証明書をセットアップ
#
setup_cert_with_letsencrypt() {
  local letsencrypt_home="${SCRIPT_DIR}/letsencrypt"

  if [[ ! -e "${letsencrypt_home}" ]]; then
    git clone https://github.com/letsencrypt/letsencrypt
  fi

  "${letsencrypt_home}/letsencrypt-auto" certonly \
    --webroot \
    -w /opt/bitnami/apps/wordpress/htdocs/ \
    -d "${DOMAIN_NAME}" \
    -m "${EMAIL}" \
    --agree-tos \
    --non-interactive

  sudo cp "/etc/letsencrypt/live/${DOMAIN_NAME}/fullchain.pem" /opt/bitnami/apache2/conf/server.crt
  sudo cp "/etc/letsencrypt/live/${DOMAIN_NAME}/privkey.pem" /opt/bitnami/apache2/conf/server.key

  sudo /opt/bitnami/ctlscript.sh restart apache
}

#
# 証明書更新用スクリプトを作成し、cron で毎週日曜日の朝4時に実行されるよう設定
#
set_cert_update_cron() {
  local cert_update_script_dir="${HOME}/bin"
  local cert_update_script="${cert_update_script_dir}/update_cert.sh"

  mkdir -p "${cert_update_script_dir}"

  cat << EOT > "${cert_update_script}"
#!/bin/bash

# --force-renewal をつけていないため、期限まで30日以内の場合に更新される
sudo /home/bitnami/letsencrypt/certbot-auto renew
sudo cp /etc/letsencrypt/live/${DOMAIN_NAME}/fullchain.pem /opt/bitnami/apache2/conf/server.crt
sudo cp /etc/letsencrypt/live/${DOMAIN_NAME}/privkey.pem /opt/bitnami/apache2/conf/server.key
sudo /opt/bitnami/ctlscript.sh restart apache
EOT

  chmod +x "${cert_update_script}"
  echo "0 4 * * 0 ${cert_update_script}" | crontab
}

#
# Really Simple SSL プラグインのインストール
#
install_ssl_plugin() {
  local wp_config="${HOME}/apps/wordpress/htdocs/wp-config.php"

  chmod g+w "${wp_config}"
  wp plugin install really-simple-ssl
  wp plugin activate really-simple-ssl
}

#
# Main
#
main() {
  delete_package_lock_files

  setup_cert_with_letsencrypt

  set_cert_update_cron

  install_ssl_plugin
}

main "$@"

  1. ロードバランサを使って SSL 化することもできますが、Lightsail のロードバランサは 18 USD / 月と少し高額です。 

  2. DNS 設定前にスクリプトを実行すると、Let's Encrypt による DNS の検証でエラーが発生します。 

  3. Lightsail の WordPress のインスタンスには wp コマンドがインストール済みのため、特にセットアップ不要で使えます。 

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1