Help us understand the problem. What is going on with this article?

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

More than 3 years have passed since last update.

あるイントラネット用の 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 くらいにする」と捉えておけば問題ないはず。

ikyu
「こころに贅沢を」をコンセプトに一休.com、一休レストランなどのサービスを提供しています。
https://www.ikyu.com
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした