目录
上次说了,有个需求,是使用nginx做反向代理用的。可以看看具体的nginx的安装。另外还有一篇介绍Squid的正向代理。
基本的nginx反向代理设置
要配置一下nginx,进入到${nginx}/conf/nginx.conf
,增加一个服务器。
增加一条server记录
server { listen 80; # 端口 server_name testproxy; # 域名 location / { proxy_pass http://www.chenyudong.com/; # 需要访问的网站 proxy_redirect off; # 重定向关闭 proxy_set_header Host $host; # 设置一下访问头 } }
注意:通过上面的方法,只是服务器简单的将文件下载下来,然后就未加工的提交给用户了。也就是里面的链接是不会出现替换的,原来是什么就该是什么。
那么要替换某些URL要怎么做的?
替换网页里某些关键字或链接
如果需要替换关键字或者链接,该怎么办呢?
我们需要重新编译一下nginx,对,重新编译。在编译的时候添加参数--with-http_sub_module
。也就是编译的命令./configure --with-http_sub_module
。然后的安装过程见这篇文章。
接下来需要修改一下${nginx}/conf/nginx.conf
配置。
server { listen 80; # 端口 server_name testproxy; # 域名 ##将页面出现的www.baidu.com改成google.com sub_filter 'www.baidu.com' 'google.com'; ## off:在符合的地方,替换所有出现的地方。默认为on:只替换第一个出现的地方 sub_filter_once off; location / { proxy_pass http://www.google.com/; # 需要访问的网站 proxy_redirect off; # 重定向关闭 proxy_set_header Host $host; # 设置一下访问头 } }
需要关心用于的真实IP了
说明:这个用户的真实IP指的是,直接和我们服务器连接的那个IP,用户可以躲在代理后面,这种情况获取不到用户真实IP,想要获得,成本很高,还不一定能获得到。下文说的都是基于这个前提条件的。
以上配置,是多么美好啊,应该能正常工作了。但是还是有些不足,就是我们对用户真实IP的获取上,已经无法通过_SERVER['REMOTE_ADDR']
获取,因为这个获取的值是前台的nginx的IP。

nginx反向代理
对于我们backend nginx代理,只能看到所有的请求是来自front nginx的,所以PHP程序想要获得用户的真实IP,需要做一些设置。
## front nginx 设置 server { listen 80; server_name server.com; #access_log /data/home/log/server.access.log main; location / { proxy_pass http://www.chenyudong.com/; proxy_redirect off; proxy_set_header X-real-ip $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } }
从HTTP_X_REAL_IP获取
通过增加HTTP_X_REAL_IP
、HTTP_X_FORWARDED_FOR
这两个变量,让后端的backend nginx从这里获取用户的真实IP。

设置用户真实IP头的结果
我们可以看到,PHP中的HTTP_X_REAL_IP
、HTTP_X_FORWARDED_FOR
已经获取到用户的真实IP了。
这还不够完美,这需要我们的程序重新使用_SERVER["HTTP_X_REAL_IP"]
这样来取值。但是程序不是从头写起的,大家都在使用_SERVER['REMOTE_ADDR']
获取,要替换,工程浩大,不适宜。那么就只能在程序的入口做个变量的替换了。
<?php _SERVER['REMOTE_ADDR'] = _SERVER["HTTP_X_REAL_IP"]; .... ?>
来个狠的,就要从REMOTE_ADDR获取
如果你觉得上面还是不太爽,我就是从那里取值。
在上面front nginx的配置基础上不变。这次我们对backend nginx做配置:
location ~ ^.+\.php { fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; fastcgi_param REMOTE_ADDR $HTTP_X_REAL_IP; }
就是高亮的第六行,添加fastcgi_param REMOTE_ADDR $HTTP_X_REAL_IP;
,把REMOTE_ADDR
这个变量在这里就给他替换了。看看替换的结果:

替换REMOTE_ADDR变量
经过这么一折腾,我们的PHP就可以和以前一样工作了。
这样就好了吗?
如果你觉得这样,就可以了,那就错了。虽然我们的PHP正确获得了用户的IP,但是nginx要打access的log,看看他的log,你会发现请求的IP还是front nginx的那个IP。
要解决这个问题,我们就要再修改一把。并且这个解决方案比上一步来的更好一些。完全可以替换上一部的方案。
前端的front nginx的配置和前面一样。
## front nginx 设置 server { listen 80; server_name server.com; #access_log /data/home/log/server.access.log main; location / { proxy_pass http://www.chenyudong.com/; proxy_redirect off; proxy_set_header X-real-ip $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } }
后台的backend nginx要使用set_real_ip_from
、real_ip_header
这两个指令,这两个是在nginx的HttpRealipModule
中,这个模块默认不被编译,因此需要在编译是添加--with-http_realip_module
参数
## 源码编译增加参数 ./configure --with-http_realip_module ## yum 安装默认是有安装的,可以 nginx -V ##查看一下编译的参数
后端的backend nginx配置
## backend nginx location ~ ^.+\.php { fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; set_real_ip_from 10.221.0.197; #set_real_ip_from 100.100.0.0/16; #set_real_ip_from 2001:0db8::/32; real_ip_header X-Real-IP; }
第7行,set_real_ip_from
定义了一个信任的IP地址,从这个信任的IP发送的可以替换用户的IP地址。如果值是unix
,所有来自UNIX域的sockets都被信任。
IPv6 addresses are supported starting from versions 1.3.0 and 1.2.1.
第10行,real_ip_header
定义了一个请求头,用于替换用户的真实IP。
这样的配置,我们的_SERVER['REMOTE_ADDR']
还是用户的真实IP,而不是front nginx的IP。并且log里面的IP也是用户的真实IP。还等什么,赶快试一试吧。
参考资料:
- http://nginx.org/en/docs/http/ngx_http_realip_module.html
- https://rtcamp.com/tutorials/nginx/forwarding-visitors-real-ip/
声明:未经允许禁止转载 东东东 陈煜东的博客 文章,谢谢。如经授权,转载请注明: 转载自东东东 陈煜东的博客
本文链接地址: nginx 反向代理 proxy – https://www.chenyudong.com/archives/nginx-reverse-proxy.html
发表评论