Action Dispatch RemoteIp
這個中間件計算提出請求的遠端用戶端 IP 位址。它會檢查可能包含位址的各種標頭,然後選取不在受信任 IP 清單中的最後設定位址。這遵循先例設定,例如 Tomcat 伺服器。演算法的更詳細說明在 GetIp#calculate_ip
中提供。
有些 Rack 伺服器會串接重複的標頭,就像 HTTP RFC 2616 所要求的。有些 Rack 伺服器只會捨棄前面的標頭,只回報在 最後標頭中給定的值。如果您在多個代理伺服器之後(例如 NGINX 到 HAProxy 到 Unicorn),您應該測試您的 Rack 伺服器以確保您的資料是好的。
如果您不使用代理,這會讓您容易受到 IP 欺騙。這個中間件假設至少有一個代理伺服器在執行,並設定標頭包含用戶端的遠端 IP 位址。如果您不使用代理,因為您是在沒有 SSL
的 Heroku 上架,任何用戶端都可以透過設定 X-Forwarded-For
標頭來宣稱擁有任何 IP 位址。如果您在意這一點,那麼您需要在這個中間件執行之前,明確捨棄或忽略那些標頭。或者,移除這個中間件以避免無意間依賴它。
常數
TRUSTED_PROXIES | = | [ "127.0.0.0/8", # RFC-3330 中的本機端 IPv4 範圍 "::1", # 本機端 IPv6 "fc00::/7", # 私有 IPv6 範圍 fc00::/7 "10.0.0.0/8", # 私有 IPv4 範圍 10.x.x.x "172.16.0.0/12", # 私有 IPv4 範圍 172.16.0.0 .. 172.31.255.255 "192.168.0.0/16", # 私有 IPv4 範圍 192.168.x.x ].map { |proxy| IPAddr.new(proxy) } |
預設信任的 IP 清單僅包含保證為私人地址的 IP 位址。在實際運作中,這些不會是最終的客戶端 IP,因此會被捨棄。有關詳細資訊,請參閱 zh.wikipedia.org/wiki/%E7%A7%81%E5%AF%86%E7%BD%91%E7%BB%9C。 |
屬性
[R] | check_ip | |
[R] | proxies |
類別公共方法
new(app, ip_spoofing_check = true, custom_proxies = nil) 連結
建立新的 RemoteIp
中介軟體執行個體。
ip_spoofing_check
選項預設為開啟。開啟時,如果看起來客戶端試圖謊報其自己的 IP 位址,則會引發例外狀況。對於針對非 IP 客戶端(例如 WAP 裝置)的網站,或在以不正確或令人混淆的方式設定標頭的代理程式(例如 AWS ELB)之後,關閉此檢查是有意義的。
custom_proxies
參數可以接受一個可列舉的項目,它將用於取代 TRUSTED_PROXIES
。任何代理程式設定都會將您想要的數值置於 X-Forwarded-For
清單的中間(或開頭),其後會是您的代理伺服器。如果您的代理程式未移除,請透過 custom_proxies
參數傳遞它們。這樣,中介軟體會忽略那些 IP 位址,並傳回您想要的 IP 位址。
來源:顯示 | 在 GitHub 上
# File actionpack/lib/action_dispatch/middleware/remote_ip.rb, line 61 def initialize(app, ip_spoofing_check = true, custom_proxies = nil) @app = app @check_ip = ip_spoofing_check @proxies = if custom_proxies.blank? TRUSTED_PROXIES elsif custom_proxies.respond_to?(:any?) custom_proxies else raise(ArgumentError, <<~EOM) Setting config.action_dispatch.trusted_proxies to a single value isn't supported. Please set this to an enumerable instead. For example, instead of: config.action_dispatch.trusted_proxies = IPAddr.new("10.0.0.0/8") Wrap the value in an Array: config.action_dispatch.trusted_proxies = [IPAddr.new("10.0.0.0/8")] Note that passing an enumerable will *replace* the default set of trusted proxies. EOM end end
執行個體公共方法
call(env) 連結
由於可能不需要 IP 位址,我們在此儲存物件,而不會計算 IP,以避免減慢大多數要求的速度。對於確實需要知道 IP 的要求,GetIp#calculate_ip
方法將計算已暫存的客戶端 IP 位址。
來源:顯示 | 在 GitHub 上
# File actionpack/lib/action_dispatch/middleware/remote_ip.rb, line 89 def call(env) req = ActionDispatch::Request.new env req.remote_ip = GetIp.new(req, check_ip, proxies) @app.call(req.env) end