В чем разница между запросом.удаленный ip и запрос.ip в Rails?
по мере того как заголовок идет, вы можете получить ip клиента с обоими методами. Интересно, есть ли какие-то различия? Спасибо.
в исходном коде идет
" / 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
но я действительно не знаю последствий.
3 ответов
из источника:
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
где Rack:: запрос выглядит так
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
так remote_ip
отдает предпочтение action_dispatch.remote_ip
. Это устанавливается ActionDispatch::RemoteIp
промежуточное. Вы можете видеть в источнике этого промежуточного ПО, что он проверяет атаки спуфинга при вызове, так как он вызывает GetIp.new
чтобы установить эту переменную env. Это необходимо, так как remote_ip
читает ip-адрес даже через локальные прокси, как объясняет Clowerweb.
request.ip
возвращает клиенту ip
даже если этот клиент является прокси.
request.remote_ip
умнее и получает реальный клиент ip
. Это можно сделать только в том случае, если все прокси по пути зададут X-Forwarded-For.
запрос.ip
request.ip
основное обнаружение ip обеспеченное Rack::Request
из коробки. Его текущее определение можно найти вhttps://github.com/rack/rack/blob/master/lib/rack/request.rb.
алгоритм он следует, чтобы сначала проверить REMOTE_ADDR
заголовок для любых ненадежных IP-адресов, и если он находит любой, он выбирает первый один в списке. "Доверенные" IP-адреса в этом случае являются IP-адресами из приватные диапазоны подсетей, но обратите внимание, что он соответствует регулярному выражению, что, вероятно, не лучший способ сделать это. Если нет ненадежных REMOTE_ADDR
затем он смотрит на HTTP_X_FORWARDED_FOR
заголовок, и выбирает последние недоверенный в списке. Если ни один из них не раскрывает никого, он возвращается к raw REMOTE_ADDR
вероятно 127.0.0.1.
запрос.remote_ip
request.remote_ip
увеличено обнаружение IP обеспеченное ActionDispatch::Request
(который наследует от Rack::Request
). Это код, показанный в вопросе. Как вы можете видеть, он возвращается к request.ip
если action_dispatch.remote_ip
на @env
. Это делается RemoteIp
промежуточное ПО, которое включено в стек Rails по умолчанию. Вы можете увидеть его источник на https://github.com/rails/rails/blob/4-2-stable/actionpack/lib/action_dispatch/middleware/remote_ip.rb.
на RemoteIp
промежуточное ПО, если включено, предоставляет эти дополнительные особенности:
- обеспечивает опционное но обнаружение spoofing IP значения по умолчанию.
- позволяет фильтровать прокси-адреса конфигурации вместо того, чтобы полагаться только на значения по умолчанию.
- использует
IPAddr
класс для проверки диапазонов IP правильно, а не полагаться на хрупкое регулярное выражение. - использует
HTTP_CLIENT_IP
как источник потенциальных IPs.
алгоритм похож на request.ip
но немного другой. Он использует HTTP_X_FORWARDED_FOR
из последних во-первых, тогда HTTP_CLIENT_IP
от последнего до первого, затем, наконец, последняя запись REMOTE_ADDR
. Он помещает их все в список и фильтрует прокси, выбирая первый оставшийся.
обнаружение подмены IP
обнаружение IP-спуфинга, предоставляемое RemoteIp
не особенно мощный, все, что он делает, это вызывает исключение, если последний HTTP_CLIENT_IP
не HTTP_X_FORWARDED_FOR
. Это не обязательно симптом атаки, но это, вероятно, симптом неправильной конфигурации или смеси прокси, использующие различные соглашения, которые не дают согласованного результата.
чтобы использовать
в простой настройке, где все ваши прокси-серверы являются локальными или в частных подсетях, вы, вероятно, можете уйти с request.ip
, а request.remote_ip
следует рассматривать главный выбор вообще. Если вы используете прокси с общедоступной интернет-маршрутизацией (например, многие CDNs), то RemoteIp
может быть настроен, чтобы дать вам правильный IPS клиента из коробки, тогда как request.ip
будет правильно, если вы можете получить свой восходящий прокси-сервер для установки REMOTE_ADDR
правильно.
Безопасная Конфигурация
теперь обратимся к комментарию Тима Колтера о спуфинге. Он определенно прав, вы должны быть обеспокоены, но он ошибается, что вы можете быть обмануты, если вы стоите за nginx или haproxy по умолчанию. RemoteIp
предназначен для предотвращения подмены, выбрав последние IP в сети. The X-Forwarded-For spec указывает, что каждый прокси-сервер добавляет IP-адрес запросчика до конца цепочки. Путем фильтрации в белый список прокси, последняя запись будет гарантированно клиентский IP написал свой первый белый список прокси. Конечно, есть одно предостережение: вы должны фактически запускать прокси-сервер, который всегда устанавливает/добавляет X-Forwarded-For
, поэтому совет Тима должен быть на самом деле противоположным: используйте только request.remote_ip
когда вы are запуск прокси-сервера.
как настроить для публичных IP-Прокси
это все нормально и хорошо, но ... --32--> уже находится в стеке промежуточного ПО по умолчанию. Как перенастроить его, чтобы добавить мои прокси CIDRs?!
добавьте это в ваш 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