get real ip php
Как в PHP узнать IP пользователя и определить его страну?
В этой статье рассмотрим, как в PHP можно узнать IP клиента и сервера, а также разберём как зная IP клиента определить его страну и город.
Как в PHP получить IP адрес посетителя сайта
Определение страны по ip с помощью Sypex Geo
Основные шаги по созданию php скрипта, с помощью которого можно будет определять страну по ip:
1. Скачаем Sypex Geo для PHP и базу данных стран. Sypex Geo распространяется по лицензии BSD, т.е. является абсолютно бесплатным.
2. Распакуем архивы и загрузим на сервер файлы «SxGeo.php» и «SxGeo.dat». В качестве примера, создадим на сервере папку SxGeo и загрузим эти файлы в неё.
3. Создадим свой скрипт, например, «get_country_code.php».
4. Вставим в этот файл следующий код:
5. Включим файл «get_country_code.php» в другие скрипты, в которых нужно реализовать выполнение кода в зависимости от принадлежности ip посетителя к той или иной стране.
Определение города по ip с помощью Sypex Geo
Для определения города, потребуется загрузить архив с базой данных городов для Sypex Geo, распаковать его и загрузить на сервер.
Скрипт в этом случае будет следующий:
Для автоматического обновления баз можно воспользоваться этим архивом. В этом архиве находится php скрипт. Этот скрипт необходимо настроить, т.е. указать в нём URL для скачивания базы и пути к файлам на сервере. После этого загрузить его на сервер и настроить его запуск по расписанию с помощью cron.
Определение страны и города по ip через сервис через сервис ipstack
Рассмотрим ещё один вариант определения в php местоположения по ip посетителя, но уже не через Sypex Geo, а с помощью сервиса ipstack.
Сервис ipstack имеет бесплатный план, который позволяет обрабатывать до 10000 запросов в месяц.
Для получения бесплатного плана нажимаем на кнопку «GET FREE API KEY» и переходим на страницу, на которой нужно заполнить регистрационную карточку.
После регистрации, на личной странице ipstack вам будет назначен «API Access Key», который нужно скопировать. Он нам потребуется при создании php скрипта.
Как в PHP получить IP адрес сервера
Узнать IP адрес сервера в PHP можно с помощью следующей инструкции:
Пример реализации определения локации в CMS MODX
В качестве примере рассмотрим, как в CMS MODX Revolution можно очень просто без сторонних сервисов осуществить определение страны посетителя. Разработаем решение на базе Sypex Geo.
1. Для этого сначала нужно загрузить Sypex Geo в проект:
Файл «SxGeo.php» – это основной скрипт, а «SxGeo.dat» – это база стран. Этих двух файлов достаточно для определения страны пользователя по его ip. Дополнительно в каталоге SxGeo ещё расположен файл «SxGeoCity.dat», данный файл в текущей реализации не нужен, он может потребовать, если в проекте потребуется определять не только страну пользователя, а ещё его регион и город.
2. Создадим сниппет, например «get_location.php». В качестве примера организуем это с помощью файлов. Для этого нужно чтобы был установлен pdoTools и в настройках включена опция «Использовать Fenom на страницах».
Код сниппета «get_location.php»:
Всё теперь чтобы написать логику достаточно использовать эту переменную.
How to get real IP of user using PHP? [duplicate]
I’ve been trying to get real IP address of the user, and not a proxy address. For that I’ve done this:
But when a user is using proxy, the above script gets the proxy address and not the real IP address:
Is there any way to get real IP just like whatismyip.com tells (it tells real IP address, proxy address and useragent)?
How come it gathers all the details so accurately but not my PHP script?
2 Answers 2
But even that is not 100%. Getting IP of the real user now a days is not a guarantee with so many NAT firewalls in between, let alone proxies.
Edit
To answer your edit as to how they show you more information, you could use many features of the language to get more request details. For example try
Then you can also use
And extract the required information from there.
Edit 2
Even your favorite whatismyip.com reports
Your IP Location can be found using our IP Lookup tool. No IP Lookup tool is 100% accurate due to many different factors. Some of those factors include where the owner of the IP has it registered, where the agency that controls the IP is located, proxies, cellular IPs, etc. If you are in the US and the controlling agency of the IP is located in Canada, chances are the IP address lookup results will show as Canada. Showing a Canadian IP while in the US is very common among Blackberry users on the Verizon network.
You might still ask ok then why cant I get at least what they show? Im sure they have put up a lot of research and resources in setting up that tool, its not a one line PHP code, in fact there is no telling whether that site is written in PHP at all. Some more research and you will be on your way to try to match their lookup.
Гормональный holywar Админа и Разраба PHP или REMOTE_ADDR vs HTTP_X_FORWARDED_FOR
Давеча был свидетелем одного интересного спора о том как же действительно нужно определять IP адрес конечного пользователя из скриптов PHP.
Собственно, каждое слово сабжа отображает действительную ситуацию. Это был религиозный спор, обострённый весенней замечательной погодой, в котором, я считаю, не оказалось правых и не правых, но который побудил меня к мини-исследованию и, к моему счастью, поставил точку в понимании этого конфессионального но по факту очень простого вопроса.
Для тех, кто как и я сомневался был уверен, что во всём разобрался, но боялся спросить лень было разбираться в мелочах — под кат.
Предыстория
Занимаясь разработкой VOD сервиса для Samsung SmartTV платформы нам непременно нужно знать страну пользователя, чтобы вдруг нечаянно не показать счастливому пользователю фильм там, где запрещает правообладатель… А ведь за нарушение данного условия договора идут не детские штрафы в тысячах долларов (при чем за каждый факт такой оплошности).
[Вопрос, как заметили в комментариях, Юридический, и мошенничество возможно, но статья даже не о том как постараться предотвратить такие мошенничества, а о том как правильно подружить php и nginx]
На сервере имеем следующее: php-fpm+nginx
Как определить страну? Ну естественно через IP пользователя и GEO IP базу maxmind
«Пффф. » — подумалось нам всем мне — да проще простого. И дабы не писать свой велосипед, нагуглил на stackoverflow, даже вник в каждую строчку, прикрутил и оставил как там и росло код:
И всё работало! Почти год… пока не случилось кое-что неожиданное. Естественно неожиданное для этого кода…
Как запутать php или цепочка прокси(всё ещё часть предыстории)
Всё сломалось! А случилось это когда нам пришлось прикручивать одну из платёжных систем и весь этот код рухнул от того, что в HTTP_X_FORWARDED_FOR пришёл не один адрес, а список адресов через запятую (что строго говоря законно, допустимо, и даже не регламентировано в доке по php)
И никто бы ничего не заметил, если бы HTTP_X_REAL_IP или HTTP_CLIENT_IP(которые тоже не регламентирован докой) содержали искомый IP, но увы они были пусты 🙁
«Ну ладно» — подумали мы(теперь я был уже не один) перепишем всё и попросим админов запихивать пользовательский IP в переменную REMOTE_ADDR:
И всё работало! Почти месяц… пока не случилось кое-что неожиданное. Естественно неожиданное для этого кода…
Весенний спор крутых мужиков(это не ирония — они крутые)
Всё сломалось! А случилось это потому, что нам нужно было обновить nginx. И мы обратились к профессионалам в этом деле — к нашим админам.
А те в свою очередь решили обновить и конфиг избавившись от нашего «костыля/не костыля» (пока мы этого не поняли) с пробросом в REMOTE_ADDR.
REMOTE_ADDR оставили без изменения т.е. там теперь светилось что-то типа «127.0.0.1»
в HTTP_X_FORWARDED_FOR прокинули IP пользователя (который между делом с лёгкостью удалось переопределить отправкой из браузера заголовка `x-forwarded-for: 999.999.999.999`)
И тут понеслось — Р=Разраб, А=Админ:
А: у вас всё сломалось, и поскольку мы имеем nginx-прокси то нужный вам адрес лежит в HTTP_X_FORWARDED_FOR а в REMOTE_ADDR будет лежать реальный IP сдресс клиента к php-fpm (т.е. 127.0.0.1)
Р: но мы не можем верить HTTP_X_FORWARDED_FOR, ведь это переменная, которую с лёгкостью можно переопределить через заголовок к серверу, ссылаясь на давольно интересную статью
А: нет, мы сделаем так что в ней будет лежать реальный IP конечного пользователя, а в REMOTE_ADDR реальный адрес клиента к php
Р: тогда мы не проследим последовательность проксей, и всё равно для универсализации на другом сервере (скажем без прокси) эти конфиги могут быть не правдивыми пихайте всё в REMOTE_ADDR который в любом случае будет работать.
… это кратко и без матов…
По итогу то конечно всё завелось… и остановились на прозрачном проксировании, когда php думает, что к нему подключаются напрямую клиенты безо всяких проксей и все переменные(точнее одна на которую мы обращаем внимание) в нужном нам состоянии.
Однако не хватает фэншуя в этом деле и по факту у нас ведь есть прокся а может и не одна.
Кто виноват из них кто прав
Судить не нам, но никто!
Если мы имеем действительно кучу клиентов напрямую к php, или прозрачное проксирование то всё просто — юзай REMOTE_ADDR на здоровье и наслаждайся.
Но как быть с фэншуем и где что должно лежать, если мы используем нормальное проксирование и хотим чтобы об этом знал PHP?
Рецепт… но не панацея:
Казалось бы ну в чем проблема парсить эту переменную и доставать оттуда последний элемент. Но в нашем случае настройки не были до конца корректными и весь HTTP_X_FORWARDED_FOR заменялся заголовком от браузера x-forwarded-for, а должен был приклеивать к нему реальный IP непосредственного пользователя.
Для примера проверил на промышленном vps хостинге:
Доверять таким данным тоже страшновато, но если всё правильно сделано в настройках то последним IP будет адресс пользователя, вне зависимости от того что придёт в заголовках.
В заключении
PS
Позже мы наведём фэншуй в настройках и избавимся от прозрачного проксирования, а так же напишем универсальную функцию определения IP для обоих случаев проксирования.
PPS
Ради фана кому интересно: если кто-то в комментариях напишет эту функцию и конфиг nginx за нас и мы её будем использовать, то под честное слово, тот получит 100р на телефон.
Но эта функция и конфиг должны быть во истину православными и учитывать всё 🙂 все зацепки есть в статье.
Главное — дзен: не торопитесь — вдруг первые напишут с ошибками и вы их учтёте, торопитесь — вдруг первый правильный ответ будет до Вас.
Всем спасибо. Хорошей весны! Договаривайтесь с коллегами и любите их! 🙂
PHP get real IP (proxy detection)
I do get track the «real» IP of an user, if he has an proxy wich sends the header of the real IP. does any of have a better solution, or even more headers?
Since this function is used very often in the script, it has to be very fast, and it does not seem in that constellation :/
A few suggestions I came up with, but could not realise:
2 Answers 2
If the proxy sends a header then you can fetch the original IP of the client. If the proxy doesn’t, then you can’t. Unfortunately (Or maybe fortunately depending on your perspective) it’s as simple as that.
You can also set an exclude list in the browser.
the regex validation would fail for ipv6 addresses; so I would rather remove that (or try to find a better RegEX).
also stripos($proxy_header_temp, ‘:’) would lead to a not expected behaivour for example for «::1» (localhost, ipv6).
my suggestion with mentioned modifications:
Not the answer you’re looking for? Browse other questions tagged php proxy detection or ask your own question.
Linked
Related
Hot Network Questions
Subscribe to RSS
To subscribe to this RSS feed, copy and paste this URL into your RSS reader.
site design / logo © 2021 Stack Exchange Inc; user contributions licensed under cc by-sa. rev 2021.9.16.40232
By clicking “Accept all cookies”, you agree Stack Exchange can store cookies on your device and disclose information in accordance with our Cookie Policy.
PHP most accurate / safe way to get real user IP address in 2017
What is the most accurate way to get user’s IP address in 2017 via PHP?
I’ve read a lot of SO questions and answers about it, but most of answers are old and commented by users that these ways are unsafe.
For example, take a look at this question (2011): How to get the client IP address in PHP?
Tim Kennedy’s answer contains a recommendation to use something like:
But as I’ve read a lot, I have seen that to use X_FORWARDED_FOR is unsafe, as the comment below highlights:
Do NOT use the above code unless you know EXACTLY what it does! I’ve seen MASSIVE security holes due to this. The client can set the X-Forwarded-For or the Client-IP header to any arbitrary value it wants. Unless you have a trusted reverse proxy, you shouldn’t use any of those values.
As I didn’t know EXACTLY what it does, I don’t want to take the risk. He said it is unsafe, but did not provide a safe method to get user’s IP address.
So do you have any ideas?
10 Answers 10
Short answer:
All the variables prefixed with HTTP_ are in fact HTTP headers sent by the client, and there there’s no other way to transfer that information while requests pass through different servers.
But that of course automatically means that clients can spoof those headers.
You can never, ever trust the client.
You have to collaborate with your sysops team (or if you’re wearing that hat too, you will need to do some research). The header check is used when your network infrastructure is configured in certain ways where the remote requester is one of your network appliances instead of the end user.
This sort of thing happens when your web server(s) sit behind a load balancer or firewall or other appliance that needs to interrogate the payload to properly handle it. An example is when a load balancer terminated ssl and forwards the request on to the web server without ssl. When this occurs the remote address becomes the load balancer. It also happens with firewall appliances that do the same thing.
Most instances the device will offer configuration to set a header value in the request with the original remote ip address. The header is usually what you’d expect but it can in some cases be different or even configurable.
What’s more, depending on your web server configuration (apache, nginx or other) may not support or be currently configured to support certain custom headers such as the common ip header.
The point is us you will need to investigate your network configuration to ensure that the original requester’s ip makes it all the way through to your application code and in what form.
If you’d like to use a pre-built library, you can use Whip.
Using pre-made libraries are usually better because most of them will have been checked thoroughly by an active community. Some of them, especially the ones that have been around for a long time, have more features built-in.
But if you want to code it yourself to learn the concept, then it’s ok I guess. I recommend packaging it as a stand alone library and releasing it as open-source 🙂
EDIT: I do not recommend using the remote IP in security mechanisms as they are not always reliable.
First, it is impossible to reliably determine someone’s source IP address if they are intent on being hidden. Even something which today seems foolproof, will soon have a loophole (if it doesn’t already). As such, any answer below should be considered UNTRUSTED, which means that if you put all of your eggs in this basket, be prepared for someone to take advantage of it or circumvent it somehow.
I won’t get in to all the ways someone can circumvent IP tracking, because it is constantly evolving. What I will say is that it can be a useful tool for logging as long as you know that IP addresses can easily change or otherwise be masked.
Now, one big point to make is that there is a difference between a public IP address and a private IP address. In IPV4, routers are generally assigned one public IP address, which is all that a server-side language can actually grab, because it doesn’t see your client-side IP address. To a server, your computer doesn’t exist as a web-space. Instead, your router is all that matters. In turn, your router is the only thing that cares about your computer, and it assigns a private IP address (to which your 172...* address belongs) to make this work. This is good for you, because you can’t directly access a computer behind a router.
If you want to access a private IP address, you need to use JavaScript (client-side language). You can then store the data asynchronously via AJAX. As far as I know, this is only currently possible using WebRTC-enabled Chrome and Firefox. See here for a demo.
I tested this and it returns private IP addresses. Typically I think this is used by advertisers to help track individual users in a network, in conjunction with the public IP address. I am certain that it will quickly become useless as people come up with workarounds or as public outcry forces them to offer the ability to disable the WebRTC API. However, for the time being it works for anyone who has JavaScript enabled on Chrome and Firefox.