request.ip
request.ip
ist die grundlegende IP-Erkennung, die standardmäßig bereitgestellt wird Rack::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, wird REMOTE_ADDR
der HTTP_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, der REMOTE_ADDR
wahrscheinlich 127.0.0.1 ist.
request.remote_ip
request.remote_ip
ist eine verbesserte IP-Erkennung, die von ActionDispatch::Request
(die von erbt Rack::Request
) bereitgestellt wird . Dies ist der in der Frage gezeigte Code. Wie Sie sehen können, fällt es auf zurück, request.ip
es action_dispatch.remote_ip
sei denn , es ist auf dem eingestellt @env
. Dies geschieht durch die RemoteIp
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:
- Bietet optionale, aber standardmäßige IP-Spoofing-Erkennung.
- Ermöglicht das Filtern von Konfigurations-Proxy-Adressen, anstatt sich nur auf Standardeinstellungen zu verlassen.
- Verwendet die
IPAddr
Klasse, um IP-Bereiche tatsächlich richtig zu testen, anstatt sich auf einen spröden regulären Ausdruck zu verlassen.
- Wird
HTTP_CLIENT_IP
als Quelle für potenzielle IPs verwendet.
Der Algorithmus ist ähnlich, request.ip
aber etwas anders. Es verwendet HTTP_X_FORWARDED_FOR
von zuletzt nach zuerst, dann HTTP_CLIENT_IP
von zuletzt nach zuerst, dann schließlich den letzten Eintrag von REMOTE_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 letzte HTTP_CLIENT_IP
nicht aktiviert ist HTTP_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 jedoch request.ip
nur dann der Fall, wenn Sie Ihren Upstream-Proxy REMOTE_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 / Appends X-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
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.