さくらVPSでサイトをSSL/TLS対応(CentOS 7 + Apache 2.4 + PHP 7.1)

このサイト(w0s.jp)はこれまでレンタルサーバーを借りて管理していました。

しかし、より自由にサーバーを使いたい(root権限が欲しい)こと、また Service Workers など HTTPS でないと実現できない新機能が現れてきていることから、VPSを契約してサイトを常時 SSL/TLS 化しました。

これまでの環境

§

借りていたのはアイネットディー(www.inetd.co.jp)の激安プランで、年間契約だとひと月あたりたったの270円。

Perl や PHP などのサーバーサイド言語が使えるほか、 SSH でログインしたり、 cron でプログラムを自動実行したりすることも可能です。

とくに cron はこの価格帯のサーバーだと実行間隔やプログラム数に制限がかけられていることも多いのですが、このサーバーではとくにそういうことはなさそうでした。私の場合10個以上のプログラムを登録していて、中には1分ごとに実行されるものや、処理時間の長いものが複数あったのですが、問題なく運用できていました。

速度面でもストレスを感じたことはありませんし、 SSH での root 権限が不要ならおすすめしたいサーバーです。

さくらのVPS契約

§

さくらのVPS(vps.sakura.ad.jp)を契約し、 OS は CentOS 7 を選択しました。

Apache 2.4

§

yum install httpd だと、2017年1月現在は Apache 2.4.6 がインストールされてしまいます。ちょっと古すぎますし、 HTTP/2 に未対応など機能面でも不足感があるので、最新版をインストールします。

いいタイミングで、半月ほど前に書かれたばかりのCentOS7にApache2.4最新版をyum installする(w3g.jp)というブログ記事を見つけたので、ここを参考に最新の 2.4.25 をインストールしました。

PHP 7.1

§

PHP も最新の 7.1 系をインストールします。Remiリポジトリをインストールのうえ、 PHP 7.1.1 をインストールします。

yum --enablerepo=remi-php71 install php php-devel php-dom php-gd php-intl php-mbstring php-pdo

  • 上記のとおり、 php-mbstring などいくつかのパッケージを入れています。

その後、 /etc/php.ini を開いて設定を変更します。とくに mbstring 関係はセキュリティ的にも重要なので、徳丸浩さんの記事文字コードに起因する脆弱性を防ぐ「やや安全な」php.ini設定(www.tokumaru.org)を参考に変更します。

SSL/TLS 対応

§

まずはファイアーウォールで 443 ポートを開放します。

firewall-cmd --list-all

で現状を確認したのち、開放。

firewall-cmd --permanent --add-service=https

firewall-cmd --reload

次に証明書をインストールします。証明書は無料で使える Let's Encrypt のサービスを使いますが、設定は驚くほど簡単。基本的には「Let's Encrypt 総合ポータル」サイトのLet's Encrypt の使い方(letsencrypt.jp)に書かれた手順に従って Certbot パッケージをインストールし、いくつかのコマンドを打ち込むだけ。

さらに Apache の設定を行います。今回はバーチャルホストで運用することにしたので、 /etc/httpd/conf.d/vhost.conf を設定します。

<VirtualHost *:80>
    DocumentRoot /var/www/w0s.jp
    ServerName w0s.jp
    ErrorLog "/var/www/log/error.log"
    CustomLog "|/usr/sbin/rotatelogs /var/www/log/access/%Y%m%d.log 86400 540" combined

    <Directory "/var/www/w0s.jp">
        AllowOverride All
        Require all granted
    </Directory>

    RewriteEngine on
    RewriteCond %{HTTPS} off
    RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
</VirtualHost>

<VirtualHost *:443>
    DocumentRoot /var/www/w0s.jp
    ServerName w0s.jp
    ErrorLog "/var/www/log/error.log"
    CustomLog "|/usr/sbin/rotatelogs /var/www/log/access/%Y%m%d.log 86400 540" combined

    <Directory "/var/www/w0s.jp">
        AllowOverride All
        Require all granted
    </Directory>

    SSLEngine on
    SSLCertificateFile /etc/letsencrypt/live/w0s.jp/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/w0s.jp/privkey.pem
    SSLProtocol all -SSLv2 -SSLv3
    SSLCipherSuite HIGH:MEDIUM:!aNULL:!MD5:!RC4
    SSLHonorCipherOrder On
    Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
</VirtualHost>

<VirtualHost *:443> の中で SSLEngine on にしたうえで、SSLCertificateFileSSLCertificateKeyFile でサーバー証明書と秘密鍵のファイルを指定します。

SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/w0s.jp/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/w0s.jp/privkey.pem

とりあえずこの3つの設定で https 接続が可能になりますが、IPAが公開しているSSL/TLS暗号設定ガイドライン(www.ipa.go.jp)の「Appendix B:サーバ設定編」を参考に、さらにセキュリティを高める設定変更をします。

デフォルト設定だとRC4暗号が有効になっていましたが、RFC 7465(tools.ietf.org)RC4 can no longer be seen as providing a sufficient level of security for TLS sessions.(tools.ietf.org)と書かれているように、TLSでの使用が禁止されているので、無効にします。具体的には、 /etc/httpd/conf.d/ssl.conf から SSLCipherSuite の記述をコピペして、末尾に :!RC4 を追記します。

SSLCipherSuite HIGH:MEDIUM:!aNULL:!MD5:!RC4

次に、暗号スイートの選択をデフォルトのクライアント側からサーバー側で行うようにします。

SSLHonorCipherOrder On

さらに HSTS を設定します。有効期限は365日(31536000秒)を指定。

Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"

ここまで設定すると、 Qualys SSL Labs によるSSL Server Test(www.ssllabs.com)の測定で A+ 判定が取れました。

サムネイル画像
SSL Server Test の測定結果(A+)オリジナル画像

なお、アクセスログは /usr/sbin/rotatelogs を使って日ごとにファイルを分割して保存するようにしています。

最後に、 Let's Encrypt の証明書は有効期間が90日なので、自動更新の設定をします。

certbot renew --pre-hook "systemctl stop httpd.service" --post-hook "systemctl start httpd.service"

コマンドオプション --pre-hook と --post-hook は、証明書を更新する時に Apache が停止している必要があるための指定ですが、

The hooks will only be run if a certificate is due for renewal, so you can run this command frequently without unnecessarily stopping your webserver.

User Guide — Certbot 0.10.0.dev0 documentation(certbot.eff.org)

とあるように、 Apache の再起動は証明書が更新されるときのみ行われるので、このコマンド自体は頻繁に実行しても問題ありません。

これを cron に設定。 root 権限が必要なので、 sudo ctontab から1日1回実行されるようにしました。

サイト改修

§

HTTPS 化のため、サイトの中で自サイトの URL を http: から始まる絶対パスで表記している部分は置換します。OGP とフィード(RSS/Atom)関係で数か所の置換が必要でした。

また、他社サービスのコンテンツを埋め込んでいるものについては、 YouTube や Twitter はとうの昔に HTTPS 対応が行われており、 Amazon のProduct Advertising API(affiliate.amazon.co.jp)を使って取得した商品画像も、2016年12月19日にようやく HTTPS 化が行われたので問題ありません。

ただ、 pixiv の埋め込みスクリプトは HTTPS に対応しておらず、代替案も思いつかないので(APIが公開されていないため)、残念ながら埋め込みを止めて <a href> によるリンクに変更しました。

ドメイン設定

§

ネームサーバ利用申請方法 – さくらのサポート情報(help.sakura.ad.jp)の手順に従い、ネームサーバの設定を行います。

次に、レジストラサービスの管理画面からネームサーバーをこれまで使っていたものから変更します。

ネームサーバー1
ns1.dns.ne.jp
ネームサーバー2
ns2.dns.ne.jp

ここまでやったら座して切り替わるのを待つだけ。

切り替え後

§

  • Google ウェブマスター(www.google.com)は http: と https: を区別するらしいので、 https: の URL を登録
  • 外部サービスに登録してある URL を変更