Demande.ip
request.ip
est la détection d'IP de base fournie par Rack::Request
en dehors de la boîte. Sa définition actuelle est disponible à l'adresse suivante https://github.com/rack/rack/blob/master/lib/rack/request.rb .
L'algorithme qu'il suit consiste à vérifier d'abord le REMOTE_ADDR
à la recherche d'adresses IP non fiables, et s'il en trouve, il choisit l'adresse IP la plus fiable. premier une liste. Dans ce cas, les adresses IP "de confiance" sont des adresses IP provenant de la liste des adresses IP de l'Union européenne. plages de sous-réseaux privés réservés mais notez qu'il s'agit d'une correspondance par regex, ce qui n'est probablement pas la meilleure façon de procéder. S'il n'y a pas de REMOTE_ADDR
puis il consulte le HTTP_X_FORWARDED_FOR
et choisit l'en-tête dernier non fiable répertoriée. Si aucune de ces listes ne révèle la présence de quelqu'un, le système revient à la méthode brute. REMOTE_ADDR
qui est probablement 127.0.0.1.
requête.remote_ip
request.remote_ip
est une détection améliorée de l'IP fournie par ActionDispatch::Request
(qui hérite de Rack::Request
). Il s'agit du code présenté dans la question. Comme vous pouvez le voir, il revient à request.ip
sauf si action_dispatch.remote_ip
est défini sur le @env
. C'est ce que fait le RemoteIp
qui est inclus dans la pile Rails par défaut. Vous pouvez consulter ses sources à l'adresse suivante https://github.com/rails/rails/blob/4-2-stable/actionpack/lib/action_dispatch/middleware/remote_ip.rb .
En RemoteIp
s'il est activé, offre ces fonctionnalités supplémentaires :
- Détection facultative mais par défaut de l'usurpation d'adresse IP.
- Permet de filtrer les adresses proxy de configuration au lieu de s'appuyer uniquement sur les valeurs par défaut.
- Utilise le
IPAddr
pour tester correctement les plages d'adresses IP au lieu de s'appuyer sur des expressions rationnelles.
- Utilisations
HTTP_CLIENT_IP
comme source de PI potentiels.
L'algorithme est similaire à request.ip
mais légèrement différent. Il utilise HTTP_X_FORWARDED_FOR
de la dernière à la première place, puis HTTP_CLIENT_IP
de la dernière à la première, puis enfin la dernière entrée de REMOTE_ADDR
. Il les place tous dans une liste et filtre les proxies, en choisissant le premier qui reste.
Détection de l'usurpation d'adresse IP
La détection de l'usurpation d'adresse IP fournie par RemoteIp
n'est pas particulièrement puissant, tout ce qu'il fait est de lever une exception si la dernière valeur de HTTP_CLIENT_IP
n'est pas dans HTTP_X_FORWARDED_FOR
. Ce n'est pas nécessairement le symptôme d'une attaque, mais c'est probablement le symptôme d'une mauvaise configuration ou d'un mélange de proxies utilisant des conventions différentes qui ne produisent pas un résultat cohérent.
Quels sont les choix à faire ?
Dans une configuration simple où vos serveurs mandataires sont tous locaux ou sur des sous-réseaux privés, vous pouvez probablement vous contenter de request.ip
mais request.remote_ip
devrait être considéré comme le meilleur choix en général. Si vous utilisez des proxys avec un routage internet public (comme c'est le cas pour de nombreux CDN), alors RemoteIp
peut être configuré pour vous donner des adresses IP correctes dès le départ, alors que request.ip
ne sera correcte que si vous parvenez à faire en sorte que votre proxy en amont définisse REMOTE_ADDR
correctement.
Configuration sécurisée
Je réponds maintenant à la remarque de Tim Coulter sur le spoofing. Il a tout à fait raison de s'inquiéter, mais il a tort de dire que vous pouvez être spoofé si vous êtes derrière nginx ou haproxy par défaut. RemoteIp
est conçu pour empêcher l'usurpation d'identité en choisissant l'option dernier IP dans la chaîne. Les X-Forwarded-For spécifie que chaque mandataire ajoute l'adresse IP du demandeur à la fin de la chaîne. En filtrant les mandataires figurant sur la liste blanche, la dernière entrée est garantie être l'IP du client écrite par votre premier mandataire figurant sur la liste blanche. Il y a bien sûr une mise en garde, à savoir que vous devez utiliser un proxy qui définit/ajoute toujours X-Forwarded-For
Le conseil de Tim devrait donc être le contraire : n'utiliser que des request.remote_ip
lorsque vous sont l'exécution d'un proxy.
Comment configurer des proxy IP publics ?
C'est bien beau, mais ActionDispatch::RemoteIp
se trouve déjà dans la pile d'intergiciels par défaut. Comment la reconfigurer pour ajouter les CIDRs de mon proxy ?
Ajoutez ceci à votre 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