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

LAN内でリバースプロキシを使用した場合の request.remote_ip

More than 5 years have passed since last update.

はまったのん…

環境

  • Rails 4.0.1
  • nginx + Unicorn

リバースプロキシを利用した場合のアクセス元アドレス

通常、リバースプロキシ (nginxなどのウェブサーバを含む; 以下単にプロキシ) を利用した場合、アクセス元はプロキシ側のIPアドレスとなるため実際のアドレスを知ることが出来ない。このため、プロキシ側ではリクエストヘッダ (Client-IP: など) にアクセス元のアドレスを含めることが多い。Webサーバはこの値を読んで本来のアドレスを知ることが出来る。

Railsでは request.env 中の情報を利用して、実際のリモートホストを取得することが出来る。ただし、request.remote_ip でヘッダの情報を処理した "正しい" リモートホストを参照することができるため、直接ヘッダの情報を参照するメリットはあまり無い。(この機能は ActionPack 中の ActionDispatch で提供されており、Client-IP: または X-Forwarded-For: に含まれるアドレスがリモートアドレスとして取り扱われる。)

問題点

LAN (プライベートIPアドレスを使用したネットワーク) 内にあるサーバにアクセスした場合には request.remote_ip がプロキシ側のアドレスとなってしまう。

※プロキシ側では Client-IP: または X-Forwarded-For: が設定されるものとする。

原因

ActionDispatch::RemoteIp::TRUSTED_PROXIES にマッチするアドレス (ループバックアドレスとプライベートアドレス) は、プロキシサーバと見なされ、Client-IP: や X-Forwarded-For: に含まれていても無視されるため。(ActionDispatch::RemoteIp::GetIp.filter_proxies で処理している。)

actionpack-4.0.1/lib/action_dispatch/middleware/remote_ip.rb
TRUSTED_PROXIES = %r{
  ^127\.0\.0\.1$                | # localhost IPv4
  ^::1$                         | # localhost IPv6
  ^fc00:                        | # private IPv6 range fc00
  ^10\.                         | # private IPv4 range 10.x.x.x
  ^172\.(1[6-9]|2[0-9]|3[0-1])\.| # private IPv4 range 172.16.0.0 .. 31.255.255
  ^192\.168\.                     # private IPv4 range 192.168.x.x
}x

対策

プロキシのみにマッチする正規表現を Rails.configuration.action_dispatch.trusted_proxies に設定する。

config/environments/production.rb
Hoge::Application.configure do
  ...
  config.action_dispatch.trusted_proxies = /^127\.|^::1$/
end

ここでは、ループバックアドレスのみをプロキシサーバとして扱うよう設定した。

まとめ

  • ドキュメントをサガしたけど直接書かれているものが見つからず、ソースコードを読むことに。オープンソースはありがたいけど、初心者には辛い。
  • デフォルトで Client-IP: や X-Forwarded-For: を処理したり、プライベートアドレスをプロキシ扱いにするのは、あまり筋が良くないと思う。
  • こまちゃん可愛い
yasu
Ruby & Rails 初心者です。
http://yasu.asuka.net/
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
ユーザーは見つかりませんでした