Ticket #23 (new enhancement)
Поддержка HTTP заголовка X-Forwarded-For
| Reported by: | seroy | Owned by: | |
|---|---|---|---|
| Priority: | major | Component: | general |
| Version: | Keywords: | force_show_code | |
| Cc: |
Description
Реализация поддержки HTTP заголовка X-Forwarded-For. Необходимо для правильного определения IP бота в случаях когда веб-сервер стоит за прокси (mod_proxy, nginx, и т.д.), как альтернатива к force_show_code=true.
Писалось (и тестировалось) под использование совместно с Django, при использовании с другими фреймворками возможно необходимо допиливать передачу объекту PageRequest? в параметре meta элемента с ключем HTTP_X_FORWARDED_FOR.
Attachments
Change History
Changed 5 months ago by seroy
-
attachment
http_x_forwarded_for_support.2.patch
added
исправлен косяк при meta=None
comment:1 Changed 5 months ago by lostclus
Опять таки, добавленная фича не поддается контролю. А что если заголовок HTTP_X_FORWARDED_FOR присутствует, но его значение не верно, а вместо него нужно использовать значение из какого нибудь другого заголовка? Или нужно игнорировать HTTP_X_FORWARDED_FOR, и использовать обычный HTTP_REMOTE_ADDR. Я считаю лучше сделать параметр конфигурации, типа look_remote_addr_in_header, который будет задавать заголовок, или список заголовков в которых нужно искать IP-адрес, который в последствии будет присвоен атрибуту remote_addr. И чтоб не дублировать код такого выбора полей, может его вывести в класс PageRequest?
comment:2 follow-up: ↓ 3 Changed 5 months ago by seroy
Ну лично я считаю, что это уже некоторый перебор и перфекционизм, а лучшее оно, как известно враг хорошего. Что значит значение не в поле не верно? Во первых это значит, что он сам себе злой Буратино (и не умеет сервер нормально настраивать :) ), а во вторых код там достаточно простой (а как следствие надежный), ну даже если будет только один IP (у меня кстати так), а не список client1, proxy1, proxy2 ничего страшного не случится. Про нужно игнорировать: обычно такой заголовок на пустом месте не возникает, опять таки по моему надумано. Про другие заголовки: x-forwarded-for это уже сейчас стандарт де-факто, а в последствии скорее всего будет стандартный заголовок http://tools.ietf.org/html/draft-petersson-forwarded-for-02, кроме того в других заголовках не понятно какой может быть формат.
По моему это как раз тот случай когда "20% усилий дают 80% результата". Необходимо только толково написать в документации этот момент, чтобы было понятно как оно работает. А если вдруг у кого что то не так, а по другому - код открытый, всегда можно поправить.
НО, Вы безусловно автор и вольны делать так как считаете нужным. Я всего лишь привел контраргументы (не могу же я с вами взять и просто согласится)))). Можно пока оставить так, а если будет потребность подтвержденная практикой внедрения, то сделать более гибкое решение. В любом случае выбор за Вами.
comment:3 in reply to: ↑ 2 ; follow-up: ↓ 4 Changed 5 months ago by lostclus
Replying to seroy:
По моему это как раз тот случай когда "20% усилий дают 80% результата". Необходимо только толково написать в документации этот момент, чтобы было понятно как оно работает. А если вдруг у кого что то не так, а по другому - код открытый, всегда можно поправить.
По крайней мере должна быть стандартная возможность отключать использование X-Forwarded-For.
Еще я считаю, что всегда брать первый адрес не совсем правильно, так как это будет означать, что нужно "пропустить" все прокси сервера, и получить адрес самой первой машины, которая отправила запрос. Но возможность использования X-Forwarded-For была добавлена исходя из того, что само веб-приложение развернуто через прокси сервер, т.е. нам точно известно, что последний один адрес (или несколько адресов, например какой-то вид балансировки нагрузки) в заголовке это адрес нашего прокси-сервера. И мы не можем отвечать за все остальные прокси сервера, которые использовались для доступа к нашему ресурсу. Поэтому считаю, что правильнее будет дать возможность задавать число, которые будет означать сколько адресов нужно пропустить с конца списка, чтобы получить нужный адрес. В обычной конфигурации, когда используется обратный прокси, это число 1.
comment:4 in reply to: ↑ 3 Changed 5 months ago by lostclus
т.е. нам точно известно, что последний один адрес (или несколько адресов, например какой-то вид балансировки нагрузки) в заголовке это адрес нашего прокси-сервера. И мы не можем отвечать за все остальные прокси сервера, которые использовались для доступа к нашему ресурсу. Поэтому считаю, что правильнее будет дать возможность задавать число, которые будет означать сколько адресов нужно пропустить с конца списка, чтобы получить нужный адрес. В обычной конфигурации, когда используется обратный прокси, это число 1.
Небольшая поправка: последний адрес, это не адрес последнего прокси, а адрес машины "перед ним". Тогда, если сайт развернут с использованием одного обратного прокси, то нужно пропускать 0 адресов с конца, т.е. брать последний адрес, а если используется два обратных прокси, то тогда нужно пропустить 1 адрес.
comment:5 follow-up: ↓ 6 Changed 5 months ago by seroy <seroy@…>
Брать всегда первый адрес правильно (подробнее http://en.wikipedia.org/wiki/X-Forwarded-For). Нас интересует адрес клиента, а не адреса возможных прокси, адрес клиента это первый адрес (слева). При прохождении запроса через прокси адрес сервера добавляется в конец через запятую.
comment:6 in reply to: ↑ 5 ; follow-up: ↓ 7 Changed 5 months ago by lostclus
Replying to seroy <seroy@…>:
Брать всегда первый адрес правильно (подробнее http://en.wikipedia.org/wiki/X-Forwarded-For). Нас интересует адрес клиента, а не адреса возможных прокси, адрес клиента это первый адрес (слева). При прохождении запроса через прокси адрес сервера добавляется в конец через запятую.
Объясните пожалуйста почему нас интересует адрес клиента? Например, я захожу в интернет через прокси со своей рабочей машины 192.168.0.3, которая расположена за маршрутизатором, на котором работает Squid с настройками по умолчанию. Тогда в заголовке X-Forwarded-For первым будет адрес 192.168.0.3, а не реальный адрес маршрутизатора. И зачем нам серый адрес 192.168.0.3? Почему адрес, который должен видеть LinkExchange где-то на сервере должен зависит от топологии моей домашней сети, из которой я захожу на этот сервер?
А теперь допустим, что сапа перевела свои рабочие сервера за такой вот маршрутизатор, и решила использовать прокси. Код на PHP будет продолжать работать корректно, потому что он использует HTTP_REMOTE_ADDR, в котором указан адрес прокси, а не какой-то серый адрес клиента, от которого пользы нет никакой.
comment:7 in reply to: ↑ 6 Changed 5 months ago by seroy <seroy@…>
Пожалуй соглашусь с Вами, для LinkExchange? брать последний адрес до обратного прокси все таки более правильно.
