-- squid http://www.squid-cache.org/ 代理服务器的作用 共享网络,加快网络访问速度(缓存),防止内部主机受攻击,限制用户访问(七层限制)等 外网 | | 路由器 | | squid正向代理 | | |----------------------| 上网用户一 上网用户二 三种代理类型 正向代理 客户端需要设置代理服务器的IP和代理端口 --代理内部主机上网(共享上网,并可以进行用户限制等功能) 透明代理 客户端不需要设置代理服务器的IP和代理端口,对用户是透明的 反向代理 从网络访问内部服务器,与正向相反 client | | 反向代理 | | web --关于它们的应用: 正向和透明用于控制上网行为,共享上网等网络管理功能 反向代理主要应用于架构。 有四层和七层等之分,可用于动静分离等架构。 硬件反向代理负载均衡调度:F5 BIG-IP squid varnish haproxy apache nginx 客户端 缓存(正向代理) --- 缓存(反向代理) apache+php(缓存) memcache(缓存) mysql(query-cache 缓存) 实验环境 公网 | | eth0 172.16.2.35 squid 服务器 vmnet1 192.168.1.1 内网用户VM1 内网用户VM2 eth0 eth0 192.168.1.128 192.168.1.129 准备这个拓扑图要注意的地方 1,宿主机(squid服务器)需要能上外网,在这里就是指向公司的路由器 2,192.168.1.0网络,我这里使用vmware的vmnet1网段来模拟 3,内网用户只要与squid服务器能ping通就行,不用指网关和DNS 4,内网用户需要安装图形界面,并安装firefox浏览器 5,squid服务器能上外网,但内网用户不能上外网,我们的目地就是让squid代理内网用户上外网 第一步:安装squid www.squid-cache.org # yum install squid -y 第二步:修改配置文件 rhel6.5下自带的squid(主配置文件少了很多参数,文档都写到了/usr/share/doc/squid-3.1.10/squid.conf.documented这个文件里) --rhel6.5下的配置 vim /etc/squid/squid.conf 59 http_access allow all --把deny all改民allow all 68 cache_dir ufs /var/spool/squid 100 16 256 --把缓存目录这一句打开注释 如果你第二次重启squid时报下面的错误,表示内存高速缓存大于磁盘缓存的总空间 WARNING cache_mem is larger than total disk cache space! 原因:默认情况下,cache_mem为256M,而squid的配置里磁盘缓存默认为100M 如果你要解决这个问题的话: 1,第一种方式:调小cache_mem,因为磁盘缓存默认是100M,所以你加上一句cache_mem 100 MB 2,第二种方式:调大磁盘缓存;如cache_dir ufs /var/spool/squid 256 16 256;把100换成256 --------------------------------------------------------- 第三步: 初始化缓存目录 --在rhel6的启动脚本里也会帮你初始化,如果你是第一次启动的话 ls /var/spool/squid --初始化之前为空 squid -zX --z参数创建缓存目录,X参数是打开调试功能,在这里就是可以看到创建过程 ls /var/spool/squid --初始化之后再查看,就创建了16个目录,每个目录里256个子目录 du -sh /var/spool/squid/ --查看一下大小,目前为17M # du -sh /var/spool/squid/ 17M /var/spool/squid/ # du -s /var/spool/squid/ 16452 /var/spool/squid/ 第三步: 启动服务 /etc/init.d/squid start 重新装载的话可以使用 /etc/init.d/squid reload 或者使用 squid -k reconfig 停服务可以使用 /etc/init.d/squid stop 或者使用 squid -k shutdown [root@li ~]# lsof -i:3128 --查看3128端口 COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME squid 4937 squid 12u IPv4 36871 TCP *:squid (LISTEN) 第四步: 客户端的测试 不用设置网关和DNS指向 主要是修改浏览器 --filefox配置 编辑--性能--高级--网络--设置-- 手动填写代理服务器的IP和代理端口 --IE配置 右键IE图标--连接--局域网设置--为LAN使用代理服务器前打勾并填上代理服务器的内网IP及其代理端口 测试: 访问已经访问过的页面是否能感觉到页面加快 再次查看 du -s /var/spool/squid 发现增大,因为缓存了对象 查看相关日志 /var/log/squid/squid/*.log ================================================================ 透明(transparent)代理: 第一步: 在squid服务器上打开路由转发功能 # vim /etc/sysctl.conf net.ipv4.ip_forward = 1 --因为要使用iptables写NAT表的规则,所以要打开ip_forward # sysctl -p 第二步:修改配置文件 # vim /etc/squid/squid.conf http_port 3128 intercept # /etc/init.d/squid restart 第三步:配置iptables client squid 公司路由器 vmnet1 eth0 192.168.1.128 192.168.1.1 172.16.2.35--> 172.16.1.1 公网IP | | | client网关指向192.168.1.1-- clientDNS指向8.8.8.8 ---------------------------------->外网DNS 由上面的分析,需要在squid服务器上写上一句snat,让DNS能正常访问外网 # iptables -t nat -A POSTROUTING -p udp --dport 53 -o eth0 -j SNAT --to-source 172.16.2.35 这样的话,内网客户端的DNS OK了,但是http的80端口的访问如果也做一个SNAT的话,如下的规则: # iptables -t nat -A POSTROUTING -p tcp --dport 80 -o eth0 -j SNAT --to-source 172.16.2.35 那么这就做的是完全的通过iptables来上外网;与squid无关 所以应该换成下面一句规则,把80端口的访问都重定向到3128端口 # iptables -t nat -A PREROUTING -p tcp --dport 80 -i vmnet1 -j REDIRECT --to-port 3128 # iptables -t nat -A PREROUTING -p tcp --dport 443 -i vmnet1 -j REDIRECT --to-port 3128 第四步:客户端验证 省略 总结: --上面所做的透明代理其实和上次iptables所讲的几乎一样,唯一不同的就是把80端口的SNAT换成了端口的转换,把它交给3128的squid来上网 --但就上面这样做,并没有看出比使用iptables上网有什么优势 --squid共享上网的优势就在于使用acl访问控制,缓存,资源控制等 ================================================================= squid 里的 ACL 访问控制列表 acl denyip src 192.168.1.129/32 --拒绝内网的192.168.1.129/32上网 http_access deny denyip acl denyip src 192.168.1.129-192.168.1.132/255.255.255.255 http_access deny denyip acl baddsturl2 dst 220.11.22.33 --不能访问这个外网IP的网站 http_access deny baddsturl2 acl baddsturl dstdomain -i www.baidu.com --不能访问www.baidu.com和WWW.BAIDU.COM;-i参数定义大小写都匹配; 但是可以访问zhidao.baidu.com或tieba.baidu.com,并且可以使用www.baidu.com的IP也可以访问 http_access deny baddsturl acl baddsturl dstdom_regex -i baidu.com --这是把baidu.com以下的所有域名都禁止 ,但直接使用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 vip arp 00:0C:29:79:0C:1A --rhel5系列里的rpm版不支持,需要编译版squid加上此功能;如果用的是rhel6的rpm版,支持MAC地址功能 http_access allow vip acl badipclient2 src 192.168.1.0/255.255.255.0 acl worktime time MTWHF 9:00-17:00 http_access deny badipclient2 worktime --拒绝192.168.1.0网段工作时间不能上网 acl badipclient3 src 192.168.1.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,上课时间不能上任何网站,休息时间可以上网,但受限 2,上课时间可以上网,但受限,休息时间可以无限制上网 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 mac 00:0C:29:79:0C:1A vim /etc/squid/denywebsite qq.com sina.com mop.com 163.com youku.com 第一种需求 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 第二种 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 ==================================================================== 客户端 | | 反向代理(缓存加速,网站数据切分) | | web服务器 | amoeba | mysql 实验环境 内网web服务器 squid VM2 eth0 vmnet1 eth1 eth0 192.168.1.128 192.168.1.1 172.16.2.35 172.16.2.x --注意: 192.168.1.1为squid的一个内网IP 172.16.2.35为squid的外网IP(也就是说在这个架构里squid在最前端) 172.16.2.x 为外网客户端 第一步: 在内网web服务器上安装httpd,并做一个主页用于测试 yum install httpd* -y echo "内网web" > /var/www/html/index.html /etc/init.d/httpd restart 第二步: 在squid服务器上安装,并进行配置 yum install squid -y 用一个新的配置文件;如果是在上面的透明代理基础上再做反向代理,先注释掉前面所有的配置 vim /etc/squid/squid.conf 62 http_port 80 accel vhost vport --accel 反向代理加速模式 --vhost 支持域名 --vport 支持IP cache_peer 192.168.1.128 parent 80 0 no-query originserver name=web --192.168.1.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.1.128);如果有多台web的话,可以多台web绑定同一个域名,还可以实现RR轮循调度 cache_peer_domain web 172.16.2.35 --光写上面一条,客户端只能通过web.cluster.com访问,再加上这条,客户端就可以使用172.16.2.35来访问 59 http_access allow all cache_dir ufs /var/spool/squid 256 16 256 保存后,先不要重启squid;因为我这是在透明代理的基础上再做的,所以要把前面做的缓存和日志给删除,清除iptables规则 # rm /var/spool/squid/* -rf # rm /var/log/squid/*.log -rf # iptables -t nat -F # squid -zX --重新初始化 重启服务,注意不要与apache的80端口冲突 --测试: 所以这里客户端的DNS解析web.cluster.com应该得到172.16.2.35的结果 所以这里不做DNS的话,就直接在/etc/hosts里写上 172.16.2.35 web.cluster.com 再使用http://web.cluster.com 就可以访问到内部的web服务器了 可以使用curl -I http://web.cluster.com去查有没有命中缓存 ================================================================= 多台squid反向代理 参考 http://www.ibm.com/developerworks/cn/linux/l-cn-squid 客户端 DNS轮叫(round-robin) www.abc.com squid1 squid2 web1 web2 参考它实现 client | | |-----------| squid 1 squid 2 | | |-----------| | | |-----------| lamp1 lamp 2 |-----------| | | mysql + nfs 两台squid1使用icp协议共同工作 两台lamp可以安装一个phpwind或discuz论坛 lamp里mysql独立出来,lamp的网站家目录也独立出来,使用nfs共享(--注意其权限) 把mysql和nfs做在同一台 --在这里我实现下面的架构 client li.cluster.com | squid2.cluster.com 外网 172.16.2.4 | 172.16.2.130 |-----------| squid 1 squid 2 | | |-----------| 内网 1.1.1.1 | 1.1.1.149 | |-----------| web1 web 2 |-----------| web内网 1.1.1.128 1.1.1.131 第一步: 主机名绑定 时间同步 防火墙关闭 yum配置 第二步: squid1 上的配置 yum install squid* -y # vim /etc/squid/squid.conf --下面只列出需要修改的参数 http_port 80 accel vhost vport icp_port 3130 icp_access allow all --在rhel6.5下的squid3.1版加上这一句 cache_peer 1.1.1.149 sibling 80 3130 cache_peer 1.1.1.128 parent 80 0 no-query originserver round-robin name=web1 cache_peer 1.1.1.131 parent 80 0 no-query originserver round-robin name=web2 cache_peer_domain web1 web2 web.cluster.com http_access allow all 保存配置文件后 squid -zX --初始化缓存目录 /etc/init.d/squid start --启动 第三步 squid2上的配置 yum install squid -y # vim /etc/squid/squid.conf 修改配置文件,和squid1的配置几乎一样,把squid1的配置文件拷过来,再修改两个参数 cache_peer 1.1.1.1 sibling 80 3130 --IP改为squid1的内网IP 保存配置文件后 squid -zX --初始化缓存目录 /etc/init.d/squid start --启动 第四步: 配置两个内网web服务器 yum install httpd* -y --因为我这里没有做共享存储,所以这里估计分别做两个不同的主页,来测试 在web1 128上 echo 128 > /var/www/html/index.html 在web1 129上 echo 129 > /var/www/html/index.html /etc/init.d/httpd start --再把两个web启起来 第五步: 我现在使用172.16.2.108做外网的一个客户端来验证 --因为我的架构是做了DNS的轮叫,也就是网站域名为web.cluster.com,但轮叫两个IP172.16.2.4和172.16.2.130 vim /etc/hosts --为了方便,我这里没有做DNS,使用hosts文件来模拟DNS轮叫 172.16.2.4 web.cluster.com 172.16.2.130 web.cluster.com [root@108 ~]# elinks web.cluster.com --得到的结果怎么样都是128的主页 [root@108 ~]# curl -I http://web.cluster.com HTTP/1.0 200 OK Date: Tue, 10 Apr 2012 09:01:42 GMT Server: Apache/2.2.3 (Red Hat) Last-Modified: Tue, 10 Apr 2012 09:01:35 GMT ETag: "1546ce-c-5ea859c0" Accept-Ranges: bytes Content-Length: 12 Content-Type: text/html; charset=UTF-8 Age: 1 X-Cache: HIT from li.cluster.com X-Cache-Lookup: HIT from li.cluster.com:80 --HIT表示命中缓存 Via: 1.0 li.cluster.com:80 (squid/2.6.STABLE21) Connection: close --结果多次删除两台squid的/var/spool/squid/*缓存信息,多台客户端的测试,有时是128的主页,有时是129的主页,说明是正常的轮叫成功 --或者清空两个缓存,重启,只启动一个httpd,那客户端就只能访问这个启动的httpd --但实际应用时,128和129应该是经过同步或共享存储的同一网站,内容是一致的 --上面的架构,坏掉任意一台内网web或squid,不影响网站的运行 测试:当缓存查不到,是否可以去找sibling的另一台squid 1,在两台web建立一个同名文件(内容不同) 2, 客户端去访问squid1的那个文件,得到内容缓存起来 3,关闭两台web ,然后客户端去访问squid2的那个文件,会得到同样的内容,说明是当缓存查不到,是先去查sibling的另一台