さくらのレンタルサーバで Let’s Encrypt を使う


追記:2017年10月17日から、さくらのレンタルサーバがコントロールパネル上で Let’s Encrypt の証明書を簡単に利用できるようになります

無料で SSL 証明書を発行できる認証局 Let’s Encrypt を使用して、さくらのレンタルサーバの Web 領域を HTTPS に対応させたメモ。

環境

前準備

Let’s Encrypt の証明書を生成する Certbot というソフトを HomeBrew を使ってインストールする必要があるが、HomeBrew が古いことと、macOSSierra にアップグレードしたことでインストールに失敗した。まずは HomeBrew の修復から始める。

ディレクトリ /usr/local の権限が my_user_name:admin でない場合、所有者の再設定を行う。

% sudo chown -R my_user_name:admin /usr/local

HomeBrew 自身とパッケージの更新を行う。

% brew update
% brew upgrade formula

ついでに古いパッケージを削除した。

% brew cleanup

証明書の発行

HomeBrew から Certbot をインストールする。

% brew install certbot

次のコマンドで suzume.cc に対する証明書を発行する。セキュリティアラートを送信するメールアドレスの入力、利用規約への同意、IP アドレス記録への同意などメッセージに応じて答える。

% sudo certbot certonly --manual -d suzume.cc

進めていくと
http://suzume.cc/.well-known/acme-challenge/SUrappQZ2Q89r3O6mcQzY339-MsHxVf
のような URL にファイルを配置するよう指示される。指示された内容のファイルを配置して Enter を押す。

すると Let’s Encrypt からその URL へアクセスがあり、認証されれば証明書が発行される。

さくらのレンタルサーバへの設定

サーバコントロールパネルから「ドメイン設定」を開く。

SSL を設定したいドメインの横にある「登録」を開く。

続いて秘密鍵をアップロードする。このとき証明書や鍵は /etc/letsencrypt/live 以下のスーパーユーザのみアクセスできるディレクトリに配置されているので、アップロードするために一時的にコピーする。

% sudo cp /etc/letsencrypt/live/suzume.cc/privkey.pem

秘密鍵をアップロードしたあと「証明書のインストール」を行う。 fullchain.pem の内容をコピーして貼り付ける。

% sudo cat /etc/letsencrypt/live/suzume.cc/fullchain.pem | pbcopy

このあと「中間証明書のインストール」を行う。 chain.pem の内容をコピーして貼り付ける。

% sudo cat /etc/letsencrypt/live/suzume.cc/chain.pem | pbcopy

そして最後にドメインの設定から SNI SSL を有効にすればよい。

HTTP→HTTPS リダイレクトの設定

さくらのレンタルサーバの場合、HTTPS で接続すると内部でプロキシが動作しているようで、通常のサーバとは設定方法が異なる。

.htaccess を使用して静的コンテンツに設定する場合、通常は RewriteCond %{HTTPS} off とするところだが、次のように記述する。

RewriteEngine On

# 指定したドメインのみに適用する
RewriteCond %{HTTP_HOST} suzume.cc

# さくらのレンタルサーバ独自の設定
RewriteCond %{ENV:HTTPS} !^on$
RewriteCond %{HTTP:X-SAKURA-FORWARDED-FOR} ^$

RewriteRule ^.*$ https://%{HTTP_HOST}%{REQUEST_URI} [R,L]

PHP でルーティングを行う場合、初めに呼ばれる index.php などに次のように記述する。

<?php
if (isset($_SERVER['HTTP_HOST'], $_SERVER['REQUEST_URI']) &&
	$_SERVER['HTTP_HOST'] === 'suzume.cc') {
	if (!isset($_SERVER['HTTP_X_SAKURA_FORWARDED_FOR'])) {
		header('Location: https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']);
	}
}