nginxでmapモジュールを使って301リダイレクトを行う

nginxでmapモジュールを使って301リダイレクトを行う

February 9, 2015,
tags: nginx redirect


このエントリーをはてなブックマークに追加

ブログの移行に当たってnginxでのリダイレクト設定をしていたのですが、そこでmapモジュールを使ったら便利だったので使い方を紹介していきたいと思います。

単純なnginxのリダイレクトについて

nginxのリダイレクト設定自体は結構簡単で、例えば古いドメインから新しいドメインに書き換える場合は以下のような感じで簡単にリダイレクト設定ができるわけです。

server {
    listen 80;
    server_name www.polidog.jp;
    rewrite ^ $scheme://polidog.jp$request_uri permanent;
  }

リダイレクト先のURLにある程度法則性がある場合は結構サクッとリダイレクトがかけますよね。

世の中めんどくさいリダイレクトを依頼される事がある

まあ正規表現でいけるようなリダイレクトの場合はいいんですよ。
ただそうじゃないことってのも夜中ありますよね。

様々な理由でまったく違うページにリダイレクトするとか、、、
そして、ディレクターから大量のリダイレクト表をもらうなんてことがあります。

そんな時に便利なのが ngx_http_map_module です。

HttpMapModuleとはなにか?

ngx_http_map_module

標準で入ってるモジュールであるngx_http_map_moduleは、configure時にdisableにすることによって、無効化できるわけですが、yumとかaptだったら恐らく標準でenableになっているかと思います。

configureのオプションを確認するにはnginx -Vで確認することができます。

$ nginx -V | grep abceeeee
nginx version: nginx/1.0.15
built by gcc 4.4.7 20120313 (Red Hat 4.4.7-11) (GCC)
TLS SNI support enabled
configure arguments: --prefix=/usr/share/nginx --sbin-path=/usr/sbin/nginx --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --http-client-body-temp-path=/var/lib/nginx/tmp/client_body --http-proxy-temp-path=/var/lib/nginx/tmp/proxy --http-fastcgi-temp-path=/var/lib/nginx/tmp/fastcgi --http-uwsgi-temp-path=/var/lib/nginx/tmp/uwsgi --http-scgi-temp-path=/var/lib/nginx/tmp/scgi --pid-path=/var/run/nginx.pid --lock-path=/var/lock/subsys/nginx --user=nginx --group=nginx --with-file-aio --with-ipv6 --with-http_ssl_module --with-http_realip_module --with-http_addition_module --with-http_xslt_module --with-http_image_filter_module --with-http_geoip_module --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gzip_static_module --with-http_random_index_module --with-http_secure_link_module --with-http_degradation_module --with-http_stub_status_module --with-http_perl_module --with-mail --with-mail_ssl_module --with-debug --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic' --with-ld-opt=-Wl,-E

で、肝心の何をするモジュールかというと

Creates a new variable whose value depends on values of one or more of the source variables specified in the first parameter.

ということなので、

最初のパラメータで指定された変数の値とマッチする場合、新しい変数を作成します。

って感じの意味合いでいいのかなと思います。(自信ないけど・・・・

簡単にサンプルを見せると

map "test" $new {
  "test" "test2"
}

if ($new = "test2") {
  ...
}

この場合だとtestという文字にマッチした場合は$newという変数にtest2という値がはいることになります。 ちなみにマッチしない場合は$newには値がはいりません。

つまり条件判定で以下のようにかければ、マッチしているかどうかがわかるわけです。

if ($new) {
 # マッチした場合の記述
}

uriを指定したリダイレクト設定の場合

nginxには$request_uriという変数がありますね。
それとmapを組み合わせれば、リダイレクト表に合わせたリダイレクト設定ができます。

例えば、www.polidog.jpからpolidog.jpへの記事をリダイレクトさせたい場合なんかは、こんな感じで設定します。

map $request_uri $new {
  ~^/2015/01/06/.* http://polidog.jp/2015/01/06/akeome/;
}

あとは$new変数に値が入った場合リダイレクトする設定を書けばいいんで、だいたいこんな感じになりますね。

map $request_uri $new {
  ~^/2015/01/06/.* http://polidog.jp/2015/01/06/akeome/;
}

server {
  listen 80;
  server_name www.polidog.jp;

  if ($new) {
     rewrite ^ $new permanent;
  }  
}

includeを利用する

map {}の中にどんどん記載していくのはいいんですが、nginxのconfに書き続けるのは若干微妙かなぁーと思います。

そんな時をはincludeを利用しましょう

map $request_uri $new {
  include /etc/nginx/redirect_list.map
}

server {
  listen 80;
  server_name www.polidog.jp;

  if ($new) {
     rewrite ^ $new permanent;
  }  
}

で、/etc/nginx/redirect_list.mapにはこんな感じで記述します。

~^/2015/01/06/.* http://polidog.jp/2015/01/06/akeome/;
~^/2015/12/31/.* http://polidog.jp/2015/12/31/fruikaeri/;

まとめ

nginxとmapを使えば、大量のリダイレクト設定も簡単にできてしまいます。 ぜひ便利な機能なので使っていきましょう。

comments powered by Disqus