オレオレ証明書で WordPress 管理画面へ SSL 接続する

もふもふあげさん セキュリティ
この記事は約9分で読めます。
スポンサーリンク

セキュリティ対策の一環として、WordPress の管理画面へ暗号化接続すると決めて数週間。やっとその気になったので、諸々作業をしてみた。要件としては“自分だけが管理画面に対して https で接続できれば良い”というただ1点。

あとはおまけとして、“管理画面に http でアクセスしようとすると自動的に https へ飛ばす”ということと、“通常のコンテンツに https でアクセスが来たら http へ戻す”という挙動を実現させる。

ただ後者に関しては、証明書を持ってない人が https でエントリにアクセスすると、証明書に関するアラートが出ちゃう。まぁこれ、私のオレオレ証明書を許可していただければエントリ読めるのだけど、普通ならそれはしないと思われ。

以下、作業手順。

専用のディレクトリを作ってオレオレ証明書を発行

sudo mkdir /var/lib/nginx
sudo mkdir /var/lib/nginx/nginx-ssl
cd /var/lib/nginx/nginx-ssl

sudo openssl genrsa -out domain.key -aes256 1024
// "domain" はこれ以降適宜置き換えてください。ex. oreore.key

Generating RSA private key, 1024 bit long modulus
.....++++++
.............++++++
e is 65537 (0x10001)
Enter pass phrase for domain.key:               // パスフレーズ
Verifying - Enter pass phrase for domain.key:   // パスフレーズ再入力

sudo openssl req -new -key domain.key -out domain.csr

Enter pass phrase for domain.key:
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:JP            // 日本だよ
State or Province Name (full name) []:Tokyo     // 東京だよ
Locality Name (eg, city) [Default City]:Shibuya // 渋谷だよ
Organization Name (eg, company) [Default Company Ltd]:UCH // 適当(会社名的な)
Organizational Unit Name (eg, section) []:Web section //適当(所属部署的な)
Common Name (eg, your name or your server%27s hostname) []:your_domain
Email Address []:age.d.ullahan+blog@gmail.com

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:     //スルー
An optional company name []: //スルー

sudo openssl rsa -in domain.key -out domain.key

Enter pass phrase for domein.key:  // 先に作ったパスフレーズ入力
writing RSA key

sudo openssl x509 -req -days 3650 -in domain.csr -signkey domain.key -out domain.crt
// 自分用なので "-days 3650" として 10 年間有効にしてみた

Signature ok
subject=/C=JP/ST=Tokyo/L=Shibuya/O=UCH/OU=Web section/CN=your_domain/emailAddress=age.d.ullahan+blog@gmail.com
Getting Private key

sudo chmod 600 domain.key // 秘密鍵の権限は root だけにしちゃう

上記手順でオレオレ証明書の発行は完了。domain.key と domain.csr のパスは控えておくこと。

SSL アクセス専用の設定ファイルを作る

nginx の設定ファイルには、conf.d 以下にある .conf ファイルを読み込ませる記述があるはず。というわけで、ssl.conf というファイルを作成する。conf.d 内には example_ssl.conf というサンプルがあるけど無視した。

cd /etc/nginx/conf.d
sudo vi ssl.conf
server {
     listen       443;
     server_name  your_domain; // あなたの所持するドメイン名を

     location / {
         root /var/www/html; // ルートのパスは適宜変更
         index index.php index.html index.htm;
     }

     ssl                  on;
     ssl_certificate      /var/lib/nginx/nginx-ssl/domain.crt; // 先に控えておいたパス
     ssl_certificate_key  /var/lib/nginx/nginx-ssl/domain.key; // 先に控えておいたパス

     ssl_session_timeout  10m;

     ssl_protocols  SSLv2 SSLv3 TLSv1;
     ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;
     ssl_prefer_server_ciphers   on;

#    "wp-" で始まるディレクトリやファイル以外への https アクセスは http に飛ばす。
#    WordPress 用のディレクトリにあるなら "^/wordpress/wp-" のようにすること。

     if ($uri !~ ^/wp-) {
         rewrite ^(.*)?$ http://$host$uri last;
     }

#    root の部分を忘れると "No input file specified." というエラーが出るかも。
#    私はそれでハマった。

     location ~ \.php$ {
         root          /var/www/html; // ルートのパスは適宜変更
         fastcgi_pass  127.0.0.1:9000;
         fastcgi_index index.php;
         fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
         include       /etc/nginx/fastcgi_params;
     }
 }

本来であれば、通常のエントリ等への自身以外からのアクセスは、証明書のアラートを出さないで自動的に http へ飛ばしたいのだけど、そこがよくわかっていない。ただまぁ、これを読んで試してみる方くらいしかお目にかからないだろうから気にしないという方向に。ていうか、仕様上仕方ないかも。

ログインページおよび管理画面へのアクセスは必ず https へ飛ばす

ssl.conf での設定とは逆に、ログインページおよび管理画面へのアクセスは http だったとしても https へ飛ばす。こちらは nginx.conf 側に rewite 文を記述する。

    server {
        listen       80;
        server_name  your_domain;

        rewrite ^/wp-login.php?$ https://$host/wp-login.php last;
        rewrite ^/wp-admin/(.*)?$ https://$host/wp-admin/$1 last;

        ......

先にも書いてあるけど、WordPress 用のディレクトリがある場合は rewite 文も修正になるので注意する。

設定ファイル構文チェックと nginx の再起動

各種設定が終わったら、設定ファイルの構文をチェックして再起動する。問題があればアラートが出るのでそれを確認して修正すること。

sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

sudo /etc/init.d/nginx restart
nginx を停止中:                                            [  OK  ]
nginx を起動中:                                            [  OK  ]

作業が完了したので、まずはログインページにアクセスしてみる。怪しいオレオレ証明書であることを警告する画面になるはずなのだけど、それは「おまえを信じるおまえを信じろ」 [01] というやつで許可しましょう。あくまで自身用ですから。

なお、途中でも書いたけど “No input file specified.” という表示になる場合は PHP 関係のエラーになります。この場合は恐らく ssl.conf で記述した fastcgi あたりが怪しいので見直しましょう。

私はこれでうまくいったけど

今回の設定に関してはいろいろと調べていたのだけど、1つだけ解せないこと。それは、どこを読んでも「wp-config.php に管理画面への SSL アクセス許可を行うための記述を追加すること」という部分。私の場合、これをやるとエラーになってログイン画面が真っ白になってしまう。

現状の設定で挙動としては問題ないから良いのだけど、そうであるなら wp-config.php に対する記述というのは必要なのであろうか。ここがよくわからない。でもどこを読んでもそうしろって書いてあるんだよなぁ。もしご存知の方がおられましたら、Twitter などでこそっとご教授していただけますと狂喜乱舞します。

References[+]

References
01 天元突破グレンラガン – Wikipedia』におけるカミナの名言ですよ。
タイトルとURLをコピーしました