NginxにSSLを導入してWordPressを常時SSL化する




1年以上前に更新された記事です。
情報が古い可能性がありますので、注意してください。

GoogleもSSLを推奨しており、SEOにも関連するらしいので導入する。
最近、正式サービス化されたLet’s Encryptで証明書を発行する。

証明書の発行

gitのインストール

インストールしていない場合はインストールする。

$ sudo apt-get install git

Let’s Encryptクライアントのダウンロード

$ cd /opt
$ sudo git clone https://github.com/letsencrypt/letsencrypt
Cloning into 'letsencrypt'...
remote: Counting objects: 34884, done.
remote: Compressing objects: 100% (20/20), done.
remote: Total 34884 (delta 7), reused 0 (delta 0), pack-reused 34864
Receiving objects: 100% (34884/34884), 9.34 MiB | 364.00 KiB/s, done.
Resolving deltas: 100% (24788/24788), done.
Checking connectivity... done.

テスト実行

$ cd letsencrypt
$ sudo ./letsencrypt-auto --help
./letsencrypt-auto –helpを実行すると、自動的にapt-getが動きpythonなど必要なパッケージをインストールします。

無事環境が整った場合、Let’s Encryptのヘルプが表示されます。
特にエラーが出ることはないと思います。
/tmpをRAMディスクにしている場合は、32M以上使用するため容量に注意。

証明書の取得

nginxが起動している場合は停止し、443番ポートを開ける。

$ sudo service nginx stop
$ sudo ufw allow 443
$ sudo ./letsencrypt-auto certonly -a standalone -d harvestasya.com

メールアドレスを入力。
罫線が文字化けしてるけど気にせずに
lets-encrypt-1
利用規約への同意
lets-encrypt-2

以下のメッセージが出れば取得完了
IMPORTANT NOTES:
- Congratulations! Your certificate and chain have been saved at
/etc/letsencrypt/live/harvestasya.com/fullchain.pem. Your cert will
expire on 2016-07-31. To obtain a new version of the certificate in
the future, simply run Let's Encrypt again.

DH鍵交換パラメータ作成

DH鍵交換用のパラメータを作成する。15分ほどがかかる。

$ sudo openssl dhparam 2048 -out /etc/letsencrypt/live/harvestasya.com/dhparam.pem

Nginxの設定

/etc/nginx/nginx.confのコメントアウトされていたところを有効化し、取得した証明書と秘密鍵を設定する。

$ sudo vi /etc/nginx/nginx.conf
user hoge hoge;
worker_processes 4;
worker_rlimit_nofile 1024;
 
events {
    multi_accept on;
    worker_connections  1024;
}
 
http {
    include         mime.types;
    default_type    application/octet-stream;
    charset         UTF-8;
 
    server_tokens   off;
    sendfile        on;
    tcp_nopush      on;
    tcp_nodelay     on;
 
    keepalive_timeout           10;
    client_header_timeout       10;
    client_body_timeout         10;
    reset_timedout_connection   on;
    send_timeout                10;
 
    gzip                on;
    gzip_http_version   1.0;
    gzip_disable        "msie6";
    gzip_proxied        any;
    gzip_min_length     1024;
    gzip_comp_level     6;
    gzip_types          text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript text/json;
 
    root   /var/www;
    index  index.php index.html;
 
    # キャッシュが保管されるパス、キャッシュゾーン、容量を指定
    # path      キャッシュ保管場所
    # levels    サブディレクトリ階層の深さ
    # keys_zone キャッシュゾーン、メモリの割当量
    # max_size  ゾーン内に保存できるキャッシュ最大値
    # inactive  アクセスの無いキャッシュを削除するまでの期間
    proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=hvzone:4m max_size=64m inactive=1440m;
    proxy_cache      hvzone;
    proxy_cache_valid 200 404 30m;

    # 80番ポートへのアクセスは443ポートへリダイレクト
    server {
        listen 80;
        server_name harvestasya.com;
        return      301 https://$server_name$request_uri;
    }

    # プロキシサーバー
    server {
        listen 443 ssl http2 default_server;
        server_name harvestasya.com;
        
        # SSL設定
        ssl_certificate      /etc/letsencrypt/live/harvestasya.com/fullchain.pem;
        ssl_certificate_key  /etc/letsencrypt/live/harvestasya.com/privkey.pem;
        ssl_dhparam          /etc/letsencrypt/live/harvestasya.com/dhparam.pem;
        ssl_session_cache    shared:SSL:1m;
        ssl_session_timeout  5m;
        ssl_ciphers ECDHE+RSAGCM:ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:!aNULL!eNull:!EXPORT:!DES:!3DES:!MD5:!DSS;
        ssl_prefer_server_ciphers  on;
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        add_header Strict-Transport-Security 'max-age=31536000; includeSubDomains;';

        # ドットファイルへのアクセスを禁止、ログを残さない
        location ~ /\.well-known {access_log off; log_not_found off; }
        location ~ /\. {deny all; access_log off; log_not_found off; }
        
        # robots.txt へのアクセスはログを残さない
        location = /robots.txt  { access_log off; log_not_found off; }
        
        # favicon へのアクセスはログを残さない
        location = /favicon.ico { access_log off; log_not_found off; }
        
        # JavaScript CSS 画像へのアクセスはログを残さない
        location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
            expires 7d;
            log_not_found off;
        }
 
        set $do_not_cache 0;
        # .php ファイルへ直接アクセスがあるのは基本的に管理ページのみのためキャッシュしない
        if ($uri ~* "\.php$") {
            set $do_not_cache 1;
        }
 
        # POST 時はキャッシュしない
        if ($request_method = POST) {
            set $do_not_cache 1;
        }
 
        # $proxy_cache_key に任意の文字を加えることで別のキーでページをキャッシュ可能にする
        set $proxy_cache_key "$scheme://$host$request_uri";
 
        # ログイン状態またはコメントを記入したことがあれば、その情報ごとにキャッシュを分ける
        if ($http_cookie ~ "(wordpress_logged_in_|comment_author_)(.*)") {
            set $proxy_cache_key "$2::$proxy_cache_key";
        }
        
        # プロキシ
        location / {
            proxy_redirect      off;
            proxy_set_header    Host               $host;
            proxy_set_header    X-Real-IP          $remote_addr;
            proxy_set_header    X-Forwarded-Host   $host;
            proxy_set_header    X-Forwarded-Server $host;
            proxy_set_header    X-Forwarded-For    $proxy_add_x_forwarded_for;
            proxy_set_header    X-Forwarded-Proto  https;
            proxy_no_cache      $do_not_cache;
            proxy_cache_bypass  $do_not_cache;
            proxy_cache_key     $proxy_cache_key;
            proxy_pass          http://unix:/var/run/nginx.sock;
        }
    }
 
    # ウェブサーバー
    server {
        listen unix:/var/run/nginx.sock;
        server_name harvestasya.com;
 
        # blogディレクトリ配下にWordPressを設置する場合
        location /blog {
            # WordPress カスタム パーマリンク対応
            try_files $uri $uri/ /blog/index.php?q=$uri&$args;
        }
 
        # PHP-FPM 設定
        location ~ \.php$ {
            fastcgi_pass        unix:/run/php/php7.0-fpm.sock;
            fastcgi_index       index.php;
            fastcgi_param       SCRIPT_FILENAME  $document_root$fastcgi_script_name;
            fastcgi_param       HTTPS on;
            include             fastcgi_params;
            fastcgi_pass_header "X-Accel-Redirect";
            fastcgi_pass_header "X-Accel-Buffering";
            fastcgi_pass_header "X-Accel-Charset";
            fastcgi_pass_header "X-Accel-Expires";
            fastcgi_pass_header "X-Accel-Limit-Rate";
            client_max_body_size 10M;    # アップロードを10M上限に
        }
    }
}

WordPressの設定

サイトアドレスの変更

サイトアドレスをhttpsに変更する。
nginx-ssl-1

記事内のサイト内リンクの置換

記事内にあるサイト内リンクをすべてhttpsに置き換える。
プラグイン「Search Regex」を使用すると簡単にできる。
nginx-ssl-2

その他

そのほかウィジェット内にないか確認する。
すべてhttpsに変更できていれば、URLの横あたりに鍵マークが表示される。
SSLサーバーのテストはQualys SSL Reportで出来る。
https://www.ssllabs.com/ssltest/

証明書の自動更新

証明書の有効期限が3ヵ月と微妙に短いので、自動更新を設定しておく。
証明書を自動更新する場合は–renew-by-default オプションを使えばいいのだが、証明書を作成した際に使用したstandaloneオプションはWebサーバーが起動していると使用できない。
webサーバーが起動している場合は、webrootオプションを使用して更新する。もちろん、証明書を取得する際でもwebrootオプションは使用できる。

$ sudo vi /etc/cron.monthly/letsencrypt
#!/bin/sh
/opt/letsencrypt/letsencrypt-auto certonly --webroot --agree-tos -w /var/www -d harvestasya.com --renew-by-default
service nginx reload
$ sudo chmod +x /etc/cron.monthly/letsencrypt

Let’s Encryptクライアントの更新

たまに更新されるので、更新しておくといいかもしれない。

$ cd /opt/letsencrypt
$ sudo git pull https://github.com/letsencrypt/letsencrypt

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です