Quelle est la différence entre request.remote_ip et request.ip dans Rails?

Comme le titre l’indique, vous pouvez obtenir l’IP du client avec les deux méthodes. Je me demande s’il y a des différences. Je vous remercie.

dans le code source il va

“/usr/local/rvm/gems/ruby-1.9.3-p194/gems/actionpack-3.2.3/lib/action _dispatch/ http / request.rb” 257L, 8741C

def ip @ip ||= super end # Originating IP address, usually set by the RemoteIp middleware. def remote_ip @remote_ip ||= (@env["action_dispatch.remote_ip"] || ip).to_s end 

mais je ne connais vraiment pas les implications.

De source:

 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 

où Rack :: Request ressemble à ceci

 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'] # If forwarded_ips doesn't include the client_ip, it might be an # ip spoofing attempt, so we ignore 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 

Donc remote_ip donne la priorité à action_dispatch.remote_ip . Cela est défini par le middleware ActionDispatch::RemoteIp . Vous pouvez voir dans la source de ce middleware qu'il vérifie les attaques d'usurpation lors de son appel, car il appelle GetIp.new pour définir cette variable env. Cela est nécessaire car remote_ip lit l'adresse IP, même à travers les proxys locaux, comme l'explique Clowerweb.

request.ip renvoie l’ ip du client même si ce client est un proxy.

request.remote_ip est plus intelligent et obtient l’ ip client réel. Cela ne peut être fait que si tous les mandataires le long de la route définissent l’en – tête X-Forwarded-For .

request.ip

request.ip est la détection ip de base fournie par Rack::Request hors de la boîte. Sa définition actuelle se trouve à l’ adresse https://github.com/rack/rack/blob/master/lib/rack/request.rb .

L’algorithme ci-dessous consiste à vérifier d’abord l’en REMOTE_ADDR tête REMOTE_ADDR pour toute adresse IP non approuvée, et s’il en trouve, il choisit la première . Les adresses IP “de confiance” dans ce cas sont des adresses IP provenant des plages de sous-réseaux privés réservés , mais notez que cela correspond à une expression régulière qui n’est probablement pas la meilleure façon de le faire. S’il n’y a pas de REMOTE_ADDR non approuvé, il examine l’en HTTP_X_FORWARDED_FOR tête HTTP_X_FORWARDED_FOR et sélectionne le dernier non fiable répertorié. Si aucun de ceux-ci ne révèle personne, il revient au REMOTE_ADDR brut qui est probablement 127.0.0.1.

request.remote_ip

request.remote_ip est une détection IP améliorée fournie par ActionDispatch::Request (qui hérite de Rack::Request ). C’est le code indiqué dans la question. Comme vous pouvez le voir, il revient à request.ip sauf si action_dispatch.remote_ip est défini sur @env . Cela est fait par le middleware RemoteIp , qui est inclus dans la stack Rails par défaut. Vous pouvez voir sa source à l’ adresse https://github.com/rails/rails/blob/4-2-stable/actionpack/lib/action_dispatch/middleware/remote_ip.rb .

Le middleware RemoteIp s’il est activé, fournit les fonctionnalités supplémentaires suivantes:

  • Fournit une détection optionnelle mais par défaut de l’usurpation d’adresse IP.
  • Permet de filtrer les adresses proxy de configuration au lieu de se fier uniquement aux valeurs par défaut.
  • Utilise la classe IPAddr pour tester correctement les plages d’adresses IP au lieu d’ IPAddr fragile.
  • Utilise HTTP_CLIENT_IP comme source d’IP potentielles.

L’algorithme est semblable à request.ip mais légèrement différent. Il utilise HTTP_X_FORWARDED_FOR de dernier à premier, puis HTTP_CLIENT_IP de dernier à premier, puis finalement la dernière entrée de REMOTE_ADDR . Il place tous ces éléments dans une liste et filtre les proxies, en sélectionnant le premier.

Détection IP Spoofing

La détection de l’usurpation d’adresse IP fournie par RemoteIp n’est pas particulièrement puissante, elle ne fait que HTTP_CLIENT_IP une exception si le dernier 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 mandataires utilisant différentes conventions qui ne produisent pas un résultat cohérent.

Qui utiliser

Dans une configuration simple où vos proxies sont tous locaux ou sur des sous-réseaux privés, vous pouvez probablement vous en sortir avec 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 (tel que de nombreux CDN), RemoteIp peut être configuré pour vous donner des adresses IP client RemoteIp , alors que request.ip ne sera correct que si vous pouvez obtenir que votre proxy amont définisse REMOTE_ADDR correctement. .

Configuration sécurisée

Maintenant, répondez au commentaire de Tim Coulter au sujet de l’usurpation. Il a certainement raison de vous inquiéter, mais il a tort de vous faire passer pour un usurpateur si vous êtes derrière nginx ou haproxy par défaut. RemoteIp est conçu pour empêcher l’usurpation d’ RemoteIp en choisissant la dernière adresse IP de la chaîne. La spécification X-Forwarded-For spécifie que chaque proxy ajoute l’adresse IP du demandeur à la fin de la chaîne. En filtrant les proxies en liste blanche, la dernière entrée est garantie comme étant l’adresse IP du client écrite par votre premier proxy avec liste blanche. Bien sûr, il y a une mise en garde: vous devez exécuter un proxy qui définit / ajoute toujours X-Forwarded-For , donc les conseils de Tim doivent être opposés: n’utilisez que request.remote_ip lorsque vous exécutez un proxy.

Comment configurer les proxys IP publics

C’est très bien, mais ActionDispatch::RemoteIp est déjà dans la stack de middleware par défaut. Comment le reconfigurer pour append mes proxy CIDR?!

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