Aus der Quelle:
module ActionDispatch
class Request < Rack::Request
def ip
@ip ||= super
end
def remote_ip
@remote_ip ||= (@env["action_dispatch.remote_ip"] || ip).to_s
end
end
end
wo Rack :: Request so aussieht
module Rack
class Request
def ip
remote_addrs = split_ip_addresses(@env['REMOTE_ADDR'])
remote_addrs = reject_trusted_ip_addresses(remote_addrs)
return remote_addrs.first if remote_addrs.any?
forwarded_ips = split_ip_addresses(@env['HTTP_X_FORWARDED_FOR'])
if client_ip = @env['HTTP_CLIENT_IP']
return client_ip if forwarded_ips.include?(client_ip)
end
return reject_trusted_ip_addresses(forwarded_ips).last || @env["REMOTE_ADDR"]
end
end
end
So remote_ip
gibt den Vorrang action_dispatch.remote_ip
. Das wird von der ActionDispatch::RemoteIp
Middleware eingestellt. Sie können in der Quelle dieser Middleware sehen, dass sie beim Aufrufen GetIp.new
nach Spoofing-Angriffen sucht, da sie zum Festlegen dieser env-Variablen aufruft . remote_ip
Dies ist erforderlich, da die IP-Adresse auch über die lokalen Proxys gelesen wird, wie Clowerweb erklärt.
request.remote_ip
nach kann die HTTP_X_FORWARDED_FOR-Kette zwar gefälscht werden, sie kann jedoch gefälscht werden, wenn Sie Rails hinter nginx oder haproxy haben. Verwenden Sie in Nginxproxy_set_header X-Forwarded-For $remote_addr;
anstelle vonproxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
. Im letzteren Fallcurl -H "X-Forwarded-For: 6.66.6.66" http://example.com
wird einrequest.remote_ip
Wert von 6.66.6.66 erzeugt, der alle IP-Überprüfungen in Rails fälscht.request.ip
Gibt den Client zurück,ip
auch wenn dieser Client ein Proxy ist.request.remote_ip
ist schlauer und bekommt den eigentlichen Kundenip
. Dies ist nur möglich, wenn alle Proxys auf dem Weg den X-Forwarded-For- Header festgelegt haben.quelle
request.ip
request.ip
ist die grundlegende IP-Erkennung, die standardmäßig bereitgestellt wirdRack::Request
. Die aktuelle Definition finden Sie unter https://github.com/rack/rack/blob/master/lib/rack/request.rb .Der Algorithmus, dem es folgt, besteht darin, zuerst den
REMOTE_ADDR
Header auf nicht vertrauenswürdige IP-Adressen zu überprüfen und, falls er welche findet, die erste aufgelistete auszuwählen. "Vertrauenswürdige" IP-Adressen sind in diesem Fall IP-Adressen aus den reservierten privaten Subnetzbereichen. Beachten Sie jedoch, dass sie mit Regex übereinstimmen, was wahrscheinlich nicht der beste Weg ist, dies zu tun. Wenn kein nicht vertrauenswürdiger Benutzer vorhanden ist, wirdREMOTE_ADDR
derHTTP_X_FORWARDED_FOR
Header angezeigt und der zuletzt aufgelistete nicht vertrauenswürdige ausgewählt. Wenn keiner von beiden jemanden enthüllt, fällt er auf den Rohwert zurück, derREMOTE_ADDR
wahrscheinlich 127.0.0.1 ist.request.remote_ip
request.remote_ip
ist eine verbesserte IP-Erkennung, die vonActionDispatch::Request
(die von erbtRack::Request
) bereitgestellt wird . Dies ist der in der Frage gezeigte Code. Wie Sie sehen können, fällt es auf zurück,request.ip
esaction_dispatch.remote_ip
sei denn , es ist auf dem eingestellt@env
. Dies geschieht durch dieRemoteIp
Middleware, die im Standard-Rails-Stack enthalten ist. Sie finden die Quelle unter https://github.com/rails/rails/blob/4-2-stable/actionpack/lib/action_dispatch/middleware/remote_ip.rb .Die
RemoteIp
aktivierte Middleware bietet folgende zusätzliche Funktionen:IPAddr
Klasse, um IP-Bereiche tatsächlich richtig zu testen, anstatt sich auf einen spröden regulären Ausdruck zu verlassen.HTTP_CLIENT_IP
als Quelle für potenzielle IPs verwendet.Der Algorithmus ist ähnlich,
request.ip
aber etwas anders. Es verwendetHTTP_X_FORWARDED_FOR
von zuletzt nach zuerst, dannHTTP_CLIENT_IP
von zuletzt nach zuerst, dann schließlich den letzten Eintrag vonREMOTE_ADDR
. Es fügt alle in eine Liste ein und filtert Proxys, wobei der erste verbleibende ausgewählt wird.IP-Spoofing-Erkennung
Die von bereitgestellte IP-Spoofing-Erkennung
RemoteIp
ist nicht besonders leistungsfähig. Sie löst lediglich eine Ausnahme aus, wenn die letzteHTTP_CLIENT_IP
nicht aktiviert istHTTP_X_FORWARDED_FOR
. Dies ist nicht unbedingt ein Symptom eines Angriffs, aber es ist wahrscheinlich ein Symptom einer Fehlkonfiguration oder einer Mischung von Proxys, die unterschiedliche Konventionen verwenden und kein kohärentes Ergebnis liefern.Welche zu verwenden
In einer einfachen Konfiguration, in der Ihre Proxys alle lokal oder in privaten Subnetzen sind, können Sie wahrscheinlich davonkommen
request.ip
,request.remote_ip
sollten aber im Allgemeinen als die überlegene Wahl angesehen werden. Wenn Sie Proxys mit öffentlichem Internet-Routing verwenden (z. B. viele CDNs),RemoteIp
können Sie diese so konfigurieren, dass Sie sofort die richtigen Client-IPs erhalten. Dies ist jedochrequest.ip
nur dann der Fall, wenn Sie Ihren Upstream-ProxyREMOTE_ADDR
korrekt einstellen können.Sichere Konfiguration
Nun zu Tim Coulters Kommentar zum Spoofing. Er hat definitiv Recht, dass Sie sich Sorgen machen sollten, aber er hat Unrecht, dass Sie gefälscht werden können, wenn Sie standardmäßig hinter Nginx oder Haproxy stehen.
RemoteIp
wurde entwickelt, um Spoofing durch Auswahl der letzten IP in der Kette zu verhindern. Die X-Forwarded-For- Spezifikation gibt an, dass jeder Proxy die IP des Anforderers an das Ende der Kette anfügt. Durch Herausfiltern von Whitelist-Proxys wird garantiert, dass der letzte Eintrag die Client-IP ist, die von Ihrem ersten Whitelist-Proxy geschrieben wurde. Es gibt eine Einschränkung natürlich die , dass Sie tatsächlich einen Proxy laufen muss , ist , dass immer Sätze / AppendsX-Forwarded-For
, so Tim Rat eigentlich umgekehrt sein sollte: nur verwenden ,request.remote_ip
wenn Sie sind ein Proxy ausgeführt wird .So konfigurieren Sie öffentliche IP-Proxys
Das ist alles in Ordnung und gut, befindet sich aber
ActionDispatch::RemoteIp
bereits im Standard-Middleware-Stack. Wie konfiguriere ich es neu, um meine Proxy-CIDRs hinzuzufügen?!Fügen Sie dies zu Ihrem hinzu
application.rb
:check_spoofing = true proxies = ["23.235.32.0/20", "203.57.145.0/24"] proxies += ActionDispatch::RemoteIp::TRUSTED_PROXIES config.middleware.swap ActionDispatch::RemoteIp, ActionDispatch::RemoteIp, true, proxies
quelle