1. #user nobody;
  2. worker_processes 4;
  3. #error_log logs/error.log;
  4. #error_log logs/error.log notice;
  5. #error_log logs/error.log info;
  6. #pid logs/nginx.pid;
  7. events {
  8. worker_connections 8192;
  9. }
  10. http {
  11. include mime.types;
  12. default_type application/octet-stream;
  13. 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" '
  14. '$status $body_bytes_sent "$http_referer" '
  15. '"$http_user_agent" "$http_x_forwarded_for" "$my_scheme://$host:$server_port:$my_https" $upstream_addr $request_time $upstream_response_time';
  16. log_format message '$time_local "$request" $status $http_CurTime $http_MD5 "$http_user_agent"';
  17. access_log logs/access.log main;
  18. ssi on;
  19. ssi_silent_errors off;
  20. sendfile on;
  21. tcp_nopush on;
  22. tcp_nodelay on;
  23. client_header_timeout 5s;
  24. client_body_timeout 15s;
  25. send_timeout 15s;
  26. resolver_timeout 5s;
  27. types_hash_max_size 2048;
  28. types_hash_bucket_size 64;
  29. server_names_hash_bucket_size 64;
  30. # keepalive_timeout 0;
  31. keepalive_timeout 60s;
  32. keepalive_requests 1024;
  33. server_tokens off;
  34. gzip on;
  35. gzip_disable "msie6";
  36. gzip_min_length 1024;
  37. gzip_proxied any;
  38. gzip_comp_level 3;
  39. 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;
  40. set_real_ip_from 10.0.0.0/8;
  41. real_ip_header proxy_protocol;
  42. include http_common.conf;
  43. upstream backend-app-server {
  44. server 127.0.0.1:8888 max_fails=3 fail_timeout=20s;
  45. keepalive 2000;
  46. }
  47. upstream backend-search-server {
  48. server 127.0.0.1:8788 max_fails=3 fail_timeout=20s;
  49. keepalive 2000;
  50. }
  51. upstream backend-im-server {
  52. server 10.202.32.27:9588 max_fails=3 fail_timeout=20s;
  53. keepalive 2000;
  54. }
  55. # god-dev-in.gameyw.netease.com, 内网lbc
  56. server {
  57. listen 80 proxy_protocol;
  58. server_name god-dev-in.gameyw.netease.com;
  59. # 限制内网ip
  60. allow 10.0.0.0/8;
  61. deny all;
  62. # include location-block-url.conf;
  63. location /v1/app {
  64. include location-cors-common-test.conf;
  65. proxy_pass http://backend-app-server;
  66. proxy_set_header host $host:$server_port;
  67. proxy_set_header X-Real-IP $http_x_forwarded_for;
  68. }
  69. location /v1/search {
  70. include location-cors-common-test.conf;
  71. proxy_pass http://backend-search-server;
  72. proxy_set_header host $host:$server_port;
  73. proxy_set_header X-Real-IP $remote_addr;
  74. }
  75. location /v1/server {
  76. proxy_pass http://backend-app-server;
  77. proxy_set_header host $host:$server_port;
  78. proxy_set_header X-Real-IP $remote_addr;
  79. }
  80. }
  81. # god-test.gameyw.netease.com, 外网lbc
  82. server {
  83. listen 80 proxy_protocol;
  84. server_name god-test.gameyw.netease.com god-dev.gameyw.netease.com;
  85. root /home/website;
  86. set $my_scheme "http";
  87. if ($http_x_forwarded_proto = 'https'){
  88. set $my_scheme "https";
  89. set $my_https "on";
  90. }
  91. location / {
  92. root /home/website;
  93. index index.html index.htm;
  94. }
  95. # include location-block-url.conf;
  96. location /v1/app {
  97. include location-cors-common-test.conf;
  98. proxy_pass http://backend-app-server;
  99. proxy_set_header host $host:$server_port;
  100. proxy_set_header X-Real-IP $http_x_forwarded_for;
  101. }
  102. location /v1/log {
  103. include location-cors-common-test.conf;
  104. proxy_pass http://backend-app-server;
  105. proxy_set_header host $host:$server_port;
  106. proxy_set_header X-Real-IP $http_x_forwarded_for;
  107. }
  108. location /v1/im/ {
  109. include location-cors-common-test.conf;
  110. proxy_pass http://backend-im-server;
  111. proxy_set_header host $host:$server_port;
  112. proxy_set_header X-Real-IP $http_x_forwarded_for;
  113. }
  114. location /v1/gameServer {
  115. proxy_pass http://backend-app-server;
  116. proxy_set_header host $host:$server_port;
  117. proxy_set_header X-Real-IP $http_x_forwarded_for;
  118. }
  119. location /v1/search {
  120. include location-cors-common-test.conf;
  121. proxy_pass http://backend-search-server;
  122. proxy_set_header host $host:$server_port;
  123. proxy_set_header X-Real-IP $remote_addr;
  124. }
  125. location /v1/server {
  126. #图片审核系统调用
  127. allow 60.191.80.12;
  128. allow 60.191.80.11;
  129. allow 60.191.80.19;
  130. #cc图片审核
  131. allow 218.107.55.252;
  132. allow 218.107.55.254;
  133. allow 218.107.55.253;
  134. deny all;
  135. proxy_pass http://backend-app-server;
  136. proxy_set_header host $host:$server_port;
  137. proxy_set_header X-Real-IP $remote_addr;
  138. }
  139. location ~ ^/(swagger|webjars|v2/api|doc) {
  140. allow 58.248.246.3;
  141. allow 218.107.55.254;
  142. allow 218.107.55.252;
  143. deny all;
  144. # proxy_pass http://backend-app-server;
  145. rewrite ^ http://god-dev.gameyw.netease.com:8080/app-swagger/swagger-ui.html permanent;
  146. }
  147. location /dashen/messageCallback {
  148. access_log logs/message.log message;
  149. return 200;
  150. }
  151. }
  152. }

我们在实际开发过程中,经常会使用Nginx做反向代理,有时候甚至使用多级Nginx做反向代理,如果我们使用多级Nginx如何获取真实IP呢?下面我将通过两种姿势来解决

环境

  1. 服务器2台:安装Nginx和web服务
  2. 一个服务:springboot启动web服务
  3. pc->14.23(nginx)->14.22(nginx)->14.22(web服务)

    姿势一

    14.23的nginx的配置文件
    重要参数:proxy_set_header X-Forwarded-For $remote_addr; 第一层nginx获取客户端的IP

    1. server {
    2. listen 7050;
    3. location /{
    4. proxy_pass http://xx.xx.14.22:8081/TestServer;
    5. proxy_set_header X-Real-PORT $remote_port;
    6. proxy_set_header X-Real-IP $remote_addr;
    7. proxy_set_header X-Forwarded-For $remote_addr;
    8. }

14.22的nginx的配置文件
重要参数:proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
第二层nginx,在真是IP上+上一层nginx所在服务器的地址。
此刻X-Forwarded-For的值为: “真实IP,第一层Nginx的Ip”

  1. server {
  2. listen 8081;
  3. listen [::]:8081 ipv6only=on;
  4. location / {
  5. proxy_set_header Host $host;
  6. proxy_http_version 1.1;
  7. proxy_set_header Connection "";
  8. proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  9. proxy_pass http://xx.xx.14.22:8080;
  10. }
  11. }


TestServer

  1. @Autowired
  2. HttpServletRequest request;
  3. @GetMapping("/test")
  4. public String test(){
  5. //获取多个ip,用逗号隔开
  6. String ips = request.getHeader("X-Forwarded-For");
  7. //真正的ipips的第一个
  8. String ip = ips.split(",")[0];
  9. return ip;
  10. }

原理分析
nginx配置 - 图1
只有客户端直接请求到第一个nginx能够拿到客户端的真实IP, 所以第一级nginx配置了 proxy_set_header X-Real-IP $remote_addr; 这个配置就会将客户端IP放到http的header里,这样到最后的应用里可以通过request.getHeader去拿到客户端真实IP了
姿势一的优点和缺点

  • 优点:可以获取多级Nginx的ip
  • 缺点:需要获取第一个ip为真实Ip

    姿势二

    14.23的nginx的配置文件
    重要参数:proxy_set_header X-CustomnReal-IP $remote_addr; 第一层nginx获取客户端的IP,自定义X-CustomnReal-IP

    1. server {
    2. listen 7050;
    3. location /{
    4. proxy_pass http://xx.xx.14.22:8081/TestServer;
    5. proxy_set_header X-CustomnReal-IP $remote_addr;
    6. }


    14.22的nginx的配置文件

    1. server {
    2. listen 8081;
    3. listen [::]:8081 ipv6only=on;
    4. location / {
    5. proxy_set_header Host $host;
    6. proxy_http_version 1.1;
    7. proxy_set_header Connection "";
    8. proxy_pass http://xx.xx.14.22:8080;
    9. }
    10. }

TestServer

  1. @GetMapping("/test2")
  2. public String test2(){
  3. //真正的ip
  4. String ip = request.getHeader("X-CustomnReal-IP");
  5. return ip;
  6. }

姿势一的优点和缺点

  • 优点:直接获取真实IP
  • 缺点:无法获取多级IP