ConoHa WordPressテンプレートを読み解く(nginxリバースプロキシ編)

2014-06-08 サーバー管理

1個前の記事で、「ConoHaってタイトルに入れとけばこのはちゃんが釣れるからちょろい」的なことを書いたら、今回はRTしてもらえませんでした…
まぁそんなことは気にせず、今回もConoHa推しでいくんですけどね。

ConoHaのWordPressテンプレート、VPS立ち上げたら既にnginxやらmysqlやらが全部設定されていて非常に便利なんですが、自分で手を動かさない分ハマったときにちょっと困ったりします。

  • あれ、.htaccess置いたけど反応しないぞ…?
  • アクセスログ見たいけどaccess.logとdefault.access.logとdefault.backend.access.logとそれぞれの日付つきがあってどれ見ればいいんです?
  • phpのupload_limit上げたいけどphp.ini弄っても反映されなくて俺涙目

などなど、自分で構成してないと分かりづらいハマりポイントは多いはず。

ちなみに上記の例は全て自分が踏んだものです。
1個目とか、ハマりポイント以前の問題ですね、すみませんでした…

そんなわけで、自分が読み解いた設定を備忘録兼ねて残しておきたいと思います。
今回はnginxリバースプロキシ編。気が向いたら他のもやるかも、ということで風呂敷を広げておきます。

nginxの設定は基本的に /etc/nginx/conf.d/ 下にまとまっているため、ここの設定を読んでいきます。linuxによくあるディレクトリ構成ですね。
ちなみに、 /etc/httpd/ も存在するため間違ってこちらを弄らないように注意が必要です。
念のためchkconfigすれば、httpdが完全offになってるのが確認できるかと思います。

どうでもいいんですが、apacheだとディストリビューションによってhttpdだのapache2だの名前が変わるのが大変アレなので、その点nginxさんは素直で良いと思います。
本当にどうでもいいんですが。

default.conf

名前からして基本設定ですが、やっぱりその通り、一番最初にリクエストを受け取るバーチャルホストの設定が書かれてます。

ちょっと長いのでブロックに分けて見ていきます。

listen      80 default;
    server_name _;
    root        /var/www/vhosts/default;
    index       index.html index.htm;
    charset     utf-8;
 
    access_log  /var/log/nginx/default.access.log  main;
    error_log   /var/log/nginx/default.error.log;

2行目から9行目は、このバーチャルホストの基本設定です。
listen 80 defaultのところは「ポート80番で来たリクエストを処理するよ、あと80番ポートで行き場のないリクエストはデフォルトでこれを使うよ」という意味になります。
また、server_name _ は「_という名前のバーチャルホストだよ」という意味になります。
OCamlとかScalaに慣れてるとパターンマッチのワイルドカードっぽく見えますが、「_という名前」であることに注意が必要です。
無論 _はドメイン名として無効なためマッチしないのですが、nginxは「ホスト名がどのサーバーにもマッチしなかった場合、デフォルトサーバーに振り向ける」という挙動になっているため、80番ポートへのリクエストは全てこのサーバーで処理されることになります。
この辺は公式の「nginx はどのようにリクエストを処理するか」が詳しいです。
ところでこれ、公式ドキュメントだとdefault_serverと書かれているのしか見当たらないんですが、defaultだけでも問題ないんでしょうか…?

4行目のroot設定はその名の通りrootディレクトリの設定です。ここからwordpressは /var/www/vhosts/default 下に設置されていることが読み取れます。
また8行目と9行目のaccess_log, error_log 設定から、一番最初に来たアクセスのログはdefault.access.logなどを見れば良さそうです。

include     /etc/nginx/drop;

11行目のincludeでは、別ファイルから設定を読み込んでいます。
/etc/nginx/dropは以下のようになっています。

基本的にはfaviconやapple系アイコンなど、取りに来られることが多いけどなくても困らないものについてaccess_logを抑制しています。
またwp-configやreadmeなど利用者に見られたくないものは強制的に404にしています。dropという名前からしてこっちが主目的ですね。

rewrite /wp-admin$ $scheme://$host$uri/ permanent;
    #rewrite ^(.*)(index|home|default)\.html? $1 permanent;

    set $mobile '';
    #include /etc/nginx/mobile-detect;
 
    set $do_not_cache 0;
    if ($http_cookie ~* "comment_author_|wordpress_(?!test_cookie)|wp-postpass_" ) {
        set $do_not_cache 1;
    }
    if ($request_method = POST) {
        set $do_not_cache 1;
    }

13行目から25行目はwp-adminをスラッシュ終わりにしていたり、管理者やPOSTでキャッシュを抑制したりといった設定です。
普通に使う分には余り気にしなくて良さそうですが、wp-adminの名前を変更する場合などは修正が必要になりそうです。
またコメントアウトされているmobile_detectはパッと見た感じモバイル端末に応じてキャッシュを分けるためのフラグを設定する処理のようです。
ここに限らず、オプション設定がコメントアウトされている部分が多くあるため、必要に応じて利用すると良いかと思います。

コメントアウトされているところは除いて32行目から。

location / {
        if ($request_filename ~ .*\.php) {
            break;
            proxy_pass http://backend;
        }
        include /etc/nginx/expires;
 
        proxy_no_cache     $do_not_cache;
        proxy_cache_bypass $do_not_cache;
 
        proxy_redirect     off;
        proxy_cache        czone;
        proxy_cache_key    "$scheme://$host$request_uri$mobile";
        proxy_cache_valid  200 0m;
        proxy_pass http://backend;
    }

ここでは/で始まるパスの(つまり全ての)リクエストに対する処理が定義されています。
ここで注意が必要なのは、「locationディテクティブでの定義は前方一致か正規表現のいずれかである」ことと、「優先順位は記述順ではなくより厳格な表現のものが優先される」ことです。
/始まりは全てのリクエストにマッチしますが、この後に正規表現でのlocation定義があるため、もしそちらの正規表現にマッチするリクエストであればそちらの処理が行われます。
この辺はnginx連載5回目: nginxの設定、その3 – locationディレクティブが詳しいです。
とりあえず、他で定義された正規表現が一致しなかった余り物リクエストにこの処理が適用される、と思ってもらえれば良いかと思います。

ifの内容は、リクエストファイルが.phpで終わるなら即座にbackendに処理を流す、というもの。
一方それ以外のファイルは/etc/nginx/expiresでファイルタイプ毎にExpiresヘッダを設定した後、キャッシュを有効にしてキャッシュが期限切れだったり存在しなかった場合のみbackendに処理を流しています。
このへんの処理はまんまリバースプロキシですね。
ただ、proxy_cache_validの有効期限が0mになっているので、このままだと全くキャッシュされないような…?
ここについては、必要に応じて伸ばせということなのか、それとも何らかのテクニックなのかよく分かってません。
教えてエロい人!

残りはphpmyadminを叩かせない設定と、50X系の設定です。

location ~* /(phpmyadmin|myadmin|pma) {
        access_log off;
        log_not_found off;
        return 404;
    }

phpmyadminは404にするよ、と。
おそらく普及度の高さ故にphpmyadminというURLで攻撃されやすいんだと思われます。
ちなみに前述の通り、正規表現の方が前方一致より優先度が高いため、/myadmin みたいなアクセスはこちらで処理されます。

error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }

50x系ページはnginxのデフォルトを使う設定。
オリジナルに置き換えたい場合はここを変えてやる必要がありますね。

ということで、最後の方は露骨に駆け足でしたが

  • default.confがリバースプロキシ設定になっていること
  • リバースプロキシのアクセスログはdefault.access.logに出ていること
  • リバースプロキシのエラーログはdefault.error.logに出ていること
  • リバースプロキシへのアクセスログがphpの実行結果はキャッシュされないこと
  • それ以外のファイルではキャッシュされるけど、初期設定ではキャッシュ期間が0mでキャッシュされてないかもしれないこと

辺りを読み解くことが出来ました。
この辺を抑えておけば、負荷が増えてキャッシュ時間を伸ばす場合や、負荷分散のためにバックエンドサーバーを複数立ててロードバランスする場合に弄る場所の検討をつけることができるんじゃないかと思います。

思いの他長くなったため、default.backend.confやnginx.confについては次回以降に気が向いたらまとめます。
というかnginx.confから読み始めるべきでしたね…
ではでは、次回以降もよろしくお願いします。

(2014/06/21追記)
続き→ConoHa WordPressテンプレートを読み解く(nginxバックエンド編)