#user nobody;
worker_processes 4;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
events {
worker_connections 8192;
}
http {
include mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request,,GL-Uid:$http_GL_Uid,,GL-Version:$http_GL_Version,,GL-DeviceId:$http_GL_DeviceId" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for" "$my_scheme://$host:$server_port:$my_https" $upstream_addr $request_time $upstream_response_time';
log_format message '$time_local "$request" $status $http_CurTime $http_MD5 "$http_user_agent"';
access_log logs/access.log main;
ssi on;
ssi_silent_errors off;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
client_header_timeout 5s;
client_body_timeout 15s;
send_timeout 15s;
resolver_timeout 5s;
types_hash_max_size 2048;
types_hash_bucket_size 64;
server_names_hash_bucket_size 64;
# keepalive_timeout 0;
keepalive_timeout 60s;
keepalive_requests 1024;
server_tokens off;
gzip on;
gzip_disable "msie6";
gzip_min_length 1024;
gzip_proxied any;
gzip_comp_level 3;
gzip_types text/plain application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png application/javascript;
set_real_ip_from 10.0.0.0/8;
real_ip_header proxy_protocol;
include http_common.conf;
upstream backend-app-server {
server 127.0.0.1:8888 max_fails=3 fail_timeout=20s;
keepalive 2000;
}
upstream backend-search-server {
server 127.0.0.1:8788 max_fails=3 fail_timeout=20s;
keepalive 2000;
}
upstream backend-im-server {
server 10.202.32.27:9588 max_fails=3 fail_timeout=20s;
keepalive 2000;
}
# god-dev-in.gameyw.netease.com, 内网lbc
server {
listen 80 proxy_protocol;
server_name god-dev-in.gameyw.netease.com;
# 限制内网ip
allow 10.0.0.0/8;
deny all;
# include location-block-url.conf;
location /v1/app {
include location-cors-common-test.conf;
proxy_pass http://backend-app-server;
proxy_set_header host $host:$server_port;
proxy_set_header X-Real-IP $http_x_forwarded_for;
}
location /v1/search {
include location-cors-common-test.conf;
proxy_pass http://backend-search-server;
proxy_set_header host $host:$server_port;
proxy_set_header X-Real-IP $remote_addr;
}
location /v1/server {
proxy_pass http://backend-app-server;
proxy_set_header host $host:$server_port;
proxy_set_header X-Real-IP $remote_addr;
}
}
# god-test.gameyw.netease.com, 外网lbc
server {
listen 80 proxy_protocol;
server_name god-test.gameyw.netease.com god-dev.gameyw.netease.com;
root /home/website;
set $my_scheme "http";
if ($http_x_forwarded_proto = 'https'){
set $my_scheme "https";
set $my_https "on";
}
location / {
root /home/website;
index index.html index.htm;
}
# include location-block-url.conf;
location /v1/app {
include location-cors-common-test.conf;
proxy_pass http://backend-app-server;
proxy_set_header host $host:$server_port;
proxy_set_header X-Real-IP $http_x_forwarded_for;
}
location /v1/log {
include location-cors-common-test.conf;
proxy_pass http://backend-app-server;
proxy_set_header host $host:$server_port;
proxy_set_header X-Real-IP $http_x_forwarded_for;
}
location /v1/im/ {
include location-cors-common-test.conf;
proxy_pass http://backend-im-server;
proxy_set_header host $host:$server_port;
proxy_set_header X-Real-IP $http_x_forwarded_for;
}
location /v1/gameServer {
proxy_pass http://backend-app-server;
proxy_set_header host $host:$server_port;
proxy_set_header X-Real-IP $http_x_forwarded_for;
}
location /v1/search {
include location-cors-common-test.conf;
proxy_pass http://backend-search-server;
proxy_set_header host $host:$server_port;
proxy_set_header X-Real-IP $remote_addr;
}
location /v1/server {
#图片审核系统调用
allow 60.191.80.12;
allow 60.191.80.11;
allow 60.191.80.19;
#cc图片审核
allow 218.107.55.252;
allow 218.107.55.254;
allow 218.107.55.253;
deny all;
proxy_pass http://backend-app-server;
proxy_set_header host $host:$server_port;
proxy_set_header X-Real-IP $remote_addr;
}
location ~ ^/(swagger|webjars|v2/api|doc) {
allow 58.248.246.3;
allow 218.107.55.254;
allow 218.107.55.252;
deny all;
# proxy_pass http://backend-app-server;
rewrite ^ http://god-dev.gameyw.netease.com:8080/app-swagger/swagger-ui.html permanent;
}
location /dashen/messageCallback {
access_log logs/message.log message;
return 200;
}
}
}
我们在实际开发过程中,经常会使用Nginx做反向代理,有时候甚至使用多级Nginx做反向代理,如果我们使用多级Nginx如何获取真实IP呢?下面我将通过两种姿势来解决
环境
- 服务器2台:安装Nginx和web服务
- 一个服务:springboot启动web服务
pc->14.23(nginx)->14.22(nginx)->14.22(web服务)
姿势一
14.23的nginx的配置文件
重要参数:proxy_set_header X-Forwarded-For $remote_addr; 第一层nginx获取客户端的IPserver {
listen 7050;
location /{
proxy_pass http://xx.xx.14.22:8081/TestServer;
proxy_set_header X-Real-PORT $remote_port;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
}
14.22的nginx的配置文件
重要参数:proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
第二层nginx,在真是IP上+上一层nginx所在服务器的地址。
此刻X-Forwarded-For的值为: “真实IP,第一层Nginx的Ip”
server {
listen 8081;
listen [::]:8081 ipv6only=on;
location / {
proxy_set_header Host $host;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://xx.xx.14.22:8080;
}
}
TestServer
@Autowired
HttpServletRequest request;
@GetMapping("/test")
public String test(){
//获取多个ip,用逗号隔开
String ips = request.getHeader("X-Forwarded-For");
//真正的ip为ips的第一个
String ip = ips.split(",")[0];
return ip;
}
原理分析
只有客户端直接请求到第一个nginx能够拿到客户端的真实IP, 所以第一级nginx配置了 proxy_set_header X-Real-IP $remote_addr; 这个配置就会将客户端IP放到http的header里,这样到最后的应用里可以通过request.getHeader去拿到客户端真实IP了
姿势一的优点和缺点
- 优点:可以获取多级Nginx的ip
-
姿势二
14.23的nginx的配置文件
重要参数:proxy_set_header X-CustomnReal-IP $remote_addr; 第一层nginx获取客户端的IP,自定义X-CustomnReal-IP
server {
listen 7050;
location /{
proxy_pass http://xx.xx.14.22:8081/TestServer;
proxy_set_header X-CustomnReal-IP $remote_addr;
}
14.22的nginx的配置文件server {
listen 8081;
listen [::]:8081 ipv6only=on;
location / {
proxy_set_header Host $host;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_pass http://xx.xx.14.22:8080;
}
}
TestServer
@GetMapping("/test2")
public String test2(){
//真正的ip
String ip = request.getHeader("X-CustomnReal-IP");
return ip;
}
姿势一的优点和缺点
- 优点:直接获取真实IP
- 缺点:无法获取多级IP