6
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

備忘録: nginx でアクセス元 IP レンジに応じて Web アプリケーションを切り替える

Posted at

あるイントラネット用の Web アプリケーションのアップグレードを試していて、次のようなことをしたい場合があった。

  1. 特定の IP からのアクセスでは次バージョンのサイトに接続する (試験ユーザ)
  2. それ以外の IP からのアクセスは現バージョンのサイトに接続する (通常ユーザ)

ローカルホストで試験するという手段もあるが、

A. ホスト名に依存する処理がある (外部の認証機構からリダイレクトする、など)
B. HTTPS 限定のサイトである (このために証明書等をローカルホストに移すのは手間かつセキュアでない)
C. 複数人のアクセスを想定している (ので人数分の /etc/hosts を書き換えるのも容易ではない)

といった条件もあり「リバースプロキシ側 (nginx) でアクセス元の IP レンジに応じて Web アプリケーションを切り替える」という方針で進めることにした。なおかつ、なるべく手軽にやりたかった。

内容はとてもシンプルだけど、すぐ忘れそうなので、備忘録として残しておく。

こう書いた

今回の要旨と関係のないディレクティブは全て省略した。
登場人物は 3 つ。

普通のユーザに見せたい方のサイトを usual_server, 試験者のサイトを testing_server と定義した。

/etc/ngnix/sites-available/site.example.com.conf
upstream usual_server {
  server 127.0.0.1:8080;
}

upstream testing_server {
  server 127.0.0.1:8081;
}

geo $maintenance {
  default 0;
  # 許可したい IP レンジ
  192.168.100.105/32 1;
}

server {
  if ($maintenance = 0) {
    set $target_proxy_server "usual_server";
  }

  if ($maintenance = 1) {
    set $target_proxy_server "testing_server";
  }

  location / {
    proxy_pass http://$target_proxy_server;
  }
}

あとは

$ sudo service nginx configtest && sudo service nginx reload

なぜこのような書き方にするか

If Is Evil にも書かれているように、 nginx では location context 内での if はうまく処理できない問題がある。

下記は動作しない。

だめな例
if ($maintenance = 1) {
  location / {
    proxy_pass http://$testing_server;
  }
}
if ($maintenance = 0) {
  location / {
    proxy_pass http://$usual_server;
  }
}

また、 nginx の if には else に対応するものがない。
「複雑なことは if で制御しようとせず、なるべくなら使わない、使っても set くらいにする」と捉えておけば問題ないはず。

6
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?