nginx做反向代理时获取真实IP
原文:http://blog.csdn.net/aquester/article/details/48657395
1. 编译
对于client -> nginx reverse proxy -> apache,
要想在程序中取得真实的IP,在执行nginx的configure时,必须指定参数“--with-http_realip_module”,示例:
./configure --prefix=/data/nginx --with-http_realip_module --with-stream --with-pcre=/tmp/X/pcre-8.32 --with-openssl=/tmp/X/openssl-1.0.2a
参数说明:
--prefix= 指定安装目录,也就是make install后程序文件等的存放目录
--with-http_realip_module 使得程序可以通过环境变量HTTP_X_REAL_IP取得真实的客户端IP地址
--with-stream 表示启用TCP代理
--with-pcre= 指定依赖的pcre,注意为pcre源代码解压后的目录路径,而不是安装路径
--with-openssl= 指定依赖的openssl,注意为openssl源代码解压后的目录路径,而不是安装路径
另外,最简单的确认方法是使用nm命令查看nginx程序文件,看看是否有包含real相关的符号,对于版本nginx-1.9.4 ,可以发现存在“0809c54b t ngx_http_realip”。
2. 程序代码
测试程序代码(后续测试基于它):
// g++ -g -o hello.cgi hello.cpp
#include <stdio.h>
#include <stdlib.h>
int main()
{
printf("Content-Type: text/html; charset=utf-8\r\n\r\n");
printf("<p>HTTP_X_FORWARDED_FOR: %s\n", getenv("HTTP_X_FORWARDED_FOR"));
printf("<p>HTTP_X_REAL_IP: %s\n", getenv("HTTP_X_REAL_IP"));
printf("<p>REMOTE_ADDR: %s\n", getenv("REMOTE_ADDR"));
printf("<p>");
return 0;
}
测试是在nginx自带配置文件nginx.conf上进行的修改:
proxy_set_header可以添加在nginx.conf的http段,也可以是server段,还可以是location段,一级一级间是继承和覆盖关系。
3. 相关配置
示例:
location / {
# root html;
# index index.html index.htm;
proxy_pass http://20.61.28.11:80;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr; # 这个是必须的
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
X-Forwarded-For和X-Real-IP的区别是,如果请求时已带了X-Forwarded-For,则nginx追加方式,这样可以通过它显示转发的轨迹。
当然请求时完全可以构造假的X-Forwarded-For,在配置文件打开了X-Real-IP及编译指定了--with-http_realip_module时,环境变量HTTP_X_REAL_IP总是为真实的客户端IP。
如果是:
client -> nginx reverse proxy (A) -> nginx reverse proxy (B) -> apache
HTTP_X_REAL_IP又会是什么了?
4. 测试1
假设如下部署:
client(10.6.81.39) -> nginx(10.6.223.44:8080) -> nginx(10.6.208.101:8080) -> apache(10.6.208.101:80)
Ø A
假设nginx(10.6.223.44:8080)的配置均为(在nginx默认配置上的修改部分):
server {
listen 8080;
server_name 10.6.223.44;
location / {
# root html;
# index index.html index.htm;
proxy_pass http://10.6.208.101:8080;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
假设nginx(10.6.208.101:8080)的配置均为(在nginx默认配置上的修改部分):
server {
listen 8080;
server_name 10.6.208.101;
location / {
# root html;
# index index.html index.htm;
proxy_pass http://10.6.208.101:80;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
上述测试程序输出的结果为:
<p>HTTP_X_FORWARDED_FOR: 10.6.81.39, 10.6.223.44
<p>HTTP_X_REAL_IP: 10.6.223.44
<p>REMOTE_ADDR: 10.6.81.39
Ø B
但如果client在HTTP请求头中加入:
X-FORWARDED-FOR:8.8.8.7
CLIENT-IP:8.8.8.8
X-REAL-IP:8.8.8.10
后输出结果变成:
<p>HTTP_X_FORWARDED_FOR: 8.8.8.7, 10.6.81.39, 10.6.223.44
<p>HTTP_X_REAL_IP: 10.6.223.44
<p>REMOTE_ADDR: 8.8.8.7
Ø C
基于A,如果只nginx(10.6.223.44:8080)配置注释掉“X-Forwarded-For”,输出结果变成:
<p>HTTP_X_FORWARDED_FOR: 10.6.223.44
<p>HTTP_X_REAL_IP: 10.6.223.44
<p>REMOTE_ADDR: 10.6.223.44
Ø D
基于A,如果只nginx(10.6.208.101:8080)配置注释掉“X-Forwarded-For”,输出结果变成:
<p>HTTP_X_FORWARDED_FOR: 10.6.81.39
<p>HTTP_X_REAL_IP: 10.6.223.44
<p>REMOTE_ADDR: 10.6.81.39
5. 测试2
基于测试1的配置,
当访问路径变成:client(10.6.81.39) -> nginx(10.6.208.101:8080) -> apache(10.6.208.101:80)时,程序输出结果为:
<p>HTTP_X_FORWARDED_FOR: 10.6.81.39
<p>HTTP_X_REAL_IP: 10.6.81.39
<p>REMOTE_ADDR: 10.6.81.39
但如果client在HTTP请求头中加入:
X-FORWARDED-FOR:8.8.8.7
CLIENT-IP:8.8.8.8
X-REAL-IP:8.8.8.10
后输出结果变成:
<p>HTTP_X_FORWARDED_FOR: 8.8.8.7, 10.6.81.39
<p>HTTP_X_REAL_IP: 10.6.81.39
<p>REMOTE_ADDR: 8.8.8.7
从上可以看出,只配置正确使用了real-ip功能,除HTTP_X_REAL_IP外,其它内容可以被干扰,client可以篡改它们。
6. 结论
如果正确编译和配置了nginx反向代理,当只有一层nginx反向代理时,可以通过“HTTP_X_REAL_IP”取得client的真实IP。
如果有二层nginx反向代理,则client的真实IP被包含在“HTTP_X_FORWARDED_FOR”中。
最不可信的是“REMOTE_ADDR”,它的内容完全可以被client指定!总之只要编译和配置正确,“HTTP_X_FORWARDED_FOR”总是包含了client的真实IP。
nginx做反向代理时获取真实IP的更多相关文章
- 如何取得nginx做反向代理时的真实IP?
1. 编译 对于client -> nginx reverse proxy -> apache, 要想在程序中取得真实的IP,在执行nginx的configure时,必须指定参数" ...
- 【Nginx】使用Nginx做反向代理时,关于被代理服务器相应的超时设置
> 参考的优秀文章 Module ngx_http_proxy_module > 设置等待被代理服务器的最大响应时间 使用Nginx做反向代理时,因被代理服务器因业务确实复杂,需时较久,往 ...
- nginx做反向代理时出现302错误
现象:nginx在使用非80端口做反向代理时,浏览器访问发现返回302错误 详细现象如下: 浏览器请求登录页: 输入账号密码点击登录: 很明显登录后跳转的地址少了端口号. 原因:proxy.conf文 ...
- nginx做反向代理时出现302错误(转载)
现象:nginx在使用非80端口做反向代理时,浏览器访问发现返回302错误 详细现象如下: 浏览器请求登录页: 输入账号密码点击登录: 很明显登录后跳转的地址少了端口号. 原因:proxy.conf文 ...
- nginx反向代理如何获取真实IP?
由于客户端和web服务器之间增加了中间层,因此web服务器无法直接拿到客户端的ip,通过$remote_addr变量拿到的将是反向代理服务器的ip地址. 1.安装--with-http_realip_ ...
- Nginx反向代理 Laravel获取真实IP地址(PHP)
使用VUE前后端分离开发 后端使用Laravel 想要获取到用户的真实IP地址 因为分离开发不同源跨域问题 所以只能进行前端Nginx反向代理 location /api { rewrite ^/a ...
- nginx设置反向代理,获取真实客户端ip
upstream这个模块提供一个简单方法来实现在轮询和客户端IP之间的后端服务器负荷平衡. upstream abc.com { server 127.0.0.1:8080; server 127.0 ...
- Nginx作为反向代理时传递客户端IP的设置方法
因为nginx的优越性,现在越来越多的用户在生产环境中使用nginx作为前端,不管nginx在前端是做负载均衡还是只做简单的反向代理,都需要把日志转发到后端real server,以方便我们检查程序的 ...
- 多级反向代理java获取真实IP地址
public static String getIpAddress(HttpServletRequest request){ String ip = request.getHeader("x ...
随机推荐
- HDU2553 N皇后问题---(dfs)
http://acm.hdu.edu.cn/showproblem.php?pid=2553 在N*N的方格棋盘放置了N个皇后,使得它们不相互攻击(即任意2个皇后不允许处在同一排,同一列,也不允许处在 ...
- [转]使用 LDAP 组或角色限制访问,包含部分单点登录SSO说明
参考:http://www-01.ibm.com/support/knowledgecenter/api/content/SSEP7J_10.2.2/com.ibm.swg.ba.cognos.crn ...
- [BZOJ2502]清理雪道解题报告|带下界的最小流
滑雪场坐落在FJ省西北部的若干座山上. 从空中鸟瞰,滑雪场可以看作一个有向无环图,每条弧代表一个斜坡(即雪道),弧的方向代表斜坡下降的方向. 你的团队负责每周定时清理雪道.你们拥有一架直升飞机,每次飞 ...
- 【BZOJ】1799: [Ahoi2009]self 同类分布
[题意]给出a,b,求出[a,b]中各位数字之和能整除原数的数的个数.1 ≤ a ≤ b ≤ 10^18 [算法]数位DP [题解] 感觉这种方法很暴力啊. 枚举数位和1~162(不能枚举0,不然会模 ...
- sprintf,snprintf的用法(可以作为linux中itoa函数的补充)【转】
转自:http://blog.csdn.net/educast/article/details/25068445 函数功能:把格式化的数据写入某个字符串 头文件:stdio.h 函数原型:int sp ...
- vs附加到进程报MSVSMON.EXE未在远程计算机启动错误
拿到同事电脑发现居然附加不上本地进程,网上那些关防火墙更改目标平台之类的方法都没用.最后发现是后台运行着一个叫 ss_privoxy.exe 的代理软件搞的,禁用所有非系统服务重启后删掉以绝后患.
- SSH Secure Shell 无法登录:server responded "algorithm negotiation failed”
SSH Secure Shell Client 连接 ubuntu系统报错 修改ssh的配置文件 /etc/ssh/sshd_config在配置文件中添加: Ciphers aes128-cbc,ae ...
- sqlserver中case when then用法
sql语句判断方法之一,Case具有两种格式,简单Case函数和Case搜索函数. --简单Case函数 (CASE sex WHEN '1' THEN '男' WHEN '2' THEN '女' E ...
- Java的Math-BigInteger-Random类概述
1. Math类 Math类在java.lang包中. 常用的方法有 Math.abs(double x)返回x的绝对值. Math.max(double x,double y)返回x和y的 ...
- Luis创建与发布
首先打开网址https://www.luis.ai,打开后,需要使用你的微软帐户或是公司账户登录至Luis 登陆进入至网站后,会自动显示你的应用,在这里你可以修改和删除你之前已经创建过的应用,如果之前 ...