前言
nginx不仅可以来做反向代理,也可以用来做正向代理(透明代理,代理上网),首先先来了解下什么是正向代理和反向代理以及两者之间的区别。
正文
正向代理
正向代理是一个位于客户端和原始服务器之间的服务器, 从而为客户端从原始服务器中取得所需要的数据。客户端向代理服务器发送一个请求,并且写明了地址。之后代理向原始服务器转交并且将获得的内容返回给客户端。客户端必须要进行一些特别的设置才能使用正向代理服务器
这里引用一个篇博文的例子
1
| A用户无法访问twitter,但是我能访问B服务器,而B服务器可以访问twitter。于是我访问B服务器,告诉它”嗨,伙计,我要访问twitter“,B服务器收到请求后,去访问twitter,twitter把响应信息返回给B服务器,B服务器再把响应信息返回给A。这样,通过B代理服务器,就实现了翻墙。
|
反向代理
反向代理正好相反。对于客户端来说,反向代理就好像原始服务器。并且客户端不需要进行任何设置。客户端向reverse proxy中的name-space发送请求,接着反向代理判断请求走向何处,并将请求转交给客户端。这些内容就好似他自己一样。
两者区别
- 从用途上来区分:
正向代理:正向代理用途是为了在防火墙内的局域网提供访问internet的途径。另外还可以使用缓冲特性减少网络使用率
反向代理:反向代理的用途是将防火墙后面的服务器提供给internet用户访问。同时还可以完成诸如负载均衡等功能
- 从安全性来讲:
正向代理:正向代理允许客户端通过它访问任意网站并且隐蔽客户端自身,因此你必须采取安全措施来确保仅为经过授权的客户端提供服务
反向代理:对外是透明的,访问者并不知道自己访问的是代理。对访问者而言,他以为访问的就是原始服务器
配置相关示例
下面主要说下nginx正向代理配置
window下测试的配置:
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
| #user nobody; worker_processes 1; #error_log logs/error.log; #error_log logs/error.log notice; #error_log logs/error.log info; #pid logs/nginx.pid; events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '$http_host $request_uri ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log logs/access.log main; sendfile on; #tcp_nopush on; #keepalive_timeout 0; keepalive_timeout 65; #gzip on; server{ resolver 8.8.8.8; resolver_timeout 30s; listen 80; location / { proxy_pass http://$http_host$request_uri; proxy_set_header Host $http_host; proxy_buffers 256 4k; proxy_max_temp_file_size 0; proxy_connect_timeout 30; proxy_cache_valid 200 302 10m; proxy_cache_valid 301 1h; proxy_cache_valid any 1m; } } }
|
实际就是获取$http_host$request_uri变量值重新拼接用户访问的url,当然以上配置尚未支持https。
启动nginx之后。下面给出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
| public static void t1() throws Exception { BufferedReader in = null; String content = null; try { HttpClient client = new DefaultHttpClient(); HttpGet request = new HttpGet("http://www.ruanyifeng.com/blog/2010/02/url_encoding.html"); HttpHost proxy = new HttpHost("127.0.0.1", 80); client.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, proxy); HttpResponse response = client.execute(request); in = new BufferedReader(new InputStreamReader(response.getEntity().getContent())); StringBuffer sb = new StringBuffer(""); String line = ""; String NL = System.getProperty("line.separator"); while ((line = in.readLine()) != null) { sb.append(line + NL); } in.close(); content = sb.toString(); } catch (Exception e) { e.printStackTrace(); } finally { if (in != null) { try { in.close(); } catch (Exception e) { e.printStackTrace(); } } System.err.println(content); } }
|
以上代码是通过本地80端口配置的代理访问http://www.ruanyifeng.com/blog/2010/02/url_encoding.html ps:代码依赖HttpClient
的jar包
这里就不贴程序打印的结果了。查看下nginx的access.log就知道是否成功访问
1
| 127.0.0.1 - - [07/May/2016:21:56:27 +0800] "GET /blog/2010/02/url_encoding.html HTTP/1.1" 200 99394 "-" www.ruanyifeng.com /blog/2010/02/url_encoding.html "Apache-HttpClient/4.3.6 (java 1.5)" "-"
|
也可以通过以下代码访问:
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
| public static void test() throws Exception { BufferedReader in = null; String content = null; try { HttpClient client = new DefaultHttpClient(); HttpGet request = new HttpGet("http://127.0.0.1/blog/2010/02/url_encoding.html"); request.setHeader("Host", "www.ruanyifeng.com"); HttpResponse response = client.execute(request); in = new BufferedReader(new InputStreamReader(response.getEntity().getContent())); StringBuffer sb = new StringBuffer(""); String line = ""; String NL = System.getProperty("line.separator"); while ((line = in.readLine()) != null) { sb.append(line + NL); } in.close(); content = sb.toString(); } finally { if (in != null) { try { in.close(); } catch (Exception e) { e.printStackTrace(); } } System.err.println(content); } }
|
效果是一样的。
参考: