首页 > nginx, 源码分析 > nginx与正向代理

nginx与正向代理

2013年1月12日 发表评论 阅读评论 11,760 次浏览

对于nginx的介绍,往往都会以这么一句评价作为开头:nginx,是一个功能强大的高性能Web和反向代理服务器,……。那么,作为反向代理概念的另一面,正向代理,nginx是否同样支持呢?在解答这个问题之前,需要先搞清楚何谓正向代理,何谓反向代理以及它们之间的联系与差别。

在计算机网络领域,代理服务器也就是充当相互通信双方(按通信请求方client以及通信服务方server两种角色划分)的中间功能媒介的角色,而正向代理和反向代理,只不过是用于对代理服务器在充当中间功能媒介的不同类别的更进一步划分(除了正向代理和反向代理,还有其他类别,具体请看参考1)。即,如果代理服务器充当的是相互通信双方中的client角色,那么就是正向代理。图示如下(来之参考2):

与此相对,如果代理服务器充当的是相互通信双方中的server角色,那么就是反向代理。图示如下(来之参考2):

对此,我们需搞清楚两个问题:
1,所谓正向反向,这个方向性是相对相互通信双方中的client端而言的。
2,要判断一个代理服务器是正向代理还是反向代理,只需检查它在原始双方通信过程中代表着哪一方,替谁干活。

代理服务器的功能有很多,比如在做正向代理时,可以用于代理共享上网,翻(河蟹)墙,掩藏身份(在网易评论里换个火星IP地址,囧)等等;做反向代理时,隐藏服务器端,统一控制,防范攻击,提高服务性能等等。

回到本文的正题:nginx是否支持正向代理?
早在4年前,Igor已经给出了答案:不支持,并且也没有打算在短期内支持。原因是:已经有了非常优秀的正向代理软件,例如squid。

虽然如此,但nginx对正向代理的有限支持还是可以有的,比如对HTTP正向代理的支持(即不支持HTTPS),示例如下(参考2)。

1,编译nginx:

[root@localhost gqk]# tar xzf nginx-1.3.16.tar.gz 
[root@localhost gqk]# cd nginx-1.3.16
[root@localhost nginx-1.3.16]# ./configure 
[root@localhost nginx-1.3.16]# make -j2
[root@localhost nginx-1.3.16]# make install

2,准备配置文件:

[root@localhost nginx-1.3.16]# cat /usr/local/nginx/conf/forward_srv.conf

worker_processes 1;

events {
	worker_connections 1024;
}


http {
	include mime.types;
	sendfile on;

	resolver 8.8.8.8;

	server {
		listen 8888;
		location / {
			proxy_pass $scheme://$http_host$request_uri;
		}
	}
}

3,运行nginx:

[root@localhost nginx-1.3.16]# /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/forward_srv.conf 
[root@localhost nginx-1.3.16]# ps auxf | grep nginx | grep -v grep
root     23937  0.0  0.0  23756   624 ?        Ss   00:08   0:00 nginx: master process /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/forward_srv.conf
nobody   23938  0.0  0.1  24152  1204 ?        S    00:08   0:00  \_ nginx: worker process                                                

4,演示:
server服务端(10.143.135.2:80):利用PHPnow-1.5.6(apache+mysql+php)架设的一台测试服务器。
client客户端(192.168.137.68):CentOS虚拟机。
forward代理端(有两个ip,分别为192.168.137.6以及10.143.135.3):运行nginx的CentOS虚拟机。

在client客户端无法直接访问到server服务端,但可以直接访问到forward代理端:

[root@localhost ~]# ip addr show eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 00:0c:29:ab:03:e1 brd ff:ff:ff:ff:ff:ff
    inet 192.168.137.68/24 brd 192.168.137.255 scope global eth0
    inet6 fe80::20c:29ff:feab:3e1/64 scope link 
       valid_lft forever preferred_lft forever
[root@localhost ~]# ping 10.143.135.2
PING 10.143.135.2 (10.143.135.2) 56(84) bytes of data.
^C
--- 10.143.135.2 ping statistics ---
10 packets transmitted, 0 received, 100% packet loss, time 9505ms
[root@localhost ~]# ping 192.168.137.6
PING 192.168.137.6 (192.168.137.6) 56(84) bytes of data.
64 bytes from 192.168.137.6: icmp_seq=1 ttl=64 time=3.81 ms
64 bytes from 192.168.137.6: icmp_seq=2 ttl=64 time=0.223 ms
^C
--- 192.168.137.6 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1397ms
rtt min/avg/max/mdev = 0.223/2.020/3.818/1.798 ms

在forward代理端可以直接访问到server服务端:

[root@localhost tmp]# ip addr show eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 00:0c:29:bb:06:87 brd ff:ff:ff:ff:ff:ff
    inet 10.143.135.3/8 brd 10.255.255.255 scope global eth0:0
    inet 192.168.137.6/24 brd 192.168.137.255 scope global eth0:1
    inet6 fe80::20c:29ff:febb:687/64 scope link 
       valid_lft forever preferred_lft forever
[root@localhost tmp]# curl http://10.143.135.2/info.php >> info.php
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
101  5683  101  5683    0     0  1077k      0 --:--:-- --:--:-- --:--:-- 1387k

在client客户端使用forward代理端进行正向代理访问到server服务端:

[root@localhost ~]# ping 10.143.135.2
PING 10.143.135.2 (10.143.135.2) 56(84) bytes of data.
^C
--- 10.143.135.2 ping statistics ---
6 packets transmitted, 0 received, 100% packet loss, time 5259ms

[root@localhost ~]# curl -v http://10.143.135.2/info.php >> info.php
* About to connect() to 10.143.135.2 port 80 (#0)
*   Trying 10.143.135.2... ^C
[root@localhost ~]# curl -v -x 192.168.137.6:8888 http://10.143.135.2/info.php >> info.php
* About to connect() to proxy 192.168.137.6 port 8888 (#0)
*   Trying 192.168.137.6... connected
* Connected to 192.168.137.6 (192.168.137.6) port 8888 (#0)
> GET http://10.143.135.2/info.php HTTP/1.1
> User-Agent: curl/7.19.7 (x86_64-unknown-linux-gnu) libcurl/7.19.7 NSS/3.12.6.2 zlib/1.2.3 libidn/1.18 libssh2/1.2.2
> Host: 10.143.135.2
> Accept: */*
> Proxy-Connection: Keep-Alive
> 
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0< HTTP/1.1 200 OK
< Server: nginx/1.3.16
< Date: Sun, 21 Apr 2013 16:48:27 GMT
< Content-Type: text/html
< Content-Length: 5683
< Connection: keep-alive
< X-Powered-By: PHP/5.2.14
< 
{ [data not shown]
101  5683  101  5683    0     0   320k      0 --:--:-- --:--:-- --:--:--  346k* Connection #0 to host 192.168.137.6 left intact

* Closing connection #0
[root@localhost ~]# ls info.php -l
-rw-r--r--. 1 root root 11366 Feb 10 18:11 info.php
[root@localhost ~]# head -n 10 info.php 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>PHPnow Works!</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="author" content="YinzCN" />
<meta name="reply-to" content="YinzCN@Gmail.com" />
<meta name="copyright" content="YinzCN" />
<style type="text/css">
[root@localhost ~]# 

可以看到,利用nginx搭建的正向HTTP代理服务器已经可以正常工作了,对于HTTPS协议,虽然没有测试,但目前看来是不行的,但尚不知道是否有对应的第三方插件。

完全参考:
1,Proxy server
http://en.wikipedia.org/wiki/Proxy_server

2,Forward Proxy vs Reverse Proxy
http://www.jscape.com/blog/bid/87783/Forward-Proxy-vs-Reverse-Proxy

3,Nginx as network edge HTTP cache?
http://serverfault.com/questions/311419/nginx-as-network-edge-http-cache

4,https and nginx as forward proxy
http://forum.nginx.org/read.php?2,15124,15124

5,Does nginx support connect method?
http://www.serverphorums.com/read.php?5,9758

转载请保留地址:http://www.lenky.info/archives/2013/01/2263http://lenky.info/?p=2263


备注:如无特殊说明,文章内容均出自Lenky个人的真实理解而并非存心妄自揣测来故意愚人耳目。由于个人水平有限,虽力求内容正确无误,但仍然难免出错,请勿见怪,如果可以则请留言告之,并欢迎来讨论。另外值得说明的是,Lenky的部分文章以及部分内容参考借鉴了网络上各位网友的热心分享,特别是一些带有完全参考的文章,其后附带的链接内容也许更直接、更丰富,而我只是做了一下归纳&转述,在此也一并表示感谢。关于本站的所有技术文章,欢迎转载,但请遵从CC创作共享协议,而一些私人性质较强的心情随笔,建议不要转载。

法律:根据最新颁布的《信息网络传播权保护条例》,如果您认为本文章的任何内容侵犯了您的权利,请以Email或书面等方式告知,本站将及时删除相关内容或链接。

分类: nginx, 源码分析 标签: ,
  1. 2013年12月25日22:32 | #1

    貌似nginx做正向代理很慢, 而且代理二级页面往往是404啊。。。

    • lenky
      2013年12月26日17:00 | #2

      额,那你不妨试试其他擅长正向代理的工具,例如squid,看是否有同样的问题,再判断是否是nginx本身的问题。

  2. boy
    2013年12月3日21:42 | #3

    恩,感谢您的回复。
    我再了解了解fastcgi、upstream模块看看是否有什么借鉴的地方。

  3. boy
    2013年12月3日11:49 | #4

    拜读了博主的书,受益匪浅。
    最近开发了一个Nginx的插件,HTTP协议的一个handler。
    我希望能够把用户提交的数据部分数据插入到数据库中,希望能够支持MySQL、Oracle、MS SqlServer等流行数据库。
    但是数据库的客户端接口多少阻塞式的API,这会影响Nginx的效率,在这方面有没有什么建议?

    • lenky
      2013年12月3日13:54 | #5

      没有办法转为未阻塞式么?
      或把这部分逻辑解耦,单独到一个进程去操作?Nginx只负责写共享内存即可。涉及到数据交互的问题,可以用环形队列?
      是否有必要这么麻烦,需要具体测试量化一下吧?

  1. 本文目前尚无任何 trackbacks 和 pingbacks.