В чем разница между запросом.удаленный 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