класс ActionDispatch::RemoteIp
Этот промежуточный обработчик вычисляет IP-адрес удалённого клиента, который делает запрос. Он делает это, проверяя различные заголовки, которые могут содержать адрес, и затем выбирая последний установленный адрес, который не находится в списке доверенных IP-адресов. Это следует за прецедентом, установленным, например, сервером Tomcat, с подробным объяснением обоснования @gingerlime. Более подробное объяснение алгоритма приведено в ActionDispatch::RemoteIp::GetIp#calculate_ip.
Некоторые Rack-серверы конкатенируют повторяющиеся заголовки, как требует HTTP RFC 2616. Некоторые Rack-серверы просто отбрасывают предыдущие заголовки и сообщают только значение, которое было указано в последнем заголовке. Если вы находитесь за несколькими прокси-серверами (например, NGINX к HAProxy к Unicorn), вам следует протестировать ваш Rack-сервер, чтобы убедиться, что ваши данные корректны.
ЕСЛИ ВЫ НЕ ИСПОЛЬЗУЕТЕ ПРОКСИ, ЭТО ДЕЛАЕТ ВАС УЯЗВИМЫМИ К ПОДМЕНЕ IP-АДРЕСА. Этот промежуточный обработчик предполагает, что существует по крайней мере один прокси, устанавливающий заголовки с IP-адресом удалённого клиента. Если вы не используете прокси, например, размещаясь на Heroku без SSL, любой клиент может заявить об любом IP-адресе, установив заголовок X-Forwarded-For. Если вам это важно, то вам необходимо явно отбросить или проигнорировать эти заголовки до запуска этого промежуточного обработчика.
Константы
- TRUSTED_PROXIES
-
Список доверенных IP-адресов по умолчанию просто включает IP-адреса, которые гарантированно являются частными адресами в соответствии со спецификацией IP. Они не будут конечными IP-адресами клиента в производстве и поэтому отбрасываются. Подробности см. в en.wikipedia.org/wiki/Private_network.
Атрибуты
Публичные методы класса
# File actionpack/lib/action_dispatch/middleware/remote_ip.rb, line 62
def initialize(app, ip_spoofing_check = true, custom_proxies = nil)
@app = app
@check_ip = ip_spoofing_check
@proxies = if custom_proxies.blank?
TRUSTED_PROXIES
elsif custom_proxies.respond_to?(:any?)
custom_proxies
else
Array(custom_proxies) + TRUSTED_PROXIES
end
end Создать новый RemoteIp экземпляр промежуточного обработчика.
Опция ip_spoofing_check включена по умолчанию. При включении, возникает исключение, если кажется, что клиент пытается солгать об собственном IP-адресе. Имеет смысл отключить эту проверку на сайтах, ориентированных на клиентов, не использующих IP (например, устройства WAP), или за прокси-серверами, которые устанавливают заголовки неправильно или запутанно (например, AWS ELB).
Аргумент custom_proxies может принимать массив строк, объектов IPAddr или Regexp, которые будут использоваться вместо TRUSTED_PROXIES. Если предоставлен одиночная строка, объект IPAddr или Regexp, он будет использован дополнительно к TRUSTED_PROXIES. Любая настройка прокси поместит желаемое значение в середину (или в начало) списка X-Forwarded-For, с вашими прокси-серверами после него. Если ваши прокси не удаляются, передайте их через параметр custom_proxies. Таким образом, промежуточный обработчик проигнорирует эти IP-адреса и вернёт нужный вам.
Публичные методы экземпляра
# File actionpack/lib/action_dispatch/middleware/remote_ip.rb, line 78 def call(env) req = ActionDispatch::Request.new env req.remote_ip = GetIp.new(req, check_ip, proxies) @app.call(req.env) end
Поскольку IP-адрес может не потребоваться, мы храним здесь объект без вычисления IP, чтобы не замедлять большинство запросов. Для запросов, которым нужен IP-адрес, метод ActionDispatch::RemoteIp::GetIp#calculate_ip вычислит кэшированный IP-адрес клиента.
© 2004–2018 David Heinemeier Hansson
Licensed under the MIT License.