見出し画像

【WordPress, SSL化】EC2で立てたWordPressをLet’s EncryptでSSL化してみた

※ 旧ブログ、Frontend Life in DEのリライト記事。
※ 新ブログは Aiki x Developerhttps://aiki-developer.com)へ。

どうもー、ドイツでフリーランスのフロントエンドエンジニアをしています、Arisaです。

この3ヶ月は、1ヶ月の長期休暇で旅行も兼ねた一時帰国をしていたり、お仕事の依頼がありがたいことに増えたり、何かと忙しくしていて、ブログを全く書く時間が確保できずにいました。

長期休暇中は、ON/OFFをはっきりさせる練習のため、完全オフということで、全く1ヶ月間、エンジニアになってからの1年半で初めてコードを書かない期間をあえて作る実験(どんな実験 笑)もしていました。

案外1ヶ月やそこらでは忘れないものですね。

でもやっぱりコードが書ける方が落ち着くことも再確認できた面白い休暇でした。

さて、今回の記事の本題ですが、AWSのEC2で立てたWordPress(Bitnami)を、Let’s Encryptと言う無料のサービスを使ってSSL化をするのが今回のチュートリアルです。

SSL化は、最近でもGoogleがSSL化されていないサイトのSEO評価を下げる、とアナウンスをしましたね。

オンライン決済などを行うサイトではSSL化は情報の安全性のためにも必須化されています。

私も先日、つい最近海外在住者の売上振込をできないようにしたBASEと言うサービスをWordPressテーマ販売に使用していたのですが、使うメリットがなくなったので、自分のこのブログ上での販売準備の一環でSSL化をするに至ったわけなのです。

ついでに、古いhttpを含むURLでアクセスされても、強制でSSL化されたURLにリダイレクトをさせる設定と、SSL証明書の90日間の有効期限も自動更新する設定もしちゃいましょうということで、トラブルシューティングも含めたボリュームのある内容になります。

うまくいかない、こんなエラーが出たと言う時にも役立ててもらえる記事になれば嬉しいです。

環境

試した大まかな環境としては、以下です。

- AWS EC2でWordPressのインスタンスを立てている
- Bitnami
- ドメインはムームードメインで紐付けしている
- Let's Encryptを使用してSSL化
- OS: Mac OS X

AWSコンソールで22, 80, 443ポートを開けておく

AWSのコンソールにログインして行う作業

まずはAWSのコンソールにログインをして、 EC2 -> Security Groups -> Inbound で22、80、443のポートを開けておきます。

BitnamiにSSH接続

EC2でWordPress(Bitnami)をインストールしていることを前提に話します。

AWSのEC2で立てたWordPressにSSHを使って接続するには、【WordPress, AWS】ブログ右下に出るBitnamiのロゴを綺麗に消し去る方法 のnote記事でのSSH接続箇所を参考にしてみてください。

Let’s Encryptを使ってSSL化

Gitをインストール

まずGitがインストールされていなければ以下のコマンドでインストール。

$ sudo apt-get install git

yum コマンドでも良いけど、まず yum のインストールから始めないといけなかったり、 root ユーザーでないと受け付けてもらえなかったりするので、 apt-get がAWS/Bitnamiのコマンドライン上でのインストールにはおすすめ。

ディレクトリを指定 & Certbot Client リポジトリを clone する

まず以下のコマンドで tmp のディレクトリに移動。

$ cd /tmp

それから、Certbot Clientリポジトリを以下のコマンドでクローンする。

$ git clone https://github.com/certbot/certbot

これが tmp のディレクトリにクローンされていないとSSL証明書が発行されないエラーの原因にもなります。

Certbotにディレクトリを移動

$  cd certbot

で、ディレクトリを移動。

ドメインに紐づいた新しいSSL化証明書のリクエスト

$ ./certbot-auto certonly --webroot -w /opt/bitnami/apps/wordpress/htdocs/ -d DOMAIN

上記のコマンドをcertbotディレクトリで叩く。

DOMAIN はそれぞれのドメイン名に変更しましょう。

うまくいくと、証明書の期限が記述された文面が出てきます。

この時点ですでにSSL化されたURLでサイトにアクセスをするとうまくアクセスができるようになっています。

が、例えばブックマークをしてくれている人が http でアクセスすると言うのはよくあることで、実際今の状態では、わざわざ https と書いてくれない限りはSSL化された方のURLには行き着けません。

せっかく訪問してくれているブログ閲覧者の皆さんに、

今日から https でアクセスお願いします!


と、頼むのもかなりアナログで、サイト運営者にとっても、閲覧者の方にも手間ですよね。

SSL化した意味が半減と言っても過言ではないくらいの手間です。

こちらでサイト訪問者が http でアクセスをしても自動で https の方にリダイレクトをするようにほんの少しの設定をしておくだけで、お互いが快適に過ごせるので、まずはその方法も以下に紹介します。

ついでに先に書いておくと、Let’s EncryptのSSL化証明書の有効期限は90日間。

先ほどのコマンドラインでの期限表示を確認して「えっ、少なっ!」と思う人も多いはず。

これを毎回90日間のサイクルで忘れずにアップデートするのは、非常に面倒なので、自動で期限が来たら更新をするように、証明書自動更新の設定もしていきたいと思います。

その前に少し念には念を入れた設定をしていきましょう。

自分のWebサーバにLet’s Encryptの証明書をインストールする

BitnamiのApacheは、デフォルトでは ↓ に証明書を保存します。

 /opt/bitnami/apache2/conf/server.crt
 /opt/bitnami/apache2/conf/server.key

念には念を入れて、デフォルトで配置されている証明書とキーのバックアップを取っておきます。

バックアップするコマンドはこんな感じ。

 $ sudo mv /opt/bitnami/apache2/conf/server.crt /opt/bitnami/apache2/conf/server.crt.backup
$ sudo mv /opt/bitnami/apache2/conf/server.key /opt/bitnami/apache2/conf/server.key.backup

バックアップが取れたら、今度は証明書とキーファイルを適切なディレクトリで紐付け。

DOMAIN の所に、自分のドメイン名を書きます。

$ sudo ln -s /etc/letsencrypt/live/DOMAIN/fullchain.pem /opt/bitnami/apache2/conf/server.crt
$ sudo ln -s /etc/letsencrypt/live/DOMAIN/privkey.pem /opt/bitnami/apache2/conf/server.key 

上記証明書類をrootユーザーだけに読める形式に変換

次に、 root ユーザーだけが読めるよう権限を与えます。

$ sudo chown root:root /opt/bitnami/apache2/conf/server*
 $ sudo chmod 600 /opt/bitnami/apache2/conf/server* 

Apacheサーバを再起動

バックアップも取ったり、ディレクトリを変えたり、 root ユーザーだけに閲覧権限を与えたりと、色々設定をしたので、Apacheを再起動します。

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

httpsでアクセス可能に

ここでも https でアクセスできるのが確認できますね。

いよいよ自動で https にリダイレクトをさせる設定をしていきます。

httpでアクセスしてもhttpsにリダイレクトさせる

httpd-prefix.confにvimでリダイレクトの文言を追加

vim(vi)で httpd-prefix.conf ファイルに https にリダイレクトをさせる文言を書き加えます。

vimはコマンドライン上でファイルに書き加えや編集ができる機能です。

nanoが良い人はnanoでも普通にここは書けるので、慣れている方で試してもらって大丈夫です。

vimを使ってファイルを編集するには、今回編集するファイルにディレクトリを移動させながらvimを起動させます。

$ sudo vi /opt/bitnami/apps/wordpress/conf/httpd-prefix.conf

vimで編集モードになったら、以下の記述を書き加えます。

RewriteEngine On

RewriteCond %{HTTPS} !=on

RewriteRule ^/(.*) https://%{SERVER_NAME}/$1 [R,L]

全て書き加えたら Enter キーをヒットして、 esc キーからの、保存&編集モード終了の :wq を押します。

完了したらApacheをまた再起動します。

Apacheサーバを再起動

おなじみのApache再起動コマンド。

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

SSL証明書のステータスを最終確認

最後にも念には念を入れて、うまくいっているかどうかをチェック。

SSL証明書のステータスも、外部サービスを使ってチェックしましょう。

wifi速度を測るスピードメーターのようなサービスで、以下のようにURLを書いてブラウザで表示させるだけです。

以下のようなA判定が出ればOKです。

DOMAIN 箇所は自分のドメインに変換しましょう。

https://www.ssllabs.com/ssltest/analyze.html?d=DOMAIN

SSL証明書の期限を自動更新させる設定

dry-run

いよいよ、最後の作業です。

Let’s EncryptのSSL化証明書の有効期限は90日間なので、そんな面倒な更新はコマンドラインの crontab 機能で全部自動化しましょう。

まずは dry-run をさせ、更新プロセスができるかどうかのテスト。

うまくいったかどうかの結果がコマンドラインにメッセージで出ます。

 $ sudo /tmp/certbot/certbot-auto renew --dry-run

cronetabでアップデート

コマンドラインの crontab 機能でアップデートしましょう。

コマンドラインで何かを一定期間で更新したり、タスクをこなさせたりするには crontab が非常に便利です。

 $ sudo crontab -e

↑ このコマンドで crontab が起動して、エディタでどの種類を使って編集したいかを聞かれます。

nanoが簡単と勧められていますが、vimで慣れていれば3が個人的におすすめです。(vim派なので)

デフォルトではnanoになっているので、間違えてnanoになったら、nanoのコマンドラインで保存やエディタモード終了などを行えば大丈夫です。

nanoの書き方は、ググるとすぐ出てくるので割愛します。

vimかnanoで自動更新内容を追記

以下の内容を crontab のエディタモードで記入します。

30 4 * * *   /tmp/certbot/certbot-auto renew --post-hook "sudo /opt/bitnami/ctlscript.sh restart apache" >> /var/log/letsencrypt/renew.log

書いたらもちろん保存してエディタモードを終了。

ここで指示を書いた内容としては、毎朝4:30AMに証明書の更新があれば実行するコマンドが起動しますが、証明書の切れる90日目以外は実行はされません。

これで証明書の期限が切れて、SSL化が90日間だけだった、という悲劇はないですね!

この通りに取り組んで全てうまくいけば、SSL化は完了です✨

ただ、いつもうまくいくとは限らないのがやはりコマンドラインやサーバー、コード。

それがまた解決できたときは面白いのですが、解決策あってこそなので、トラブルシューティングを一部ではありますが書いておきます。

トラブルシューティング:あと一歩で証明書が出ない

私がハマったのが、1つ目はGitのクローンディレクトリが違ったということと、2つ目がドメインに紐づいたSSL証明書のリクエストコマンドで --standalone オプションで、Apacheが動作していない時に充てる方法で実行してしまっていたことです。

2つ目はApacheがなんで起動していないと思い込んだのだろうと、自分でもアホくさくなる凡ミスですが 笑

1つ目のGitインストールのディレクトリが違った分に関しては、上記チュートリアルですでに解決策があるので、そちらを参考にしてもらうとして、2つ目の --standalone オプションにしていた件については、実際のLet’s Encrypt日本語サイト(非公式)と公式の英語サイトも交えて解説していきます。

まず日本語の非公式サイトには、以下のように4つのパターンで、ドメインに紐付けさせたSSL証明書のリクエストコマンドが違ってきます。

- webサーバ(Apacheなど)が起動していて、サブドメイン名なしでリクエストする場合
- webサーバ(Apacheなど)が起動していて、サブドメインと通常ドメインの両方でリクエストする場合
- webサーバ(Apacheなど)が起動していて、複数の異なるドメインに対して1つのSSL証明書をリクエストする場合
- webサーバ(Apacheなど)が起動していない状態で、Certbot内部でドメイン認証して証明書をリクエストしたい時

基本はwebサーバが起動している場合であれば --webroot に -w を書いて、ディレクトリを書き、 -d をそれぞれドメインやサブドメイン名の前に書くのが雛形なので、Apacheが起動している状態で、起動していないときのコマンドである --standalone は、メールアドレスの記入や、サービス利用の同意を求められるところまではうまくいっても、最終的な期日付きのメッセージが表示されるはずのところでエラーが出ます。

Please see the logfiles in /var/log/letsencrypt for more details. というエラー文とともに、うまくいかなかったメッセージが出た時には、まず正しいSSL証明書リクエストコマンドになっているかを確認しましょう。

大抵の場合は、上記のようにオプションが合っていなかったり、ディレクトリが正しくなかったりします。

今回は、4つのパターンのうちの一番上の方法、サブドメインなしでトライしたチュートリアルですが、基本形は以下のようにLet’s Encrypt が採用しているCertbot公式ソースにもあります。(Apacheの場合を引用)

$ certbot certonly --webroot -w /var/www/html -d example.com

実際は、超基礎ではありますが、このcertbotのところから certbot と書いてもディレクトリに届くかはわからないので、上記のチュートリアルでは対応できるように書いています。

-w あとのディレクトリも、個人の環境によって変わるために、上記の通りに書いてもうまくはいきません。EC2でインスタンスを立てたWordPressであれば、上記チュートリアルのようにカスタマイズができるので、そこもディレクトリが違えばうまくいかない可能性もあります。

エラーが出る解決策は1つではありませんが、上記はよく間違えやすいポイントかな、と自分も引っかかったので、お役に立てれば嬉しいです。

参考ソース

以下、そのほか参考にしたソースを載せておきます。

AWS: 公式コマンドライン: https://aws.amazon.com/premiumsupport/knowledge-center/redirect-http-https-elb/

vim 編集参考:https://nkmrkisk.com/archives/1608

では、ちゅーす。

この記事が気に入ったら、サポートをしてみませんか?
気軽にクリエイターの支援と、記事のオススメができます!
ありがとうございます:) コードを書くスピードが倍になります^^
3
元エミレーツCA。ドイツ在住フルスタックエンジニア。https://aiki-developer.com/ プログラミング講師。プログラミングコース受講はTwitter/上記サイトからどうぞ。合気道好き。Podcastは、https://anchor.fm/arisa-dev
コメントを投稿するには、 ログイン または 会員登録 をする必要があります。