В чем разница между запросом.удаленный ip и запрос.ip в рельсах?


как следует из названия, вы можете получить ip клиента с помощью обоих методов. Интересно, есть ли какие-то различия. Спасибо.

в исходном коде идет

"/usr/местные/РВМ/драгоценные камни/рубин-1.9.3-p194/драгоценные камни/actionpack-3.2.3/Либ/действий _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 55

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 middleware. Вы можете видеть в источнике этого промежуточного программного обеспечения, что он проверяет атаки спуфинга при вызове, так как он вызывает 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.

The RemoteIp middleware если включено предоставляет эти дополнительные особенности:

  • обеспечивает необязательное, но по умолчанию обнаружение 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 можно настроить, чтобы дать вам правильный IP-адрес клиента из коробки, в то время как request.ip будет исправьте, если вы можете получить свой восходящий прокси для установки REMOTE_ADDR правильно.

Безопасная Конфигурация

теперь обратимся к комментарию Тима Коултера о спуфинге. Он определенно прав, вы должны быть обеспокоены, но он ошибается, что вас можно обмануть, если вы по умолчанию стоите за nginx или haproxy. RemoteIp предназначен для предотвращения спуфинга выбрав последние IP в сети. Элемент X-Forwarded-For spec указывает, что каждый прокси-сервер добавляет IP-адрес инициатора запроса до конца цепочки. При фильтрации прокси-серверов из белого списка последняя запись гарантированно будет IP-адресом клиента, записанным вашим первым прокси-сервером из белого списка. Конечно, есть одно предостережение, которое заключается в том, что вы должны на самом деле запускать прокси-сервер, который всегда устанавливает/добавляет X-Forwarded-For, поэтому совет Тима на самом деле должен быть противоположным: используйте только request.remote_ip когда вы are запуск прокси-сервера.

как настроить для публичных IP Прокси

это все нормально и хорошо, но ActionDispatch::RemoteIp уже находится в стеке промежуточного программного обеспечения по умолчанию. Как перенастроить его, чтобы добавить мои прокси 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