详解正向代理与反向代理

Posted Dax1_

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了详解正向代理与反向代理相关的知识,希望对你有一定的参考价值。

1.正向代理

1.1 概念

正向代理是一个位于客户端和目标服务器之间的代理服务器(中间服务器)。为了从目标服务器取得内容,客户端向代理服务器发送一个请求,并且指定目标服务器,之后代理向目标服务器转发请求,将获得的内容返回给客户端。正向代理的情况下,客户端必须要进行一些特殊的设置才能使用。

1.2 特点

  • 正向代理需要主动设置代理服务器ip或者域名进行访问,由设置的服务器ip或者域名去访问内容并返回
  • 正向代理是代理客户端,为客户端收发请求,使真实客户端对服务器不可见。

1.3 使用场景

正向代理的典型用途是为防火墙内的局域网客户端提供访问服务器的途径,正向代理还可以使用缓冲特性减少网络利用率。

  • 科学上网(翻墙)

有时候,用户想要访问某国外网站,该网站无法在国内直接访问,但是我们可以访问到一个代理服务器,这个代理服务器可以访问到这个国外网站。这样呢,用户对该国外网站的访问就需要通过代理服务器来转发请求,并且该代理服务器也会将请求的响应再返回给用户。这个上网的过程就是用到了正向代理。

1.4 用途

  • 突破访问显示:通过代理服务器,可以突破自身ip访问限制,访问国外网站等
  • 提高访问速度:通常代理服务器都设置一个较大的硬盘缓冲区,会将部分请求的响应保存到缓冲区中,当其他用户再访问相同的信息时,则直接由缓冲区中取出信息,传给用户,以提高访问速度
  • 隐藏客户端真实ip:上网者可以通过正向代理的方法隐藏自己的ip,免受攻击

2.反向代理

2.1 概念

反向代理是指以代理服务器来接收客户端的请求,然后将请求转发给内部网络上的服务器,将从服务器上得到的结果返回给客户端,此时代理服务器对外表现为一个反向代理服务器。

对于客户端来说,反向代理就相当于目标服务器,只需要将反向代理当作目标服务器一样发送请求就可以了,并且客户端不需要进行任何设置。

2.2 特点

  • 正向代理需要配置代理服务器,而反向代理不需要做任何设置。
  • 反向代理是代理服务器,为服务器收发请求,使真实服务器对客户端不可见。

2.3 使用场景

反向代理的典型用途是将防火墙外的服务器提供给客户端访问,反向代理还可以为后端的多台服务器提供负载均衡,或者为后端较慢的服务器提供缓冲服务。

2.4 用途

  • 隐藏服务器真实ip:使用反向代理,可以对客户端隐藏服务器的ip地址
  • 负载均衡:反向代理服务器可以做负载均衡,根据所有真实服务器的负载情况,将客户端请求分发到不同的真实服务器上
  • 提高访问速度:反向代理服务器可以对静态内容及短时间内有大量访问请求的动态内容提供缓存服务,提高访问速度
  • 提供安全保障:反向代理服务器可以作为应用层防火墙,为网站提供对基于web的攻击行为(例如DoS/DDoS)的防护,更容易排查恶意软件等。还可以为后端服务器统一提供加密和SSL加速(如SSL终端代理),提供HTTP访问认证等。

3.正向代理和反向代理的异同

3.1 相同点

正向代理和反向代理所处的位置都是客户端和真实服务器之间,所做的事情也都是把客户端的请求转发给服务器,再把服务器的响应转发给客户端。

3.2 不同点

  • 正向代理是客户端的代理,服务器不知道真正的客户端是谁;反向代理是服务器的代理,客户端不知道真正的服务器是谁
  • 正向代理一般是客户端架设的;反向代理一般是服务器架设
  • 正向代理主要是用来解决访问限制问题;反向代理则是提供负载均衡、安全防护等作用。二者都能提高访问速度

4.通过故事理解正向代理和反向代理

4.1 正向代理

同学A急需一笔钱,他直接向富豪马云借钱,但是他俩之间毫无关系,结果当然是没有借到。经过一番打听,同学A的老师王先生是马云的好朋友,于是A同学请求王老师,让王老师帮忙向马云借钱,最终马云同意借钱给王老师,王老师把这笔钱转交给了A同学。

上文就相当于一个正向代理的过程,A同学为客户端,马云为服务器,王老师为正向代理。A同学请求王老师向马云借钱,这个过程中A同学隐藏了自己的角色,马云事实上是不知道到底是谁借的钱。相当于服务器不知道真正发起请求的客户端是谁。

4.2 反向代理

如果遇到困难需要拨打10086客服电话,可能一个地区的10086客服有几十个,但是我们不需要关心电话那头的人是谁。只需要拨通10086的总机号码,电话那头总有客服会回应。

这里的10086总机号码就相当于反向代理,客户端不知道真正提供服务的人是谁。

参考文档

正向代理与反向代理的区别 - 简书

终于有人把正向代理和反向代理解释的明明白白了!

squid详解(正向代理透明代理反向代理)

squid正向代理案例详解,透明代理案例详解,反向代理案例详解。通过案例理解三种代理模式


squid   
http://www.squid-cache.org/  --官方网址

squid软件主要有两大应用:1,代理上网(正向代理,透明代理)
       2,网站静态页面缓存加速(反向代理)
三种代理类型:
正向代理 代理内部主机上网,共享上网,缓存,控制内网用户上网行为等功能(客户端需要设置代理服务器的IP和代理端口)
透明代理 和正向代理的功能完全一致(客户端不需要设置代理服务器的IP和代理端口,对用户是透明的)
正向代理分析图:
外网
|
modem
|
路由器(dhcp,snat共享上网,上网行为控制,限速等)
|
|
squid正向代理(共享上网,静态页面缓存加速,内网用户四七层上网行为控制,限速等)
|
|
|----------------------|
上网用户一 上网用户二

反向代理 从外部网络访问内部服务器,与正向方向相反,主要用于网站架构的缓存加速或CDN
反向代理分析图:
client
|
|
反向代理 (缓存加速,七层切分,负载均衡,会话保持等)


web
===================================================================
正向代理实验
公网


br0 172.16.13.250
squid 服务器
virbr1 192.168.100.1
|
|
|
内网用户VM1
eth0(virbr1)
192.168.100.128
准备如图所示的虚拟机及网络配置
准备这个拓扑图要注意的地方:
1,宿主机(squid服务器)需要能上外网,在这里就是指向公司的路由器
2,192.168.100.0网络,我这里使用kvm的virbr1网段来模拟
3,内网用户只要与squid服务器能ping通就行,不用指网关和DNS
4,内网用户需要安装图形界面,并安装firefox浏览器
5,squid服务器能上外网,但内网用户不能上外网,我们的目地就是让squid代理内网用户上外网

第一步:在squid服务器上安装squid
# yum install squid -y
扩展:安装完后,会有一份官方文件在下面的路径下
/usr/share/doc/squid-3.5.20/squid.conf.documented

第二步:修改配置文件
# vim /etc/squid/squid.conf
http_access allow all --把deny all改成allow all
cache_dir ufs /var/spool/squid 100 16 256 --把缓存目录这一句打开注释

如果要简单优化,则可以加上cache_mem参数,你多余的内存大小都可以指定给cache_mem
比如
cache_mem 5000M
cache_dir ufs /var/spool/squid 5000 16 256 --这个100指的是此目录可以存放的缓存空间大小,磁盘空间足够,可以尽量调大
内存---》磁盘
cache_mem /var/spool/squid
---------------------------------------------------------

第三步:
启动服务
# systemctl start squid
# lsof -i:3128 --查看3128端口
COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME
squid 4937 squid 12u IPv4 36871 TCP *:squid (LISTEN)

第四步:
客户端的测试
不用设置网关和DNS指向
主要是修改浏览器(具体步骤如下)
--filefox配置
firefox浏览器右上角open menu--preferences--advanced--network--settings-- 手动填写代理服务器的IP和代理端口
此处填写就应该填写172.16.13.250 端口3128  然后保存退出后就能成功上外网了

--IE配置
右键IE图标--连接--局域网设置--为LAN使用代理服务器前打勾并填上代理服务器的内网IP及其代理端口

测试:
访问已经访问过的页面是否能感觉到页面加快
再次查看 du -s /var/spool/squid 发现增大,因为缓存了对象
查看相关日志 /var/log/squid/access.log
--此日志可以看到所有被代理的内网用户访问的网址和时间等信息
# date -d "@1500620984" +%F %T
================================================================
透明(transparent)代理实验:
准备工作:先把上面的正向代理客户端的浏览器设置去掉
第一步:
在squid服务器上打开路由转发功能

# vim /etc/sysctl.conf --更改配置文件
net.ipv4.ip_forward = 1
# sysctl -p  --用此命令让其生效

第二步:修改配置文件
# vim /etc/squid/squid.conf
http_port 3128 intercept  --intercept打开支持透明代理
# systemctl restart squid  --重启服务

第三步:配置iptables
client squid 公司路由器
virbr1 br0
192.168.100.128 192.168.100.1 172.16.13.250--> 172.16.13.254 公网IP
|
|
|
client网关指向192.168.100.1--
clientDNS指向114.114.114.114 ----------------------->外网DNS(8.8.8.8)

由上面的分析,需要在squid服务器上写上一句snat,让DNS能正常访问外网
# iptables -F
# iptables -F -t nat
# iptables -F -t mangle
# iptables -t nat -A POSTROUTING -p udp --dport 53 -o br0 -j SNAT --to-source 172.16.13.250

这样的话,内网客户端的DNS OK了,但是http的80端口的访问如果也做一个SNAT的话,如下的规则:
# iptables -t nat -A POSTROUTING -p tcp --dport 80 -o br0 -j SNAT --to-source 172.16.13.250
那么这就做的是完全的通过iptables来上外网;与squid无关
所以应该换成下面一句规则,把80端口的访问都重定向到3128端口
# iptables -t nat -A PREROUTING -p tcp --dport 80 -i virbr1 -j REDIRECT --to-port 3128
还有443的端口问题,这里如果也重定向到3128,会出现访问https网站报ssl错误。我们这里把443用iptables直接SNAT转发出去(也就是说443与squid无关)
# iptables -t nat -A POSTROUTING -p tcp --dport 443 -o br0 -j SNAT --to-source 172.16.13.250
第四步:测试验证
内网用户(也就是client端)用浏览器访问网页,就会发现能够成功访问
==================================================================================
此处插入一点知识点:
squid的acl(access control list)访问控制(下面列举一些常见的控制)

acl denyip src 192.168.100.128/32 --拒绝内网的192.168.100.128/32上网
http_access deny denyip

acl denyip src 192.168.100.128-192.168.100.132/255.255.255.255
http_access deny denyip

acl vip arp 00:0C:29:79:0C:1A
http_access allow vip

acl baddsturl2 dst 220.11.22.33 --不能访问这个外网IP的网站
http_access deny baddsturl2

acl baddsturl dstdomain -i www.163.com --不能访问www.163.com和WWW.163.COM;-i参数定义大小写都匹配; 但是可以访问war.163.com或sports.163.com
http_access deny baddsturl

acl baddsturl dstdom_regex -i 163 --这是把163以下的所有域名都禁止 ,但直接使用IP仍然是可以访问的
http_access deny baddsturl

acl baddsturl dstdom_regex "/etc/squid/baddsturl" --如果网址太多,可以写成一个文件,然后在这个文件里一行一个网站写上你要禁止的
http_access deny baddsturl

acl baddsturl3 url_regex -i baidu --拒绝访问url里有baidu这个关键字的网站
http_access deny baddsturl3

acl badfile urlpath_regex -i \\.mp3$ \\.rmvb$ \\.exe$ \\.zip$ \\.mp4$ \\.avi$ \\.rar$
http_access deny badfile --禁止下载带有定义后缀名的文件

acl badipclient2 src 192.168.100.0/255.255.255.0
acl worktime time MTWHF 9:00-17:00
http_access deny badipclient2 worktime --拒绝192.168.100.0网段工作时间不能上网

acl badipclient3 src 192.168.100.128
acl conn5 maxconn 5
http_access deny badipclient3 conn5 --最大连接数为5

访问控制案例
实现如下要求:
1,允许周一到周五12:00-14:00和17:30-21:00和双休能上网,别的时间不能上网
2,禁止下载.exe .rar .mp3 .avi .rmvb .mp4后缀的文件
3,禁止访问qq.com,mop.com,sina.com,163.com,youku.com
4,禁止访问网址中包含某些关键字的网站:比如 sex news movie sport game stock
5, vip没有任何限制
--把上面五点情况做成两种需求:
1,上课时间不能上任何网站,休息时间可以上网,但受限, vip没有任何限制
理论分析:
http_access    允许  vip
http_access   拒绝  限制
http_access    允许  休息时间
http_access deny all

实验需求一:
# vim /etc/squid/squid.conf
acl lunchtime time MTWHF 12:00-14:00
acl dinnertime time MTWHF 17:30-21:00
acl weekend time SA 00:00-24:00
acl badfile urlpath_regex -i \\.mp3$ \\.rmvb$ \\.exe$ \\.zip$ \\.mp4$ \\.avi$ \\.rar$
acl badweb dstdom_regex "/etc/squid/denywebsite"
acl badword url_regex -i sex news movie sport game stock
acl vip arp 00:0C:29:79:0C:1A
http_access allow vip
http_access deny badfile
http_access deny badweb
http_access deny badword
http_access allow lunchtime
http_access allow dinnertime
http_access allow weekend
http_access deny all
# vim /etc/squid/denywebsite
qq
sina
mop
163
youkud
# systemctl restart squid
2,上课时间可以上网,但受限,休息时间可以无限制上网, vip没有任何限制
理论分析:
http_access   允许  vip
http_access   允许  休息时间
http_access 拒绝  限制
http_access allow all
实验需求二:
# vim /etc/squid/squid.conf
acl lunchtime time MTWHF 12:00-14:00
acl dinnertime time MTWHF 17:30-21:00
acl weekend time SA 00:00-24:00
acl badfile urlpath_regex -i \\.mp3$ \\.rmvb$ \\.exe$ \\.zip$ \\.mp4$ \\.avi$ \\.rar$
acl badweb dstdom_regex "/etc/squid/denywebsite"
acl badword url_regex -i sex news movie sport game stock
acl vip arp 00:0C:29:79:0C:1A
http_access allow vip
http_access allow lunchtime
http_access allow dinnertime
http_access allow weekend
http_access deny badfile
http_access deny badweb
http_access deny badword
http_access allow all
=========================================================================================================
反向代理实验:
client 比喻→ 国外客户
|  |
反向代理 海外仓储
| | 
web 国内公司
client
|
|
正向代理(静态加速)

因特网


1个或多个反向代理(较近地理位置增强响应时间,静态缓存加速,网站数据切分) cdn
|
前端web
|
中间件

数据库
    |
存储
准备如下图的虚拟机:
client 172.16.25.2 比喻→  要租房或买房的客户


br0 172.16.25.1
squid 服务器 房产中介
virbr1 192.168.100.1
|
|
|
内网web服务器VM1
eth0(virbr1) 要出租或卖房的业主
192.168.100.128
--注意:
192.168.100.1为squid的一个内网IP
172.16.25.1为squid的外网IP(也就是说在这个架构里squid在最前端)
172.16.25.2 为外网客户端

第一步:
在内网web服务器上安装httpd,并做一个主页用于测试
# yum install httpd* -y
# echo "内网web" > /var/www/html/index.html
# systemctl restart httpd

第二步:
在squid服务器上安装,并进行配置
# yum install squid -y
用一个新的配置文件;如果是在上面的透明代理基础上再做反向代理,先注释掉前面所有的配置
# vim /etc/squid/squid.conf
http_access allow all --ACL我这里直接允许所有(这一句前面的ACL配置我这里全删除了)
http_port 80 accel vhost vport
--80 因为外网客户只能访问的是你的80端口,所以此处将其改为80
            --accel 反向代理加速模式
--vhost 支持域名或主机名来表示代理节点
--vport 支持IP和端口来表示代理节点
cache_peer 192.168.100.128 parent 80 0 no-query originserver name=web
--192.168.100.128 内网web服务器的IP
--parent 上下关系,非平级关系
--80 代理内部web服务器的80端口
--0 没有使用icp,表示就一台squid服务器
--no-query 不去查询邻居,与上面的0结合使用
--originserver 表示源实际服务器
--name=web 定义一个名字,让后面的参数引用
cache_peer_domain web web.cluster.com --对web.cluster.com的请求会给web这台服务器(也就是上面定义的192.168.100.128);如果有多台web的话,可以多台web绑定同一个域名,还可以实现RR轮循调度
cache_peer_domain web 172.16.25.1 --光写上面一条,客户端只能通过web.cluster.com访问,再加上这条,客户端就可以使用172.16.25.1来访问
cache_dir ufs /var/spool/squid 256 16 256
# systemctl restart squid

--测试:
所以这里客户端的DNS解析web.cluster.com应该得到172.16.25.1的结果
所以这里不做DNS的话,就直接在/etc/hosts里写上
172.16.25.1 web.cluster.com
再使用http://web.cluster.com 就可以访问到内部的web服务器了
可以使用curl -I http://web.cluster.com去查有没有命中缓存
======================================================================
问题一:
squid如何代理多个web?
vim /etc/squid/squid.conf
http_port 80 accel vhost vport
cache_peer 192.168.100.128 parent 80 0 no-query originserver round-robin name=web1
cache_peer 192.168.100.129 parent 80 0 no-query originserver round-robin name=web2
cache_peer 192.168.100.130 parent 80 0 no-query originserver round-robin name=web3
cache_peer 192.168.100.131 parent 80 0 no-query originserver round-robin name=web4
cache_peer_domain web1 web2 www.aaa.com
cache_peer_domain web3 web4 www.bbb.com
======================================================================
问题二:
如何配置下面的squid集群?
参考
http://www.ibm.com/developerworks/cn/linux/l-cn-squid

172.16.25.X
client

www.abc.com
通过dns技术(dns轮循或智能dns);通过负载均衡软件(nginx,haproxy,lvs)

172.16.25.1 172.16.25.2
squid1 squid2
192.168.100.1 192.168.100.2

web1 web2
192.168.100.128 192.168.100.129
配置过程
第一步:
两个web上安装httpd,并建立两个不同主面方便测试(注意这里所有的机器的时间一定要同步,特别是web1和web2;如果web1和web2的时间隔得太久,可能会造成客户端访问时,不先访问缓存而是访问后台web,也就是缓存失效了)
过程省略
第二步:
安装并配置squid1
# yum install squid -y
# vim /etc/squid/squid.conf
http_access allow all
cache_dir ufs /var/spool/squid 256 16 256
http_port 80 accel vhost vport

icp_port 3130
icp_access allow all
cache_peer 192.168.100.2 sibling 80 3130
cache_peer 192.168.100.128 parent 80 0 no-query originserver round-robin name=web1
cache_peer 192.168.100.129 parent 80 0 no-query originserver round-robin name=web2
cache_peer_domain web1 web2 www.abc.com
# /etc/init.d/squid start

第三步:
安装并配置squid2
把squid1的配置文件拷过来,只需要修改一个地方(就是sibling的IP)
# yum install squid -y
# vim /etc/squid/squid.conf
cache_peer 192.168.100.1 sibling 80 3130 --把这个IP换成对方的IP
然后也启动服务
# /etc/init.d/squid start

第四步:
在客户端测试
# vim /etc/hosts --绑定IP地址与域名来模拟DNS(注意这里不能实现DNS轮循,所以手动绑定其中指定解析为squid1或squid2)
172.16.25.1 www.abc.com
# vim /etc/hosts
172.16.25.2 www.abc.com

====================================================================================================
扩展项目: (可自主进行搭建)
模拟cdn
squid+dns-view实现
北京


成都 武汉 上海


广州
(网站源在深圳)

人生是条无名的河,是浅是深都要过; 人生是杯无色的茶,是苦是甜都要喝; 人生是首无畏的歌,是高是低都要唱。


以上是关于详解正向代理与反向代理的主要内容,如果未能解决你的问题,请参考以下文章

详解正向代理与反向代理

Nginx详解(正向代理反向代理负载均衡原理)

正向代理/反向代理理解Nginx概述安装及配置详解

Apache正向代理反向代理

Nginx反向代理常用配置

Atitit.HTTP 代理原理及实现 正向代理与反向代理attilax总结