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

简介: 前言 获取用户的真实 IP,对于安全业务来说非常重要 阿里云场景下一个Http 请求一般为: 用户IP --> Ddos 高防 IP ->SLB IP 背景 对于WEB服务器来说,主要是通过两种方式获取 IP 1.

前言

获取用户的真实 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

目录
相关文章
|
5月前
|
人工智能 NoSQL Java
LangChain4j 项目概览
LangChain4j 是一个专为 Java 开发者设计的大语言模型 (LLM) 集成框架,旨在简化 Java 应用程序与各种 LLM 提供商的集成过程。该项目受到 Python 的 LangChain、Haystack、LlamaIndex 等框架的启发,为 Java 生态系统提供了强大而统一的 LLM 工具链。
|
存储 缓存 NoSQL
这些年背过的面试题——Redis篇
本文是技术人面试系列Redis篇,面试中关于Redis都需要了解哪些基础?一文带你详细了解,欢迎收藏!
935 17
|
机器学习/深度学习 自然语言处理 算法
进阶RAG:探索前沿应用与挑战
【10月更文挑战第21天】
431 0
|
存储 弹性计算 数据处理
阿里云对象存储OSS怎么收费?包年包月和按量付费价格表
阿里云对象存储OSS提供灵活的计费方案,包括存储费、流量费和请求费等。用户可选择按量付费或包年包月模式。标准型存储按量付费为0.09元/GB/月,包年包月则有多种套餐选择,如9元/年40GB和99元/年100GB。OSS流量费仅针对公网出方向,并区分闲忙时段。此外还提供流量包服务。更多详情及特殊需求费用(如数据处理、传输加速等)
|
Rust 监控 Linux
这款开源网络监控工具(sniffnet),太实用了!
这款开源网络监控工具(sniffnet),太实用了!
559 0
|
JavaScript 前端开发 编译器
vue 代码高亮 prismjs 或 highlight.js插件的用法
vue 代码高亮 prismjs 或 highlight.js插件的用法
907 0
|
弹性计算 负载均衡 前端开发
使用阿里云负载均衡时获取客户端真实IP的方法
使用阿里云负载均衡时获取客户端真实IP的方法
使用阿里云负载均衡时获取客户端真实IP的方法
|
SQL 关系型数据库 MySQL
MySQL数据库——触发器-介绍、语法(创建,查看,删除)
MySQL数据库——触发器-介绍、语法(创建,查看,删除)
1092 0
|
存储 关系型数据库 对象存储
PolarDB-PG | PostgreSQL + 阿里云OSS 实现高效低价的海量数据冷热存储分离
数据库里的历史数据越来越多, 占用空间大, 备份慢, 恢复慢, 查询少但是很费钱, 迁移慢 怎么办? 冷热分离方案: - 使用PostgreSQL 或者 PolarDB-PG 存成parquet文件格式, 放到aliyun OSS存储里面. 使用duckdb_fdw对parquet文件进行查询. - duckdb 存储元数据(parquet 映射) 方案特点: - 内网oss不收取网络费用, 只收取存储费用, 非常便宜 - oss分几个档, 可以根据性能需求选择 - parquet为列存储, 一般历史数据的分析需求多,性能不错 - duckdb 支持 parquet下推过滤, 数据过滤性能不错
7925 6
PolarDB-PG | PostgreSQL + 阿里云OSS 实现高效低价的海量数据冷热存储分离
|
负载均衡 网络协议 应用服务中间件
使用阿里云NLB获取客户端原地址
本文为您介绍NLB如何获取客户端真实IP,及通过Proxy Protocol获取客户端真实IP的场景和配置教程。
943 1