Nginx由于其体积小、性能强而被广泛使用,而其中用其做反向代理服务器是非常常见的。但其实Nginx也是可以用来做正向代理服务器的,本文就记录我用Nginx做正向代理服务器和反向代理服务器的过程。

关于正向代理和反向代理的示意图如下:

proxy-type

一、用Nginx做正向代理服务器

如下所示,假设我们现在本地电脑所连接的是某公司的内网,而该公司设置了只有通过公司的代理服务器才能访问公网。那我们现在的本地电脑仅连接了网络的话,也不能访问公网,必须要设置代理为公司代理服务器的地址,之后才可以通过代理服务器访问公网。

nginx-forward-proxy

下面,我们就配置一台Nginx来作为图中的正向代理服务器。

首先,我们打开本地电脑也即192.168.0.207的终端,然后执行如下命令:

1
2
3
curl -i http://example.com/
# 可以得到正常返回信息(HTTP/1.1 200 OK,其余的此处省略了,太占篇幅)
# 但在真实场景下此处应该是curl不通的,因为我们尚未配置代理,无法访问公网嘛

然后,我们设置代理:

1
export http_proxy=192.168.0.199:8080

然后再次访问一下http://example.com/

1
2
3
4
curl -i http://example.com/
# 此时就会得到如下信息,因为我们尚未配置代理
curl: (7) Failed to connect to 192.168.0.199 port 8080 after 22 ms: Connection refused
(base)

上面是准备工作,下面我们正式开始配置正向代理服务器(即192.168.0.199)。此处我们仅做演示,所以最简化配置,在nginx.conf文件中的http模块下添加部分内容:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
http {
	  # http模块下的其他内容此处省略,以下为本次新增的配置
	  
    # 设置DNS服务器
    resolver    8.8.8.8;
    # 新加一个虚拟主机
    server {
        # 监听8080端口
        listen        8080;
        # 直接代理到目标地址
        location / {
            proxy_pass http://$http_host$request_uri;
        }
    }
}

按上述配置好之后,启动Nginx,此时再次使用本地电脑来访问http://example.com/

1
2
curl -i http://example.com/
# 此时可以访问成功了:HTTP/1.1 200 OK

除此之外,我们还可以通过查看Nginx的access.log,来确认刚刚的这次访问的确是走了代理服务器的,此时的access.log中应该有一行:

1
192.168.0.207 - - [06/Apr/2022:22:06:37 +0800] "GET http://example.com/ HTTP/1.1" 200 1256 "-" "curl/7.79.1"

二、用Nginx做反向代理服务器

如下所示,我们先配置域名nginx.hongmao.run解析到192.168.0.199,然后192.168.0.199再转发到192.168.0.200,在真实的生产环境中,目标服务器(也即192.168.0.200)可能不是Nginx了,而是Tomcat之类的。而Tomcat之类的这种Web服务器提供的服务一般不会直接向公网开放,而是通过Nginx服务器来反向代理一下,我们下面就模拟这个过程,但是我们此处不用Tomcat了,目标服务器也用Nginx来实现。

nginx-reverse-proxy

首先,将199和200这两台机器上的Nginx的index.html修改以下,分别添加一行<p>current ip: 192.168.0.199</p><p>current ip: 192.168.0.200</p>,用于区分当前访问到了哪台机器。

然后,启动192.168.0.199上的Nginx服务器,无需改动配置,通过IP能正常访问即可。然后,增加域名hongmao.run的解析记录,使nginx.hongmao.run解析到192.168.0.199,然后,访问nginx.hongmao.run,可以正常访问,因为此处几台机器都是在同一个局域网内。

然后,启动192.168.0.200上的Nginx服务器,通过IP可以正常访问即可,然后设置该服务仅允许192.168.0.199访问。设置过程如下:

先修改192.168.0.200的配置文件:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
server {
    listen       80;
    server_name  localhost;

    location / {
        root   html;
        index  index.html index.htm;
        # 添加下行配置,允许192.168.0.199
        allow  192.168.0.199;
        # 添加下行配置,拒绝所有。此处从上至下读取配置,匹配到规则就不往下匹配了,所以此处需要先allow再deny,不然就全部deny了
        deny   all;
    }
    # 添加如下配置,是在未授权的机器访问该服务时,跳转到指定的页面去
    error_page  403  /403.html;
        location = /403.html {
	      root   html;
	  }
    # 此处默认的配置未修改,省略不写了
}

如此配置之后,非192.168.0.199的机器访问时,均会得到403的响应,我们上面在配置中配置了当403时跳转到html/目录下的403.html页面,所以,此处我们还需要写一个403的页面,放在html/目录下:

1
2
3
4
5
6
7
8
9
<!DOCTYPE html>
<html>
	<head>
		<title>Welcome to nginx!</title>
	</head>
	<body>
		<h1>Hello! my ip is 192.168.0.200, only allow 192.168.0.199 access.</h1>
	</body>
</html>

刷新了配置文件后,我们在本地电脑(192.168.0.207)上访问192.168.0.200,此时应该得到的是我们配置的那个403页面。

接下来,我们就需要配置反向代理服务器(192.168.0.199)了:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
server {
    listen       80;
    server_name  localhost;
    location / {
        # 此处的root、index就不需要了
        # 添加下行配置,反向代理至192.168.0.200
         proxy_pass   http://192.168.0.200;
    }
    # 此处默认的配置未修改,省略不写了
}

刷新了配置文件后,此时我们访问http://nginx.hongmao.run/看到的最下面一行应该是“current ip: 192.168.0.200”,至此我们就用Nginx实现了反向代理。