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. Merci.
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 la 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
Alors remote_ip
donne la priorité à action_dispatch.remote_ip
. Cela est défini par ActionDispatch::RemoteIp
middleware. 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 depuis remote_ip
lit l'adresse IP même via les proxys locaux, comme l'explique Clowerweb.
request.ip
renvoie le client ip
même si ce client est un proxy.
request.remote_ip
est plus intelligent et obtient le client réel ip
. Cela ne peut être fait que si tous les mandataires en cours de route définissent l'en-tête X-Forwarded-For .
request.ip
Est la détection IP de base fournie par Rack::Request
Hors de la boîte. Sa définition actuelle peut être trouvée à https://github.com/rack/rack/blob/master/lib/rack/request.rb .
L'algorithme qu'il suit consiste à vérifier d'abord l'en-tête REMOTE_ADDR
Pour toutes les adresses IP non fiables, et s'il en trouve, il choisit d'abord le un répertorié. Les adresses IP "approuvées" dans ce cas sont des adresses IP des plages de sous-réseaux privés réservés , mais notez qu'elles correspondent par 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-tête HTTP_X_FORWARDED_FOR
Et sélectionne le dernier non approuvé de la liste. Si aucun de ceux-ci ne révèle personne, cela revient au brut REMOTE_ADDR
Qui est probablement 127.0.0.1.
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 affiché dans la question. Comme vous pouvez le voir, il revient à request.ip
Sauf si action_dispatch.remote_ip
Est défini sur le @env
. Cela se fait par le middleware RemoteIp
, qui est inclus dans la pile par défaut Rails. Vous pouvez voir sa source sur 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 ces fonctionnalités supplémentaires:
IPAddr
pour tester correctement les plages IP au lieu de s'appuyer sur une expression rationnelle fragile.HTTP_CLIENT_IP
Comme source d'adresses IP potentielles.L'algorithme est similaire à request.ip
Mais légèrement différent. Il utilise HTTP_X_FORWARDED_FOR
Du dernier au premier, puis HTTP_CLIENT_IP
Du dernier au premier, puis enfin la dernière entrée de REMOTE_ADDR
. Il met tous ces éléments dans une liste et filtre les proxys, en choisissant le premier restant.
La détection d'usurpation d'adresse IP fournie par RemoteIp
n'est pas particulièrement puissante, elle ne fait que lever 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.
Dans une configuration simple où vos mandataires sont tous locaux ou sur des sous-réseaux privés, vous pouvez probablement vous en tirer avec request.ip
, Mais request.remote_ip
Devrait être considéré comme le choix supérieur en général. Si vous utilisez des proxys avec un routage Internet public (tels que de nombreux CDN), RemoteIp
peut être configuré pour vous donner des IP client correctes, tandis que request.ip
Ne sera correct que si vous le pouvez demandez à votre proxy en amont de définir correctement REMOTE_ADDR
.
Maintenant, pour répondre au commentaire de Tim Coulter sur l'usurpation d'identité. Il a certainement raison, vous devriez vous inquiéter, mais il a tort que vous puissiez être usurpé si vous êtes derrière nginx ou haproxy par défaut. RemoteIp
est conçu pour empêcher l'usurpation d'identité en choisissant la dernière IP de la chaîne. La spécification X-Forwarded-For spécifie que chaque proxy ajoute l'IP du demandeur à la fin de la chaîne. En filtrant les proxys sur liste blanche, la dernière entrée est garantie comme l'adresse IP du client écrite par votre premier proxy sur liste blanche. Il y a bien sûr une mise en garde, à savoir que vous devez en fait exécuter un proxy qui définit/ajoute toujours X-Forwarded-For
, Donc les conseils de Tim devraient en fait être opposés: utilisez uniquement request.remote_ip
Lorsque vous exécutent un proxy.
C'est bien beau, mais ActionDispatch::RemoteIp
Est déjà dans la pile middleware par défaut. Comment le reconfigurer pour ajouter mes CIDR 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