アンテナメニュー開閉
←前の記事 次の記事→

【SSL導入】高速で強力なWordPressサイトを構築する6

より安全性の高いSSL(TLS)環境を構築する。

【SSL導入】高速で強力なWordPressサイトを構築する6
高い安全性を持ったSSL(TLS)の設定。(American Advisors Group)

SSL(TLS)を使用し、通信を暗号化する

前回の記事ではより高度な画像圧縮方法をご紹介しました。

今回の記事では通信の暗号化という高速化とは少し異なる方面を扱います。

しかし、今回扱う暗号化では高速化も兼ね備えた内容となっているため、ウェブサイトをSSL(TLS)化させたい方にとっては役に立つ内容かもしれません。

また、通常の暗号化よりも更に高度な暗号化(SSL LABSでA+)の設定方法も記述しています。

なお、サンプルには無料でウェブサイトの暗号化を行えるツールである『Lets Encrypt』を使用します。

(本文前に)簡単な3行まとめ

  • ウェブサイトをSSL(TLS)化する手順を紹介。
  • HTTP/2化することで暗号化以外に高速化も可能。
  • Lets Encryptならば無料で暗号化可能。

記事目次

SSL(TLS)とは

SSL(TLS)はSecure Sockets LayerあるいはTransport Layer Securityを意味したもので、どちらもコンピューターネットワークの暗号化規格を表しています。

通常の通信では簡単に相手の通信内容を盗み取られてしまいますが、暗号化を行うことにより通信内容を保護することが出来ます。

そのため、オンラインショップなどはじめ個人情報を取り扱うサイトでは暗号化は必須になっており、逆に保護されていないサイトは非常に危険です。

他にも暗号化することでウェブサイトの改竄も防ぐことが出来るため、通常のサイトでも暗号化することが望ましくなっています。

ちなみに、もともとはSSLが主流でしたが、脆弱性によりSSLの使用は非推奨となり、現在ではTLSが最新となっています。

また、多くのサイトではSSLとTLSを同時表記していますが、これは認知度や統一時の混乱等を考慮しているためです。

暗号化による利点

我々の通信を守ってくれるSSL(TLS)ですが、暗号化を行う場合これまでは『速度遅延』『コスト』『導入の手間』などが問題となっていました。

これらは導入する際に立ちはだかる大きな壁となり、暗号化を遠ざける主な要因の一つでした。

しかし、現在ではそれら壁のほとんどは解消しており、手軽に暗号化を施すことが出来るようになっています。

速度遅延

まず、ウェブサイトに暗号化を施すと通常よりも余分な通信が増えます。

そのため、通信が遅くなってしまうと考えている人は多いでしょう。

確かに通常よりも通信数は増大しますが、現在はHTTP/2という新たな規格の登場により、遅くなるというよりかはむしろ高速化に繋がる可能性も十分に考えられます。

その例としてhttps://www.httpvshttps.com/というサイトではHTTP2化することによる高速化を検証しています。

このテストでも証明されているように、従来の暗号化では遅延が目立っていたものが現在では大幅に解消されているため、SSL(TLS)を導入するという選択肢はこれまで以上に選びやすくなっているでしょう。

コスト

これも今までに暗号化を行う際に障壁となっていた点です。

暗号化には低価格から結構な金額がかかる証明書が存在していますが、これら証明書は全て期限が存在しており、いつかは更新しなければなりません。

例え低価格でも毎回証明書を更新すると、やはりある程度はお金が必要となってきます。

しかし、最近になって様々な技術団体が開発した『Lets Encrypt』の登場により、その壁は完全に取り払われることとなりました。

Lets Encryptは完全無料で使用出来るツールなので、SSL(TLS)化を目指すユーザーにとって非常に心強いパートナーとなっています。

導入の手間

前述の通りLets Encryptは無料で使用出来るツールですが、実はそれ以前にもStartSSLという所でも無料で暗号化が出来ました。

ただ、ややこしい部分など、人によっては少々面倒だと思われる点があり、更に簡単には出来ないものかと思う人は多かったかもしれません。

ここでもLets Ecnryptがその問題を解消しており、認証から暗号化ファイルの設定など、暗号化を行う際の面倒なポイントを易しくして導入を更に簡単なものとしています。

可能であれば暗号化すべき

長年運営しているために記事が大量にあるなどのウェブサイトでは、URLの置き換えなどで膨大な手間がかかってしまうため、その場合にはSSL(TLS)化に躊躇してしまうでしょう。

しかし、そうではないならば導入することのメリットはデメリットを上回っているため、暗号化を施すことをおすすめします。

また、GoogleはSSL(TLS)化したサイトをランキング指標の一つとして採用することを宣言しており、検索エンジンの最適化を意味するSearch Engine Optimization(SEO)上でもメリットがあります。

SSL(TLS)化するだけでランキングが大きく変わるわけではありませんが、導入していて損はないでしょう。

なお、下記のページではSSL(TLS)化に関する疑問について分かりやすくまとめられているので、一読しておくことをおすすめします。

HTTPSにまつわる怪しい伝説を検証する – Google I/O 2016のセッションから
http://qiita.com/takoratta/items/5bfe926a6421a14c1f94

他にもLets Encryptには日本語で解説を行っている総合ポータルサイトが存在しているため、こちらも併せて読むことを推奨します。

また、導入に関しても下記の方がより詳しく載っていますので、十分な情報が欲しい場合は読んでおきましょう。

Let’s Encrypt 総合ポータル
https://letsencrypt.jp/

少し前置きが長くなりましたが、次の項目からLets Encryptによる暗号化方法、そしてSSL(TLS)のパフォーマンスを向上させる設定を説明していきます。

Lets Encryptの導入

SSL(TLS)にはポート443の解放が必須となっているため、UFWのポートを解放します。

$ sudo ufw allow 443

UFWを再起動して設定を反映させます。

$ sudo service ufw restart

gitをインストールしていない場合はここでインストールしておきます。

$ sudo apt-get update
$ sudo apt-get install -y git

nginxディレクトリ内にsslディレクトリを作成します。

$ sudo mkdir /etc/nginx/ssl

sslディレクトリに移動し、Certbotをインストールします(仕様変更によりletsencrypt-autoは旧型になりました)。

$ cd /etc/nginx/ssl
$ sudo git clone https://github.com/certbot/certbot

certbotディレクトリに移動し、certbot-autoを実行して必要ファイルのインストールを行います。

$ cd certbot/
$ ./certbot-auto

ウェブサイトの認証

次にウェブサイト認証を行いますが、ウェブサーバを停止する方法停止しない方法の2つがあります。

手軽でおすすめなのは停止しない方法です。

ウェブサーバを停止して認証する場合。

-dの後のexample.comは自サイトのドメインを入力して下さい

なお、www有り無しは自由です。どちらかを削除しても構いませんし、どちらも欲しい場合は両方利用してもOKです。

また、認証開始時には利用規約の同意および通知用メールアドレスの記入を求められます。

$ sudo service nginx stop
$ ./certbot-auto certonly --standalone -d example.com -d www.example.com
$ sudo service nginx start

ウェブサーバ稼働中に認証する場合。

こちらもwww有り無しは自由です。

$ ./certbot-auto certonly --webroot --webroot-path /var/www/example.com/ -d example.com -d www.example.com

ファイルの場所(実体)

全て完了すると自動的にサーバ証明書(公開鍵)と中間証明書、そしてサーバ証明書と中間証明書が結合されたファイルおよび秘密鍵が作成されます。

以下はLets Encryptによって作成された実体(元ファイル)となるファイルの場所を表しています。

サーバ証明書(公開鍵)の場所は『/etc/letsencrypt/archive/ドメイン名/cert.pem』です。

中間証明書の場所は『/etc/letsencrypt/archive/ドメイン名/chain.pem』です。

サーバ証明書と中間証明書が結合されたファイルの場所は『/etc/letsencrypt/archive/ドメイン名/fullchain.pem』です。

最後に秘密鍵の場所は『/etc/letsencrypt/archive/ドメイン名/privkey.pem』です。

ちなみに、それぞれのファイルは拡張子の前に証明書の発行回数を表す番号が付与されます(例:5回目であればcert5.pem)。

なお、これらファイルにはシンボリックリンクも提供されており『/etc/letsencrypt/live/ドメイン名/種類名.pem』というようにliveディレクトリ以下にそれぞれが関連付けされています。

ファイルの場所(シンボリックリンク)

証明書の更新時に発行回数が付与される仕様から、シンボリックリンクの場所を設定ファイルに記入しておくと更新の際に必要となる変更の手間が省けます。

サーバ証明書(公開鍵)『/etc/letsencrypt/live/ドメイン名/cert.pem

中間証明書『/etc/letsencrypt/live/ドメイン名/chain.pem

結合されたファイル『/etc/letsencrypt/live/ドメイン名/fullchain.pem

秘密鍵『/etc/letsencrypt/archive/ドメイン名/privkey.pem

自動で証明書の更新を行う

最初の証明書取得は手動による更新でしたが、毎回これを行うのは非常に面倒です。

そのため、コマンドの定期実行スケジュールを管理しているcrontabを使って自動で証明書の更新を行えるように設定します。

$ sudo vim /etc/crontab

exampleの部分やwwwの有り無しは適宜変更して下さい。

更新方法は好きな方を選択して下さい。

crontab
# 毎月1日の05:01に証明書の更新を自動で行う(ウェブサーバを停止させない更新)
1 5     1 * *   root    /etc/nginx/ssl/certbot/certbot-auto certonly --webroot --renew-by-default -w /var/www/example.com/ -d example.com -d www.example.com && sudo service nginx reload

# 毎月1日の05:01に証明書の更新を自動で行う(ウェブサーバを停止させて更新)
# 1 5     1 * *   root    sudo service nginx stop && /etc/nginx/ssl/certbot/certbot-auto certonly -a standalone --renew-by-default -d example.com -d www.example.com && sudo service nginx start

暗号鍵とチケットを作成する

証明書を作成した後はnginxの設定ファイルを編集するだけですが、より良い暗号化環境を実現するためにDH鍵共有(ディフィー・ヘルマン鍵共有)暗号鍵とSSL(TLS) Session Ticketsを作成します。

まずはDHパラメータの暗号鍵を2048ビットで作成します。

$ cd /etc/nginx/ssl
$ sudo openssl dhparam 2048 -out dhparam.pem

次に同じディレクトリ内(/etc/nginx/ssl)でチケットを作成します。

$ sudo su -
# cd /etc/nginx/ssl
# openssl rand 48 > ticket.key
# exit

$ sudo chmod 400 dhparam.pem ticket.key

Nginxの設定ファイル編集

ほとんどの設定は整いましたので、次にNginxの設定ファイルを編集します。

exampleは現在使用している名前に変更して下さい。

$ sudo vim /etc/nginx/conf.d/example.conf
example.conf
server {
	# httpで接続して来たユーザーを強制的にhttps転送(301リダイレクト)。
	listen 80;
	server_name example.com;
	return 301 https://www.example.com$request_uri;
}

server {
#	listen       80; # 443を使用するのでコメントアウト。
	listen 443 ssl http2; # SSL(TLS)を有効化し、更にHTTP/2も有効化。
# 2017 3/1追記:OpenSSLを最新版にしてALPNが有効化されていないとhttp2が無効化される模様。
# Nginxを再ビルド、あるいはUbuntuのバージョンを16.04以上を使うなどの必要があります。

# SSL SETTINGS

	ssl on;
	ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
	ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
	ssl_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem;
	ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
	ssl_ciphers 'kEECDH+ECDSA+AES128 kEECDH+ECDSA+AES256 kEECDH+AES128 kEECDH+AES256 kEDH+AES128 kEDH+AES256 DES-CBC3-SHA +SHA !aNULL !LOW !kECDH !DSS !MD5 !WXP !PSK !SRP !CAMELLIA !SEED';
	ssl_prefer_server_ciphers on;
	ssl_dhparam /etc/nginx/ssl/dhparam.pem;
	ssl_stapling on;
	ssl_stapling_verify on;
	resolver 8.8.8.8 8.8.4.4 valid=300s;
	resolver_timeout 5s;
	ssl_session_tickets on;
	ssl_session_ticket_key /etc/nginx/ssl/ticket.key;
	ssl_session_cache builtin:1000 shared:SSL:10m;
	ssl_session_timeout 5m;

	# add_header Strict-Transport-Security 'max-age=315350000; includeSubDomains; preload';

#/ SSL SETTINGS

次にSSL SETTINGS内の項目を簡単に解説します。

なお、http://nginx.org/en/docs/http/ngx_http_ssl_module.htmlではNginxがSSL(TLS)に使用する項目が解説されています。

ssl on

sslではSSL(TLS)の有無を設定します。

offにすることでSSL(TLS)を無効化します。

ssl_certificate

ssl_certificateではサーバ証明書と中間証明書が結合されたファイルを設定します。

ここでは『/etc/letsencrypt/live/ドメイン名/fullchain.pem』を設定しています。

ssl_certificate_key

ssl_certificate_keyでは秘密鍵のファイルを設定します。

ここでは『/etc/letsencrypt/live/ドメイン名/privkey.pem』を設定しています。

ssl_trusted_certificate

ssl_trusted_certificateでは中間証明書のファイルを設定します。

ここでは『/etc/letsencrypt/live/ドメイン名/chain.pem』を設定しています。

ssl_protocols

ssl_protocolsではSSL(TLS)に使用するプロトコルを設定します。

ここでは『TLSv1 TLSv1.1 TLSv1.2』を設定しています。

SSLは脆弱性があるため設定していません。

ssl_ciphers

ssl_ciphersでは暗号の組み合わせ(Cipher suite)を設定します。

ここでは『‘kEECDH+ECDSA+AES128 kEECDH+ECDSA+AES256 kEECDH+AES128 kEECDH+AES256 kEDH+AES128 kEDH+AES256 DES-CBC3-SHA +SHA !aNULL !LOW !kECDH !DSS !MD5 !WXP !PSK !SRP !CAMELLIA !SEED’』を設定しています。

ssl_prefer_server_ciphers

ssl_prefer_server_ciphersでは暗号の組み合わせをサーバ優先あるいはクライアント優先にするかどうかを設定します。

ここでは『on』を設定しており、サーバ側を優先しています。

offにしている場合はクライアント優先になりますが、その場合は弱い暗号化の組み合わせが使用されるおそれがあります。

ssl_dhparam

ssl_dhparamではDH鍵共有に使用するファイルを設定します。

ここでは『/etc/nginx/ssl/dhparam.pem』を設定しています。

ssl_stapling

ssl_staplingではOnline Certificate Status Protocol(OCSP) Staplingの有無を設定します。

ここでは『on』を設定しており、有効化しています。

有効化することにより証明書の失効確認をサーバ側で行うため、レスポンスが良くなります。

ただし、使用するにはresolverディレクティブも設定する必要があります。

ssl_stapling_verify

ssl_stapling_verifyでは(OCSP) Staplingの有無を設定します。

ここでは『on』を設定しており、有効化しています。

この項目はssl_staplingの子項目となっています。

resolver

resolverではOCSPの名前解決に使用されるDNSサーバを設定します。

ここでは『8.8.8.8 8.8.4.4 valid=300s』を設定しています。

resolver_timeout

resolver_timeoutではresolverの名前解決タイムアウト時間を設定します。

ここでは『5s』を設定しています。

ssl_session_tickets

ssl_session_ticketsではSSL(TLS) Session Ticketsの有無を設定します。

ここでは『on』を設定しています。

ssl_session_ticket_key

ssl_session_ticket_keyではSSL(TLS) Session Ticketsに使用するチケットを設定します。

ここでは『/etc/nginx/ssl/ticket.key』を設定しています。

ssl_session_cache

ssl_session_cacheでは接続パラメータを格納するキャッシュの種類とサイズを設定します。

ここでは『builtin:1000 shared:SSL:10m』を設定しています。

ssl_session_timeout

ssl_session_timeoutでは接続パラメータのキャッシュを再利用出来る時間を設定します。

ここでは『5m』を設定しています。

add_header Strict-Transport-Security

add_headerStrict-Transport-Securityでは、レスポンスヘッダにStrict Transport Security(HSTS)を付与します。

HSTSはクライアントにいかなる場合でもHTTPSでサイトに接続することを要求します。

これにより、クライアントがHTTPで接続した場合でも強制的にHTTPSに変換を行います。

ここでは『'max-age=315350000; includeSubDomains; preload'』を設定しています。

この設定ではサイトのサブドメインも全て含め、クライアントに1年間要求をキャッシュさせます。

更にプリロード(preload)を設定することで初回接続からHTTPSで接続するようになります。

ただしプリロードは事前申請の必要がありhttps://hstspreload.appspot.com/にて登録を行わなければなりません(無料)。

また、テスト段階などで完全にHTTPSへ移行していない場合に有効化してしまうと弊害が生じます(HTTPで接続できなくなるため)ので、設定例ではコメントアウトしています。

WordPressでのHTTPS設定

Nginxでの設定は完了ですが、WordPressを使用している場合にはNginxを再起動する前にこちらでも設定を行わなければ正常に接続出来ません。

ただ、設定は簡単でWordPress内の『設定』→『一般』から『WordPress アドレス (URL) 』および『サイトアドレス (URL)』をhttpsに変更するだけです。

また、PHPMyAdmin内のWordPressデータベース(例ではドメイン名)からoption_name『home』および『siteurl』のデータをhttpsに変更してもOKです。

全ての設定が完了後、Nginxを再起動するとHTTPSでの接続が出来るようになっています。

なおHTTP状態でのキャッシュが残っている場合はリダイレクトループが発生するため、必ず削除しておきましょう(FastCGI Cacheも含む)。

設定後の暗号化状態確認

以上の設定を全て終えた後はSSL LABSのSSLサーバテストでSSL(TLS)の安全度を確認します。

当サイトでは以下の評価となっていましたが、全て正しく設定出来ていれば他のサイトでも同様の評価を得ることが可能です。

なお、HSTSがオンになっていない場合はワンランク下がってAとなってしまうので注意。

SSL LABSでのチェック結果。最高評価のA+となっている。
SSL LABSでのチェック結果。最高評価のA+となっている。

今回はA+となっていますが、現在の評価が高かったとしてもセキュリティ効果が永久に発揮される事は100%有り得ません

今日の評価が最高評価だとしても、脅威のある脆弱性が発見された場合には最低評価になっている可能性も十分考えられます。

ネットワークセキュリティの世界は日々変化していますので、定期的に診断を行って常に状態を知っておくことが非常に大切です。

次回はWEBとDBの分離、静的プロキシキャッシュサーバの構築を紹介

次回はウェブサーバとデータベースサーバの分離および、静的ファイル(JPG等)を配信するプロキシキャッシュサーバの構築方法を扱います。

より専門的な内容となるかもしれませんが、導入することで更にパフォーマンスが上昇します。

なお、公開された関連記事は以下より閲覧することが可能です。

シリーズ目次

記事内でのサンプルは『さくらVPS4G・Ubuntu14.04・Nginx・PHP7・MariaDB・Wordpress・+α』となっています。

記事の執筆時、参考となった情報はここのtxtで公開しています。

暗号通貨アドレス

寄付されたコインはサイト運営やコミュニティの発展のために使用されます。

Bitcoin:1NEh5GY6GyY3NZ3bY4ZUtu1CWhRcGhErwc

NEM:NDBEQJ-7XIF6P-46AST5-2JQVLP-JIJS43-VOY5L7-LWA5

アンテナサービス運営中

当サイトでは現在アンテナサービス(プリズムアンテナ)を運営しています。

様々なジャンルのサイト(200以上)を取り扱っているので、よろしければ暇つぶしにどうぞご利用下さい。

アンテナのジャンルについては『アンテナについて』をご覧下さい。