Яка різниця між request.remote_ip та request.ip у Rails?


75

Як випливає з назви, ви можете отримати 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

але я насправді не знаю наслідків.

Відповіді:


43

Від джерела:

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 :: Request виглядає так

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.


11
З мого досвіду, навіть незважаючи request.remote_ipна те, що він переглядає ланцюжок HTTP_X_FORWARDED_FOR, він все одно може бути підроблений, якщо у вас є Rails позаду nginx або haproxy. У nginx використовуйте proxy_set_header X-Forwarded-For $remote_addr;замість proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;. В останньому випадку curl -H "X-Forwarded-For: 6.66.6.66" http://example.comвидасть request.remote_ip6.66.6.66, який буде підробляти будь-яку перевірку ip, яку ви маєте в Rails.
Тім Коултер

84

request.ipповертає клієнта, ipнавіть якщо цей клієнт є проксі-сервером.

request.remote_ipрозумніший і отримує фактичного клієнта ip. Це можна зробити, лише якщо всі проксі-сервери на цьому шляху встановлюють заголовок X-Forwarded-For .


56

request.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заголовок і вибирає останній недовірений із перерахованих. Якщо жодне з них нікого не виявляє, воно повертається до вихідного, REMOTE_ADDRщо, ймовірно, є 127.0.0.1.

request.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Проміжний шар , якщо включена надає наступні додаткові можливості:

  • Забезпечує необов’язкове виявлення підміни IP, але за замовчуванням.
  • Дозволяє фільтрувати адреси проксі-сервера конфігурації, а не покладатися лише на за замовчуванням.
  • Використовує IPAddrклас для фактичного тестування діапазонів IP належним чином, замість того, щоб покладатися на крихке регулярне вираження.
  • Використовує HTTP_CLIENT_IPяк джерело потенційних ІВ.

Алгоритм схожий на, 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в цілому це слід вважати вищим вибором. Якщо ви використовуєте проксі-сервери із загальнодоступною маршрутизацією в Інтернеті (наприклад, багато CDN), то RemoteIpїх можна налаштувати так, щоб вони надавали вам коректні IP-адреси клієнтів, тоді як request.ipвони будуть правильними лише в тому випадку, якщо ви зможете REMOTE_ADDRправильно встановити ваш проксі-сервер .

Безпечна конфігурація

Тепер звернімось до коментаря Тіма Коултера щодо підробки. Він точно має рацію, якщо вас це турбує, але він помиляється, що вас можуть підманути, якщо за замовчуванням ви перебуваєте за nginx або haproxy. RemoteIpпризначений для запобігання спуфінгу шляхом вибору останнього ІР у ланцюжку. Специфікація X-Forwarded-For вказує, що кожен проксі додає IP-адресу запитувача до кінця ланцюжка. Фільтруючи проксі-сервери з білого списку, останнім записом гарантовано буде IP-адреса клієнта, записана вашим першим проксі-сервером із білого списку. Існує один нюанс, звичайно, що це те , що ви повинні на насправді бути запущений проксі - сервер , який завжди набори / приєднує X-Forwarded-For, тому рада Тіма повинен бути на самому ділі навпаки: тільки використовувати , request.remote_ipколи ви будете запущений проксі - сервер.

Як налаштувати для загальнодоступних IP-проксі

Це все добре і добре, але ActionDispatch::RemoteIpце вже є в стеку проміжного програмного забезпечення за замовчуванням. Як переналаштувати його, щоб додати мої проксі CIDR ?!

Додайте це до свого 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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.