阿里云场景下获取用户真实 IP

前言

获取用户的真实 IP,对于安全业务来说非常重要。
阿里云场景下一个Http 请求一般为:

用户IP --> Ddos 高防 IP ->SLB IP

背景

对于WEB服务器来说,主要是通过两种方式获取 IP

  1. 与服务器建立TCP连接的地址 Remote Address
  2. 通过 Http Header 的 X-Forwarded-For 字段

对应的 PHP 变量如下

$_SERVER['REMOTE_ADDR']   // 与服务建立TCP连接的IP
$_SERVER['HTTP_X_FORWARDED_FOR'] // 获取 Http 请求头 X-Forwarded-For数据

Remote Address

  1. 与服务器建立TCP连接的 IP
  2. 无法伪造,很合适作为用户真实IP
  3. 但是 HTTP 请求经过七层代理后,就不是用户IP了,一般为SLB IP

X-Forwarded-For

  1. 通过Http Header传递给服务端
  2. 可以伪造,有可能获取的数据不准确,还可能引发 XSS,SQL 注入等问题
  3. X-Forwarded-For :格式如下

X-Forwarded-For: client, proxy1, proxy2

如果一个 HTTP 请求到达服务器之前,经过了三个代理 Proxy1、Proxy2、Proxy3,IP 分别为 IP1、IP2、IP3,用户真实 IP 为 IP0,服务端最终会收到以下信息:

X-Forwarded-For: IP0, IP1, IP2

Proxy3 直连服务器,它会给 XFF 追加 IP2,表示它是在帮 Proxy2 转发请求。列表中并没有 IP3,IP3 可以在服务端通过 REMOTE_ADDR 字段获得。

如果用户篡改 X-Forwarded-For

curl http://a.b.com/ -H 'X-Forwarded-For: IP100' ,服务端会受到如下信息;
X-Forwarded-For: IP100, IP0, IP1, IP2

思考

我们怎么通过这两个字段获取用户真实 IP 呢?

  1. 如果 HTTP 请求没有经过七层代理,直接读取 REMOTE_ADDR 字段最好
  2. 如果 HTTP 请求经过七层代理, 我们只能从 X-Forwarded-For 获取,但是我们必须过滤用户伪造数据,获取真实的用户 IP
  3. 如上面例子 IP1, IP2是我们自己配置的 IP,可信任的IP,过滤掉可信任的代理IP,最后一个不可信任的IP就是用户IP。

问题

要解决的问题如下

  1. nginx的访问日志,记录用户真实ip,现在记录的是Remote Address。
  2. php获取用户真实IP,如果我们获取X-Forwarded-For第一个IP。容易被用户篡改。

调研过程中,发现ngx_http_realip_module 满足我们需求, 当获取了用户真实IP,会赋值给 nginx变量 $remote_addr 变量,那么 PHP的 $_SERVER['REMOTE_ADDR'] 也变成了用户真实IP。

与web服务器建议TCP连接的IP 存储在变量 $realip_remote_addr 中。

set_real_ip_from  192.168.1.0/24;
real_ip_header    X-Forwarded-For;
real_ip_recursive on;
  • set_ip_from
    设置信任 IP,就是我们自己的代理IP,可以设置多个
  • real_ip_header
    设置请求头字段,表示从X-Forwarded-For字段获取用户 IP
  • real_ip_recursive
    off:如果remote address 能够匹配set_real_ip_from 的ip,用户 X-Forwarded-For最后一个 IP 作为用户IP。

on: 如果remote address 能够匹配set_real_ip_from 的ip,用户 X-Forwarded-For最后一个不可信任 IP 作为用户IP。

我们的配置如下,注意还没有上线

nginx 配置如下

#slb IP
set_real_ip_from   100.64.0.0/10;
# ddos高防iP的回源IP
set_real_ip_from     180.97.165.0/24;
set_real_ip_from     180.97.166.0/24;
set_real_ip_from     180.97.88.0/24;
set_real_ip_from     116.211.163.0/24;
set_real_ip_from     116.211.164.0/24;
set_real_ip_from     116.211.165.0/24;
set_real_ip_from     218.60.116.0/24;
set_real_ip_from     218.60.117.0/24;
set_real_ip_from     218.60.120.0/24;
set_real_ip_from     218.11.4.0/24;
set_real_ip_from     121.29.52.0/24;
set_real_ip_from     121.29.53.0/24;
set_real_ip_from     120.55.146.0/24;
set_real_ip_from     120.55.147.0/24;
set_real_ip_from     120.55.177.0/24;
set_real_ip_from     120.27.173.0/24;
set_real_ip_from     118.178.15.0/24;
set_real_ip_from     118.178.177.0/24;
set_real_ip_from     118.178.202.0/24;
set_real_ip_from     118.178.203.0/24;
set_real_ip_from     118.178.204.0/24;
set_real_ip_from     118.178.221.0/24;
set_real_ip_from     118.178.222.0/24;
set_real_ip_from     118.178.223.0/24;
set_real_ip_from     118.178.244.0/24;

real_ip_header     X-Forwarded-For;
real_ip_recursive on;

PHP 获取用户IP
$_SEVER['REMOTE_ADDR']

参考

https://imququ.com/post/x-forwarded-for-header-in-http.html

http://nginx.org/en/docs/http/ngx_http_realip_module.html

http://baike.baidu.com/item/IANA%E4%BF%9D%E7%95%99%E5%9C%B0%E5%9D%80?fr=aladdin

时间: 2024-08-23 09:41:48

阿里云场景下获取用户真实 IP的相关文章

Java中使用HttpRequest获取用户真实IP地址_JSP编程

在JSP里,获取客户端的IP地址的方法是:request.getRemoteAddr(),这种方法在大部分情况下都是有效的.但是在通过了Apache,Squid,nginx等反向代理软件就不能获取到客户端的真实IP地址了. 如果使用了反向代理软件,将http://192.168.1.110:2046/ 的URL反向代理为 http://www.jb51.net / 的URL时,用request.getRemoteAddr()方法获取的IP地址是:127.0.0.1 或 192.168.1.110

Nginx阻止用户代理及nginx获取用户真实IP地址

Nginx阻止用户代理 有些时候,需要阻止某些用户代理访问网站,比如ab,wget,curl等等,这就需要使用到$http_user_agent变量. 修改nginx.conf if ($http_user_agent ~* (Wget|ab) ) {    return 403; }   if ($http_user_agent ~* LWP::Simple|BBBike|wget) {             return 403; } 重启nginx # /usr/local/nginx-

PHP获取用户真实 IP , 淘宝IP接口获得ip地理位置

自己不需ip库,免更新.  淘宝IP库: http://ip.taobao.com  多谢5楼提醒   ​ /**  * 获取用户真实 IP  */ function getIP() {     static $realip;     if (isset($_SERVER)){         if (isset($_SERVER["HTTP_X_FORWARDED_FOR"])){             $realip = $_SERVER["HTTP_X_FORWARD

获取用户真实IP地址代码

获取用户真实IP地址代码 Public Function GetIp(getType)   If getType = 0 then    GetIp = Request.ServerVariables("HTTP_X_FORWARDED_FOR")    if GetIp = "" Then getIp = Request.ServerVariables("REMOTE_ADDR")   ElseIf getType = 1 Then    Ge

asp获取用户真实IP地址的方法

 一般的程序都具备获取用户IP地址的命令,但是我们访问网站有两种一种是我们这种普通用户,一种是使用代理IP上网的用户,下面我来介绍介绍.   在asp中获取用户IP地址我们最简单的获取方法就是使用  代码如下   Request.ServerVariables("REMOTE_ADDR") 但是如果用户使用了代理服务器IP地址就不对了,但我们可通过  代码如下   Request.ServerVariables("REMOTE_ADDR") 结果上面的两个获取IP的

【整理】获取用户真实 ip 地址的 nginx 相关配置

nginx 为实现反向代理的需求增加了一个 ngx_http_proxy_module 模块.其中 proxy_set_header 指令就是该模块需要读取的配置.        HTTP header 中的 Host 含义为所请求的目的主机名.当 nginx 作为反向代理使用,而后端真实 web 服务器设置有类似 防盗链功能 ,或者根据 HTTP header 中的 Host 字段来进行 路由 或 过滤 功能的话,若作为反向代理的 nginx 不重写请求头中的 Host 字段,将会导致请求失败

获取用户真实ip地址的方法

一.没有使用代理服务器的情况: REMOTE_ADDR = 您的 IP HTTP_VIA = 没数值或不显示 HTTP_X_FORWARDED_FOR = 没数值或不显示   二.使用透明代理服务器的情况:Transparent Proxies REMOTE_ADDR = 最后一个代理服务器 IP HTTP_VIA = 代理服务器 IP HTTP_X_FORWARDED_FOR = 您的真实 IP ,经过多个代理服务器时,这个值类似如下:203.98.182.163, 203.98.182.16

LNAMP架构中后端Apache获取用户真实IP地址的2种方法_Linux

一.Nginx反向代理配置: 1.虚拟主机配置 复制代码 代码如下: location / {    try_files $uri @apache;} location @apache {internal;    proxy_pass http://127.0.0.1:8080;    include proxy.conf;} location ~ .*\.(php|php5)?$  {    proxy_pass http://127.0.0.1:8080;    include proxy.

详细ASP获取用户真实IP代码

正常情况这样就能取得客户端的ip地址,但如果客户端是使用代理服务器来访问,那取到的就是代理服务器的 ip 地址,而不是真正的客户端 ip 地址,要想透过代理服务器取得客户端的真实  ip 地址,就要使用微软公司在一般asp教程技术文档中并未公布的request.servervariables("http_x_forwarded_for") 来读取,但是需要注意的是:如果客户端没有通过代理服务器来访问,那么用 request.servervariables ("http_x_f