Nginx 的反向代理设置(二)

Nginx 的反向代理设置(一) 中,我们演示了一个如何通过 Nginx 的代理功能代理内网中运行的业务服务。 本文我们将进一步解决在业务服务器中获取用户真实IP的问题。

修改 default.conf 文件

要让代理后的后端服务获取客户的真实IP, 我们需要改变 Nginx 中代理的设置,利用 Nginx 内置的变量和 proxy_set_header 命令,将客户真实 IP 设置到 HTTP 的 header 中去, 如下:

1
2
3
4
5
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;
proxy_set_header X-Forwarded-Host $server_name;

修改后完整的 default.conf 文件如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
server {
listen 80 default_server;
listen [::]:80 default_server;

location / {
proxy_pass http://app1: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;
proxy_set_header X-Forwarded-Host $server_name;
}
}

修改后端服务

为获取在 HTTP header 中的客户端信息,我们需要修改对应的业务服务器代码,增加从 HttpServeltRequest 中获取 header 的功能:

1
2
3
4
5
StringBuffer buf = new StringBuffer();
buf.append("Served at: ").append(host).append(":").append(String.valueOf(port));
buf.append("<br/>").append("X-Real-IP").append(":").append(request.getHeader("X-Real-IP"));
buf.append("<br/>").append("X-Forwarded-For").append(":").append(request.getHeader("X-Forwarded-For"));
buf.append("<br/>").append("X-Forwarded-Host").append(":").append(request.getHeader("X-Forwarded-Host"));

以上代码只是简单的获取相关信息并存储在 StringBuffer 中。

修改后完整的 Java 代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
package cn.com.hohistar.study.servlet;

import java.io.IOException;
import java.net.InetAddress;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
* Servlet implementation class HelloServlet
*/
@WebServlet({ "/HelloServlet", "/ok" })
public class HelloServlet extends HttpServlet {
private static final long serialVersionUID = 1L;

/**
* @see HttpServlet#HttpServlet()
*/
public HelloServlet() {
super();
// TODO Auto-generated constructor stub
}

/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub

InetAddress iAddr;

iAddr = InetAddress.getLocalHost();
String host = iAddr.getHostAddress();

int port = request.getLocalPort();

StringBuffer buf = new StringBuffer();
buf.append("Served at: ").append(host).append(":").append(String.valueOf(port));
buf.append("<br/>").append("X-Real-IP").append(":").append(request.getHeader("X-Real-IP"));
buf.append("<br/>").append("X-Forwarded-For").append(":").append(request.getHeader("X-Forwarded-For"));
buf.append("<br/>").append("X-Forwarded-Host").append(":").append(request.getHeader("X-Forwarded-Host"));


response.getWriter().append(buf.toString());
}

/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}

}

再依次构建 war 包, docker 镜像, 最后使用修改在 Nginx 的反向代理设置(一) 中使用的 docker-compose.yml 文件,将 app1 的镜像文件 image 该为: hello-servlet:1.0, 然后再运行

1
docker-compose up -d

既可以打开浏览器查看结果了。

修改后完整的 docker-compose.yml 文件如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
version: '2'

services:
proxy:
image: my-nginx:1.0
container_name: Proxy-Srv
hostname: proxy
ports:
- "80:80"
volumes:
- ./default.conf:/etc/nginx/conf.d/default.conf
links:
- app1
depends_on:
- app1
app1:
image: hello-servlet:1.0
container_name: App1-Srv
hostname: app1

本文标题:Nginx 的反向代理设置(二)

文章作者:Morning Star

发布时间:2020年12月17日 - 08:12

最后更新:2021年04月16日 - 15:04

原始链接:https://www.mls-tech.info/nginx/nginx-setup-proxy-02/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。