Nginxをインストール

Webサーバーをインストール?Apache入ってますよね!?という話になりますが、はい確かにApache httpdが初めっからインストールされています。

しかし、当方はhttpdではなくMade in RussiaのNginxというWebサーバーを使いたいと思います。確固たるこだわりがあるわけではないですが、最近シェアを伸ばしてきているのと、大量アクセスを捌く能力が高いのと、柔軟な設定ができるなどのメリットがあるのでNginxをWebサーバーとして使います。

では早速インストール+初期設定を行います。

# デフォルトではyumでインストールできないのでまずリポジトリを登録
rpm -ivh http://nginx.org/packages/centos/6/noarch/RPMS/nginx-release-centos-6-0.el6.ngx.noarch.rpm

# インストール
yum install nginx

# インストール確認ついでにバージョン確認
nginx -v
nginx version: nginx/1.8.1

# httpdを停止。お疲れさんです(_´Д`)ノ
service httpd stop

# 以後、httpd自動起動しないように設定
chkconfig httpd off

# nginxをスタート
service nginx start

# 以後、Nginxが自動起動するよう設定
chkconfig nginx on

これで、再起動しても次回からはhttpdの代わりにnginxが起動します。

ブラウザからアクセスしてNginxのデフォルトページが表示されればOKです。

nginx

 

Webサーバーは主にWordPressを動かすために使う予定です。そのためには別途設定が必要なので後ほどNginxの設定を行います。

 

WordPressを設置

まずWordPressに必要な環境を準備しなくてはいけません。WordPressに必要なのはWebサーバー・PHP・MySQLの3つです。

WebサーバーはNginxをインストール済みなのでクリア、ただPHPとMySQLは今回のServersManシンプルセットVPSには入ってません。なので新規インストールします。

 

必要なものを準備

WordPressの設置に必要なものを一括でインストールしてしまいます。

yum install mysql-server php php-mysql php-fpm php-mbstring

mysql-serverはMySQL本体です。phpもPHPの実行環境本体です。php-mysqlはPHPからMySQLにアクセスするためのDBコネクターみたいなものです。php-fpmは効率的にPHPを動作させる仕組みです。php-fpmは必須ではないですがあるに越したことはありません (`・ω・´)b

php-mbstringはPHPでマルチバイトつまり日本語を使うために必要な追加パッケージです。

これで必要な道具立ては整いましたので、MySQLやNginxの設定を行います。

 

MySQL設定とDB作成

MySQLを自動起動する設定を行います。

# 自動起動設定
chkconfig on mysql

# 起動
service mysqld start

# MySQLのセキュアな初期設定を行う
mysql_secure_installation

・・・メッセージ省略・・・
Enter current password for root (enter for none): ← 空エンター
OK, successfully used password, moving on...

Set root password? [Y/n] y
New password: ******** ※rootパスワード
Re-enter new password: ******** ※rootパスワード確認
Password updated successfully!

#anonymousユーザーを削除
Remove anonymous users? [Y/n] y
 ... Success!

#rootログインを localhost に制限
Disallow root login remotely? [Y/n] y
 ... Success!

# test データベースの削除
Remove test database and access to it? [Y/n] y
 - Dropping test database...
 ... Success!
 - Removing privileges on test database...
 ... Success!

# 権限変更の反映
Reload privilege tables now? [Y/n] y
 ... Success!

All done!  If you've completed all of the above steps, your MySQL
installation should now be secure.

Thanks for using MySQL!

これで、MySQLにはローカルのrootユーザーからのみアクセス及び設定できるようになりました。

次にWordPress用のデータベースを作成します。

mysql -u root -p
Enter password: <設定したパスワード>

# MySQL上にデータベースwpを作成
mysql> create database wp;
Query OK, 1 row affected (0.02 sec)

# 作成したDB「wp」のユーザ名「wpadmin」パスワード「xxx」とし全権限を与える
mysql> grant all privileges on wp.* to wpadmin@localhost identified by 'xxx';
Query OK, 0 rows affected (0.01 sec)

mysql> q
Bye

 

http://qiita.com/bird_nitryn/items/6d7e6a33b3eca7af5c76

 

php-mbstringの設定

php-mbstringがないと、日本語でのWordPress利用に不具合が生じるため必須のパッケージです。

下記サイトを参考にしてphp.iniを修正しましょう。ここでの説明は省きます!

日本語環境の設定 – mbstring

php-fpmの設定

php-fpm(php FastCGI Process Manager)は、PHP用のFastCGI実装といえます。ではFastCGIとは何か?といいますと、CGIをより効率的にオーバーヘッドを少なく実行するための仕組みです。CGIはWebサーバー上で動的にHTMLを生成するための仕組みでしたね。

何はともあれ入れといたほうが良いってことです。

まず、php-fpmのデフォルトユーザーとグループはapacheになってるのでnginxに変更します。

> vim /etc/php-fpm.d/www.conf

;user = apache から nginx に変更
user = nginx

;group = apache から nginx に変更
group = nginx

後は自動起動設定と起動するだけですので簡単ですね。

> chkconfig php-fpm on
> service php-fpm start
Starting php-fpm:                                          [  OK  ]

> netstat -tan | grep 9000
tcp        0      0 127.0.0.1:9000              0.0.0.0:*                   LISTEN

見てみるとphp-fpmは9000番ポートで待ち受けていることが分かります。

 

 

Nginxの基本設定

まずは基本部分の設定を行います。基本設定は/etc/nginx/nginx.confから行います。以下では、修正および追加部分だけ記述しておりデフォルト部分は省略しています。

# サーバーのCPUコア数に合わせるのが良策
worker_processes 2;
http {
    # なるべく少ないパケット数にまとめる
    tcp_nopush on;

    # HTTPヘッダからNginxバージョン情報を隠蔽する
    server_tokens off;

    # gzipをオンにしてネットワーク帯域を節約する
    gzip on;

    # サーバー/クライアント間にキャッシュサーバある場合はONにする
    gzip_vary on;

    # 圧縮対象を指定する ※適宜設定
    gzip_types text/plain
               text/xml
               text/css
               text/javascript
               application/xml
               application/javascript
               application/x-javascript
               application/x-httpd-php;
}

CPUコア数はnprocコマンドで確認できます。今回のVPSは2コアなので2とします。

gzipをオンにすることでクライアントへの送信データを圧縮してまとめるため、ネットワーク帯域を節約できますが代わりに圧縮処理に伴いCPUを消費します。なのでサーバースペックに応じて臨機応変に設定します。

あとは適当にサーバー環境に合わせて設定しましょう。これらの設定はNginxのレスポンスを向上させたりするための設定なので、未設定でも特に支障はありません。

Nginxをvimでハイライトする

ちなみに、デフォルトのvimではNginxの設定ファイルはハイライトされませんので可読性がよろしくないです。なので今後のためにもハイライト表示させるための設定を行いましょう。

http://www.vim.org/scripts/script.php?script_id=1886 から最新verのリンクを確認してwgetでダウンロードします。

# 最新版といっても、現時点で3年ほど前ですね・・・
> wget http://www.vim.org/scripts/download_script.php?src_id=19394 -O nginx.vim

# ファイルをvim syntax 用のディレクトリに移す
> mv nginx.vim /usr/share/vim/vim74/syntax/

# vimrc にシンタックスを有効にする設定を追記
> vim /etc/vimrc

au BufRead,BufNewFile /etc/nginx/* set ft=nginx

※上記は全ユーザー共通設定です。個別設定したい場合は各ユーザーの.vimrcなどに設定します。

 

NginxのWordPress用の設定

WordPressはPHPで動作しますが、デフォルトのNginxの設定ではPHPは動かず、結果WordPressを乗せることはできません。なのでWordPress用の設定を行っていきます。

基本設定は/etc/nginx/nginx.confから行いましたが、個々の設定は/etc/nginx/conf.d/内の設定ファイルにて行います。デフォルト設定はdefault.confというファイルに書かれています。

直接編集するのはアレなので、とりあえずdefault.confをwordpress.confとかにコピーします。そしてwordpress.confのほうを編集していきます。

> cd /etc/nginx/conf.d
> cp default.conf wordpress.conf

# default.confを読み込まれないようリネーム
> mv default.conf default.conf.bak

> vim wordpress.conf

server {
    
    listen 80 default_server;
    # $hostnameは「hostname -v」コマンドの結果と同値
    server_name  $hostname;
    
    # アップロード上限を15MBに設定 ※WP側の上限は2MBなんだけど・・・
    client_max_body_size 15m;
    # ドキュメントルートを指定
    root /usr/share/nginx/wordpress;

    # インデックスページパターン
    index index.php;
    #charset koi8-r; さすがはロシア製ですね
    charset utf-8;
  
    # アクセスログとエラーログをとる
    access_log  /var/log/nginx/wordpress.access.log main;
    error_log   /var/log/nginx/wordpress.error.log;

    # redirect server error pages to the static page /50x.html
    # サーバーエラーの場合は固定ページにリダイレクト
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root /usr/share/nginx/html;
    }

    # 上記以外の全リクエストはこのディレクティブに入る
    location / {
        # try_files は内部リダイレクトを使用している
        # http://domain.com/xxx
        # xxxファイルを探す ↓ない
        # xxx/ ディレクトリから index.php?$args を探す ↓ない
        # xxx/ ディレクトリから index.php?q=$uri&$args を探す
        try_files $uri $uri/ /index.php?$args /index.php?q=$uri&$args;
    }
    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
    location ~ .php$ {
        fastcgi_split_path_info ^(.+.php)(/.+)$;
        fastcgi_pass   127.0.0.1:9000;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include        fastcgi_params;
    }
}

先頭にlisten 80 default_serverとあります。listen 80は想像が付くと思いますので省略。default_serverというのは、サーバへのリクエストのホスト部分がserver_nameのどれにも該当しない場合に選択されるサーバであることを指定しています。例えば、IPアドレスで直接サイトにアクセスした場合はserver_nameにIPアドレスを定義していないので、このdefault_server指定のあるバーチャルホストの設定が使われます。

location~ほにゃららというブロックはlocationディレクティブといいます。簡単に言うと、クライアント要求をマッチさせる条件とその処理内容を表しています。条件には正規表現や完全一致、前方一致など色々ありそれぞれ優先順位もあります。

優先順位は基本的に次のようになりますが、ここでは書ききれないので Nginxでlocationの判定方法と優先順位を調べる に詳しいです。

以降処理終了  = 完全一致, ^~ 前方一致

処理継続優先高 ~ 正規表現, ~* 正規表現(大小文字区別無し)

処理継続優先低 /hoge 前方一致と類似だが処理を継続 / 全てに一致だが他のルール優先される

大体こんな感じの設定でOKですね。これでとりあえずWordPressは動くはずです。余裕があれば、ページキャッシュなどパフォーマンスを上げる設定を追記するのもアリでしょう。

Nginxの設定はかなり色々なことが出来るので、後々カスタマイズしていく予定です。

 

~ 2016/4/18追記 ~

アクセス制限などの設定を別ファイルとして記述します。別ファイルで定義するのは、今後管理するWebサーバー数やバーチャルホストが増えた場合、再利用できるからです。

> vim /etc/nginx/drop

#
# アクセスログを取らないもの
#
### ファビコンや検索ロボット用のテキストはログを無効に設定
location ~* ^/(favicon.ico|robots.txt)$ {
 access_log off;
 log_not_found off;
 break;
}

#
# アクセス制限をし403コードを返すもの ※多分403コードを返す
#
### .* 隠しファイルや wp-config.php にマッチ
location ~* ^/(\..*|wp-(config|blog-header)\.php)$ {
 deny all;
 access_log off;
 log_not_found off;
}

#
# 404コード(Not Found)を返すようにするもの
#
### readme.txt や readme.html readme-hoge.txtなどにマッチ
location ~* ^/(.*\.(cache|sql|log)|(license|readme|readme-[^\.]+)\.(txt|html?))$ {
 access_log off;
 log_not_found off;
 return 404;
}

こちらはキャッシュ関係の設定です。同じく別ファイルとして定義します。

> vim /etc/nginx/expires

#
# 各ファイルのキャッシュ設定(保持期間など)
#
location ~* \.(js|css|html?|xml|gz|jpe?g|gif|png|swf|wmv|flv|ico)$ {

 # [単位記号]
 # s:秒 m:分 h:時 d:日 w:週 M:月(30日) y:年(365日)
 # k|K:キロバイト m|M:メガバイト 1M=1024K

 if ( $request_filename ~ .*\.(jpe?g|gif|png|swf|wmv|flv|ico)$ ) {
 expires 1y;
 }
 if ( $request_filename ~ .*\.(css|js)$ ) {
 expires 1w;
 }
 if ( $request_filename ~ .*\.(xml|gz)$ ) {
 expires 1d;
 }
 # ログ取らない
 access_log off;
}

これらのファイルはログ設定の下あたりにincludeで読み込ませましょう。

server {
    ・・・
  
    # アクセスログとエラーログをとる
    access_log  /var/log/nginx/wordpress.access.log main;
    error_log   /var/log/nginx/wordpress.error.log;

    # 別ファイルで定義した設定を読み込む
    include /etc/nginx/drop;
    include /etc/nginx/expires;

    ・・・
}

 

 

WordPress本体をセットアップ

さて、やっと肝心のWordPress本体の準備に入ります。

まずは、WordPress本体を本家からダウロードして、解凍・展開後にドキュメントルートにおきましょう。

# 日本語版のWordPressをダウンロード
> wget https://ja.wordpress.org/latest-ja.tar.gz
> tar xzvf latest-ja.tar.gz
> rm latest-ja.tar.gz
> chown -R nginx:nginx wordpress
> chmod 777 wordpress
> mv wordpress /usr/share/nginx/

 

最新の日本語版WordPressをwgetで取得して、解凍します。解凍展開後にできたwordpressディレクトリの所有者とグループをnginxに変更、パーミッションをとりあえず777(誰でも読み書き可能)にしておきます。これは、755のままだと初期インストール時にwp-config.phpに書き込み不可とエラー出るためです。WordPressインストール完了後には755に戻します。

最後にwordpressを/usr/share/nginx/、つまりドキュメントルートに置いてウェブ上に公開します。

ブラウザでアクセスすると、WordPressの初期設定ページが表示されますので、先ほど設定したMySQLの情報を入力してインストールを完了させます。

wordpressのパーミッションは755に戻しておきます。

 

別サーバーのWordPressから移行

WordPressのインストール自体はここで完了なのですが、当方は別サーバー上でWordPressを既に運用していたので、その環境を丸ごとこっちのVPSに移したいと思います。

どちらのWordPressも基礎部分は同じなので、環境移行に必要なデータは次の通りです。

  • プラグインデータ
  • 画像などのメディアデータ
  • テーマ
  • 投稿などの記事データ

さてこれらのデータを新環境に移していきます。

まず上から3つのデータはwordpressディレクトリ内の次の場所にあります。

プラグイン → wordpress/wp-content/plugins/

メディア → wordpress/wp-content/uploads/

テーマ → wordpress/wp-content/themes/

よって、pluginsuploadsthemesの3つのディレクトリを旧環境からDLしてきて、新環境のそれと置き換えればOKです。

DL及び置換方法はftp, sftp, ftps, scpなど色々ありますので旧環境が対応している方法を選択します。

次に記事データですが、これは普通にWordPressの管理画面のツール > エクスポート、インポート機能から簡単に行えます。

詳細は下記リンク参照。

バックアップデータを使ってWordPressを復旧・移行する方法

旧環境の復元に重要なポイントは次の3点のようですね。

  • パーマリンク表示設定を新旧で合わせること
  • 新WordPressのユーザーをインポートユーザーとして選択すること
  • 添付ファイルダウンロードにチェック入れること

※ インポート実行側サーバーにphp-xmlのインスト必要、そのごphp-fpmの再起動が必要

 

インポートに失敗したら、DBManagerというプラグインをインストールして、インポート内容をクリアして再度挑戦すればOKです。

http://apr20.net/web/2842/

 

あとは、ウィジェットやメニューの設定を合わせれば移行作業は完了です。そうそう、WordPress設置後の重要な設定の1つにサイトアドレス設定がありますので、これは設定しておきましょう。

管理画面 → 一般設定 から下図の、WordPressアドレス(URL)サイトアドレス(URL)項目を取得したドメイン名に変更します。ま、既になっていれば何もする必要はありません。

これをしないと、例えばIPアドレスが指定されていた場合、WordPress内でのページ遷移後にはURLがIPアドレス指定のものになってしまい、ドメインが反映されません。

2016-04-21

 

認証をより強固にするためにBASIC認証を取り入れます。

いや、結局現時点で認証必要なのはWPログインだけで、個別ページに認証設定するつもりはないから止めた\(^o^)/

> htpasswd -cb /usr/share/nginx/wordpress/.htpasswd wp pass
> chown nginx:ngnix /usr/share/nginx/wordpress/.htpasswd
> vim /etc/nginx/conf.d/wordpress.conf

 # 以下を追記
 location ~* /wp-login\.php|/wp-admin/((?!admin-ajax\.php).)*$ {
     auth_basic "Please enter your name and password";
     auth_basic_user_file "/var/www/wordpress/.htpasswd";
 }

> nginx -s reload

 

SSLの設定

さて、WordPressを導入したのはいいですが、現状だとログイン時にIDとパスワードが平文で流れてしまいます。これはセキュリティ的に如何なものかと思いますのでSSLの設定を行います。

オレオレ証明書(自己署名証明書)の作成

通常のSSL証明書というものは信頼性が命ですので、信頼されたルート認証局から証明書を購入します。しか~し!高いものだと年間20万程度の利用料が発生するものもあります。せっかく銭をケチって安いVPSを借りたのにそれでは意味が無いですね・・・

なのでここでは、体外的な信頼性こそ無いものの、通信を暗号化するという意味では全く同じ機能でなおかつ無料で作れるオレオレ証明書を作成し、SSL(HTTPS)通信に使用したいと思います。

参考URL:http://d.hatena.ne.jp/ozuma/20130511/1368284304

# 秘密鍵(Private Key)作成
# 鍵長を2048bitとしている(デフォルトでは512bit)
# この秘密鍵から公開鍵や証明書の署名要求ファイルが作成される
> openssl genrsa 2048 > server.key


# 証明書署名要求(CSR;Certificate Signing Request)作成
# これは自分の公開鍵(秘密鍵から生成された)に対して署名してほしいと、認証局に要求するメッセージである。
# 証明書要求者の各情報を本来は入力するので入れたければ適宜入力してもOK
> openssl req -new -key server.key > server.csr
・・・基本Enter連打・・・
Common Name []: sincere-hips.tokyo ← ここは取得したドメインを指定
・・・基本Enter連打・・・


# CSRに自己署名しサーバ証明書を作成
# ※days=3650=10年間有効なサーバ証明書が作成される
> openssl x509 -req -days 3650 -signkey server.key < server.csr > server.crt
Signature ok
subject=/C=jp/ST=tokyo/L=Default City/O=Company LLC/CN=sincere-hips.tokyo
Getting Private key


# 秘密鍵と証明書のパーミッションを644に変更
> chmod 644 server.crt server.key
> chown nginx:nginx server.crt server.key

これでSSL証明書が出来てしまいました。ちなみに、不特定多数向けのHTTPSページでこの証明書は絶対に使ってはダメです。めちゃくちゃ怪しまれますし、そもそもブラウザが警告を出しますから・・・

一応、正規のSSL証明書取得手順が下記リンクに載っていますので参考までに。

https://www.sslcerts.jp/guide/

 

作成した証明書や秘密鍵はそれぞれ次の場所に置きましょう。

# 秘密鍵を移動
> mv server.key /etc/pki/tls/private/

# SSL証明書を移動
> mv server.crt /etc/pki/tls/certs/

 

NginxのSSL設定及びwp-loginの隠蔽

SSL証明書を作成しましたが、肝心のhttps通信を受け持つのはNginxですので、そちらを設定しないとhttpsアクセス出来ません。早速、先ほどのwordpress用の設定ファイルに追記していきます。基本、差分のみ記述しています。

# FastCGI部分は別ファイルに分離します
> vin /etc/nginx/phpfpm

fastcgi_split_path_info ^(.+.php)(/.+)$;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;


> vim /etc/nginx/conf.d/wordpress.conf

server {
    listen      80 default_server;
    listen      443 ssl;

    # SSL証明書パスを指定
    ssl_certificate      /etc/pki/tls/certs/server.crt;
    ssl_certificate_key  /etc/pki/tls/private/server.key;

    # ↓ キャッシュ設定、 10MB キャッシュする
    ssl_session_cache   shared:SSL:10m;
    # セッションの切れる時間を10分に指定
    ssl_session_timeout 10m;

    # サーバーの暗号スイート指定
    ssl_ciphers  HIGH:!aNULL:!MD5;
    # クライアントではなくサーバーの暗号スイート指定を優先する
    ssl_prefer_server_ciphers   on;

    # 各種変数を定義
    set $newlogin   HIDDENLOGIN;
    set $authid     XXXxxxXXX;
    set $logout     "";
    set $badlogin "";

    # デフォルトログインアクセスならフラグ設定
    if ( $uri ~ ^/wp-(login|config|blog-header)\.php$ ) {
        set $badlogin  1;
    }

    # 隠蔽ログインからのアクセスを許可する
    if ( $http_referer = $scheme://$hostname/$newlogin ) {
        set $badlogin "";
    }

    # 正しいログアウトを判定する
    # 1.リファラが /wp-admin である 2.認証クッキー情報があり、一致する
    if ( $http_referer ~ ^https://.+/wp-admin/ ) {
        set $logout 0$logout;
    }
    if ( $cookie_authid = $authid ) {
        set $logout 0$logout;
    }
    # ログアウト処理リンク
    if ( $request_uri ~ "^/wp-login\.php\?action=logout&_wpnonce=[0-9a-f]{10}$" ) {
        set $logout 1$logout;
    }
    # ログアウト完了後のログイン画面リンク
    if ( $request_uri = /wp-login.php?loggedout=true ) {
        set $logout 2$logout;
    }
    # ログアウト処理へのリンクの場合は /wp-login.php でもスルー
    if ( $logout = 100 ) {
        set $badlogin   "";
    }
    # ログアウト完了の場合は、隠蔽リンクにリダイレクト
    if ( $logout = 200 ) {
        rewrite ^(.*)$  /$newlogin?   redirect;
    }

    # デフォルトログインアクセスは403返す
    if ( $badlogin = 1 ) {
        return 403;
    }

    # 正規表現内では変数使えない?
    # 隠蔽ログインアクセスをデフォルトにリダイレクトする
    if ( $uri = /$newlogin ) {
        rewrite ^(.*)$ /wp-login.php;
    }

    # $host: HTTPヘッダのホストの値 $hostname: hostnameコマンドと同じ
    # $server_addr はサーバーIPアドレス
    # アドレスバーのドメイン部分が hostname と違う場合はリダイレクト
    if ($host != $hostname) {
        rewrite ^/(.*)$     $scheme://$hostname$uri;
    }

    set $sslstat    "";
    # ログイン画面 or 管理画面トップ の場合はhttps必須
    if ( $uri = /wp-login.php ) {
        set $sslstat    e;
    }
    # /wp-admin /wp-content /wp-includes 下へのアクセスはhttpリダイレクト回避
    if ( $uri ~ ^/wp-(content|includes|admin)/ ) {
        set $sslstat    _;
    }
    # エラー系のページもhttpリダイレクト回避
    if ( $uri ~ /error/.+\.html ) {
        set $sslstat    _;
    }

    # httpsフラグを設定  httpsなら末尾に"on"が追加される
    set $sslstat $sslstat$https;

    # https必須ページにhttpで来ていたら418コード
    if ( $sslstat = e ) {
        return 418;
    }
    # https不要なのにhttpsだったらhttpにリダイレクトする
    if ( $sslstat = on ) {
        rewrite ^(.*)?$     http://$host$uri    last;
    }

    # エラーコードによって418.htmlにリダイレクト
    error_page 418 /error/418.html;
    error_page 403 /error/403.html;
    error_page 404 /error/404.html;

    # サーバーエラーは 50x.html に内部リダイレクトする
    error_page 500 502 503 504 /error/50x.html;

    # エラーページ関係は全てこのディレクティブに
    location ~ ^/error/.+\.html$ {
         root /usr/share/nginx/html;
    }

    # ログイン成功者に認証IDの設定
    location = /wp-login.php {
        # 有効期限は1日, secure: https時のみSetする
        add_header Set-Cookie 'authid=$authid;Domain=$hostname;Path=/wp-login.php;Max-Age=86400;secure';
        include phpfpm;
    }

    ・・・省略・・・
}

# 設定ファイル再読込
> nginx -s reload

差分のみにしては随分とボリューミーになってしまいました。主にリダイレクトに関する設定やセキュリティ強化に関する設定で記述が膨らんでいます・・・

ただ、HTTPS通信を行う上で重要な部分はlisten 443 ssl証明書パス指定部分だけです。後はWordPress用のオプション設定みたいな感じです(オプション長っ・・・)。また、暗号スイートの部分などは指定しなくても別段支障はないと思われます。

また、FastCGI関係の設定は今後使いまわすかも知れないので別ファイルで定義しています。ちなみにNginxのfastcgiモジュールの各項目の説明はhttp://mogile.web.fc2.com/nginx/http/ngx_http_fastcgi_module.htmlに載っていますので参照ください。

 

では今回の設定がボリューミーになった原因でもあるリダイレクト関連について説明します。

さて、当方がやりたかったことは次の2つです。

  1. デフォルトログインページを隠蔽する処理
  2. ログインページにhttpsを強制する処理

まず、1.についてですが、/wp-login.phpがWordPressログイン画面なのは周知の事実であり、それが仇となり攻撃対象となり得るため隠蔽したいのです。ま、パスワード強度が非常に高ければ大丈夫かとは思いますが、隠蔽するに越したことはありませんね。

次に2.ですがこれはログインページへのhttpsの強制です。ログインページにhttpでアクセスしたら何らかのエラーコードを返したいのです。ちなみに、ここでいうログインページとは/wp-login.phpではありません。すでに隠蔽処理していますから。

 


1.の隠蔽処理について簡単に説明します。

とりあえずこの設定ではクライアントがhttpだろうがhttpsかに関わらず/wp-login.php等の重要アクセスの場合は403 Forbiddenをクライアントに返し、403エラーページにリダイレクトさせています。これによって攻撃者は/wp-login.phpへの直アクセスができなくなるため、突破リスクは低くなるでしょう。ちなみに、ここでは/wp-login.phpの代わりにHIDDENLOGINというリンク文字列を使って、内部的に/wp-login.phpへリダイレクトさせています。つまり、http://domain.com/HIDDENLOGINにアクセスすることで初めてログインページが現れるという仕組みです。直の/wp-logindでは403ページです。※ここでは仮にHIDDENLOGINですが実際のリンク文字列はもっと複雑にします。

ただし、ログアウト時はたとえアクセス先が/wp-login.phpであっても許可しなければなりません。というのも、ログアウト時にWordPressは/wp-login.phpへアクセスしてログアウト処理を行いますので禁止しているままだと、ログアウト後に403になってしまいます。ここでは主に、ログアウト時の許可判断および隠蔽ログインへのリダイレクトに$authid(認証クッキー)変数を使っています。正規ユーザーは隠蔽されたログインページにアクセスすることで、Nginxから認証クッキーを貰います🍪 そして、ログアウト時の/wp-login.phpアクセスでこの認証クッキーを持っていれば、正規ユーザーのログアウト要求と判断してアクセスを許可しています($badloginを空にする)。実際のクッキー設定はadd_header Set-Cookie ‘authid=$authid;Domain=$hostname;Path=/wp-login.php;Max-Age=86400;secure’;で行ってます。各意味は

http://www.yunabe.jp/docs/cookie_and_security.htmlに詳しいです。

また、ログアウト要求の判断には認証クッキーだけではなくHTTPヘッダーのRefererという属性($http_referer)も見ています。ここではアクセス元が/wp-admin、つまり管理画面からのアクセスか否かで判断しています。

/wp-login.phpへのアクセスもより正確に、?/wp-login.php?action=logout&_wpnonce=xxxxxxxxxx などのパラメータの有無も考慮しています。しかしながら、このログアウト要求においてパラメータの有無やRefererの値は偽装できますので、正規判断で一番重要なのは認証クッキーの部分です。$authidの値を十分に長く強固なものにすれば偽装することはできませんから。

さて、wp-config.phpとwp-blog-header.phpは特別なファイルなので置いといて、wp-login.phpだけ隠蔽すればOKなの?/wp-adminとかでアクセスされたらまずいんじゃ?と思うかもしれません。でも大丈夫です、なぜならWordPress内で次のようなリダイレクト設定がなされているからです。

 

path8628

 

/wp-adminへのアクセスはログインセッションが維持されていれば/wp-login.phpにリダイレクトされませんが、いきなり/wp-adminと打った場合はリダイレクトされます。つまり、ログインしていない状態で管理系のURLアクセスを行っても必ず/wp-login.phpに辿り着くので、その入り口のみを隠蔽すればOKなのです。

 


2.はhttpsの強制及びリダイレクト設定です。ここでは主に次のことを行っています。

  • ログインページではhttps必須にしhttpでアクセスした場合はエラーコードを返す。
  • 本来、平文にすべきアクセスがhttps要求ならhttpにリダイレクト

まず、ログインページへのアクセスはhttpsに限定しています。http->httpsリダイレクト設定していないことに注意してください。これはリダイレクトを利用したMITM(中間者攻撃)を意識してのことです。なのでエラーコードのみ返します。ここではジョークコードの418を返しています。気になる方はググりましょう。ログインは必ずhttpsになりますので、以降の管理画面でもhttpsセッションが継続します。

一方、通常公開する記事などへhttpsでアクセスした場合はhttpにリダイレクトさせます。そもそもサイト全体を常時SSL化していればこんなリダイレクト設定は不要なのですが、なんせオレオレ証明書なんで訪問者様に公開する訳にはいかないのです。訪問者様のブラウザで警告が出されてしまい、かなり怪しいサイトに思われかねないので。

 


以上、今回のSSL設定でした。細かい部分はコメントから察してください。

あとエラー系ページ(403.htmlなど)の設定は別になくても、Nginxのデフォルトが使用されるので構いません。デフォルトから変えたい場合などに設定します。

 

次回はメールサーバー設定を行います。