一、缓存代理概述
1、代理的工作原理。
图1
我们从图1来解释一下squid的工作原理
首先客户机访问www.163.com的时候,首先到squid的缓存中进行查找如果有直接将结果应答给客户机,如果没有缓存则squid服务器想目www.163.com发送请求,将返回的结果存入自己的缓存并且应答给客户端。
squid可以代理的应用层协议有http、ftp。其中应用最广泛的是http。
HTTP代理的缓存对象主要是文字,图像等静态web元素,使用缓存机制后,当客户机在不同的时候
访问统一web元素,或者不同的客户机的访问相同的web元素时,可以直接从缓存服务器中获取结果,这
样就提高了用户向internet访问的速度。
使用squid代理服务器有以下几点好处:
1)加快了访问速度
2)隐藏了客户端的IP地址
3)可以对源地址尽心过滤
4)可以控制访问
2、代理的基本类型
根据实现的方式不同,代理服务可以分为传统代理和透明代理,这两种代理服务完成的工作相差不多,而还有一种代理也就是我们今天的重点反向代理
传统代理:在客户端使用的时候需要在web游览器中进行设置,来指定服务器的端口和地址,这种代理主要是针对局域网访问internet的时候用的比较广泛,但由于客户端需要进行设置,所以这种并不是最常用的。
透明代理:提供与传统代理相同的服务,但不需要用户进行设置,而是通过默认路由和防火墙的
重定向功能,在整个过程中用户不知道其中的过程,所以称之为透明代理。使用透明代理时网页浏
览器访问网站时的域名解析请求优先发给DNS服务进行解析。透明代理必须在linux操作系统的防火墙
上进行操作。操作上不是很灵活。
说完了两种正向代理,我们来看一反向代理的工作原理:
图2
客户端请求访问 WEB 服务时,DNS 将访问的域名解析为 Squid 反向代理服务器的 IP 地址,这样客户端的 URL 请求将被发送到反向代理服务器。如果 Squid 反向代理服务器中缓存了该请求的资源,则将该请求的资源直接返回给客户端,否则反向代理服务器将向后台的 WEB 服务器请求资源,然后将请求的应答返回给客户端,同时也将该应答缓存在本地,供下一个请求者使用。
Squid 反向代理一般只缓存可缓冲的数据(比如 html 网页和图片等),而一些 CGI 脚本程
序或者 ASP、JSP 之类的动态程序默认不缓存。它根据从 WEB 服务器返回的 HTTP 头标记来缓冲静
态页面。有四个最重要 HTTP 头标记:
Last-Modified: 告诉反向代理页面什么时间被修改
Expires: 告诉反向代理页面什么时间应该从缓冲区中删除
Cache-Control: 告诉反向代理页面是否应该被缓冲
Pragma: 用来包含实现特定的指令,最常用的是Pragma:no-cache
原理就说到这里。
二、安装squid及运行控制。
本例以squid3.4.6源码包进行演示,系统本本为centos6.5内核2.6.26 。
基本环境:gcc编译器,开发工具。
主机名:entos1.lzg.com
IP地址:192.168.1.1
ps:本次安装是以单台服务器作为安装,之后的代理验收的时候会有专门的拓扑图。
[root@centos1 tools]# ls squid-3.4.6/ -ld
rwxr-xr-x. 18 1000 1000 4096 Jun 25 2014 squid-3.4.6/
[root@centos1 tools]# cd squid-3.4.6
[root@centos1 squid-3.4.6]# ./configure --prefix=/usr/local/squid --syconfdir=/etc --enable-linux-netfilter --enable-linux-tproxy --enable-async-io=100 --enable-err-language="Simplify_Chinese" --enable-underscore --enable-poll --enable-gnuregex --enable-arp-acl
上述含义如下:
--prefix 指定安装的位置
--sysconfdir=/etc 指定配置文件的存放位置
--enable-linux-netfilter 使用内核进行过滤
--enable-linux-tproxy 支持透明模式
--enable-arp-acl 可以直接在规则中通过客户端MAC地址进行管理
--enable-async-io=100 提升存储性能 值一般都为100
--enable-err-language="Simplify_Chinese" 错误信息显示为中文
--enable-underscore 允许url路径存在下划线
--enable-poll 使用poll()模式,提升性能
--enable-gnuregex 使用正则表达式
[root@centos1 tools]# make && make install
[root@centos1 squid-3.4.6]# echo $?
使用变量$?来判断是否安装正确。返回0代表正确执行,squid我们就安装完成了,这是我们只需要做一下简单的配置即可。
因为squid默认不存在运行用户,我们先创建一个运行用户名为squid
[root@centos1 squid-3.4.6]# useradd -M -s /sbin/nologin squid
由于程序用户不需要宿主目录以及不需要登录操作系统,所以添加-M -s选项
现在我们来将他的执行程序链接到/usr/local/sbin目录下,方便命令的执行或者直接修改PATH环境变量。
这里我选择修改PATH环境变量
[root@centos1 squid-3.4.6]# echo "PATH=$PATH:/usr/local/squid/sbin/" >> /etc/profile
[root@centos1 squid-3.4.6]# . /etc/profile
之后我们将squid安装目录下的var子目录的属组和属主改变
[root@centos1 squid-3.4.6]# chown -R squid:squid /usr/local/squid/var
可以使用whilere看一下squid的主配置文件路径
[root@centos1 squid-3.4.6]# whereis squid
squid: /etc/squid.conf /usr/local/squid
我们来看一下squid的默认的配置文件内容
[root@centos1 squid-3.4.6]# vim /etc/squid.conf
#
# Recommended minimum configuration:
#
# Example rule allowing access from your local networks.
# Adapt to list your (internal) IP networks from where browsing
# should be allowed
#下面的部分为程序定义的acl规则
acl localnet src 10.0.0.0/8 # RFC1918 possible internal network
acl localnet src 172.16.0.0/12 # RFC1918 possible internal network
acl localnet src 192.168.0.0/16 # RFC1918 possible internal network
acl SSL_ports port 443
acl Safe_ports port 80 # http
acl Safe_ports port 21 # ftp
acl Safe_ports port 443 # https
acl Safe_ports port 70 # gopher
acl Safe_ports port 210 # wais
acl Safe_ports port 1025-65535 # unregistered ports
acl Safe_ports port 280 # http-mgmt
acl Safe_ports port 488 # gss-http
acl CONNECT method CONNECT
#
# Recommended minimum Access Permission configuration:
#
# Deny requests to certain unsafe ports
http_access deny !Safe_ports
# Deny CONNECT to other than secure SSL ports
# Only allow cachemgr access from localhost
http_access allow localhost manager
http_access deny manager
# web applications running on the proxy server who think the only
# one who can access services on "localhost" is a local user
#http_access deny to_localhost
#
# INSERT YOUR OWN RULE(S) HERE TO ALLOW ACCESS FROM YOUR CLIENTS
#
# Example rule allowing access from your local networks.
# from where browsing should be allowed
#以http开头的为调用上面定义的acl规则
http_access allow localnet
http_access allow localhost
# And finally deny all other access to this proxy
http_access deny all
# Squid normally listens to port 3128
http_port 3128
# Uncomment and adjust the following to add a disk cache directory.
#cache_dir ufs /usr/local/squid/var/cache/squid 100 16 256
# Leave coredumps in the first cache dir
coredump_dir /usr/local/squid/var/cache/squid
#
# Add any of your own refresh_pattern entries above these.
#
refresh_pattern ^ftp: 1440 20% 10080
refresh_pattern ^gopher: 1440 0% 1440
refresh_pattern -i (/cgi-bin/|\?) 0 0% 0
refresh_pattern . 0 20% 4320
以上的配置项主要定义程序运行时需要的一些组件,和监听地址、端口号。其中实现代理主要就是通过这个配置文件来实现的,和我们今天后面需要讲解的acl也是需要应用在这个配置文件中,所以一定要及时进行备份,更多的配置项请参/etc/squid.conf.documented
我们先进性配置文件的修改,主要修改有以下几条配置项,有的配置项需要修改,而有的配置项需要添加。
http_port 3128 squid的默认监听端口tcp 修改
cache_effective_group squid squid的运行组 添加
cache_effective_user squidsquid的运行用户 添加
visible_hostname centos1.lzg.com 当前系统的主机名 添加
cache_dir ufs /usr/local/squid/var/cache/squid 100 16 256
上条配置项为缓存的目录位置其中
100代表缓存的大小
16表示最多可以有多少个一级子目录
256表示最多可以有多多少个二级子目录。
以上就是需要修改的配置文件内容。
我们保存之后使用语法检测工具对语法进行检查。
[root@centos1 squid-3.4.6]# squid -k parse
会输出很多信息,只要细看一下有没有出现错误就可以了。
语法没有任何错误,
我么首先对缓存目录进行初始化。
[root@centos1 squid-3.4.6]# squid -z
[root@centos1 squid-3.4.6]# echo $?
正确执行了,之后我们启动squid
[root@centos1 squid-3.4.6]# squid
[root@centos1 squid-3.4.6]# netstat -anpt | grep "squid"
tcp 0 0 :::3128 :::* LISTEN 37749/(squid-1)
可以看见我们的squid服务已经启动了,并且也看见监听的端口,地址以及进程号。为了更好的控制squid的服务,我们可以编写一个脚本来控制squid的服务。
[root@centos1 squid-3.4.6]# vim /tools/squid
#!/bin/bash
# chkconfig: 2345 90 25
# config: /etc/squid.conf
# pidfile: /usr/local/squid/var/run/squid.pid
# Description: Squid - internet object cache.
PID="/usr/local/squid/var/run/squid.pid"
CONF="/etc/squid.conf"
CMD="/usr/local/squid/sbin/squid"
case "$1" in
start)
netstat -anpt | grep squid &> /dev/null
if [ $? -eq 0 ]
then
echo "squid is running"
else
echo "正在启动squid..."
$CMD
fi
;;
stop)
$CMD -k kill &> /dev/null
rm -fr $PID &> /dev/null
;;
status)
[ -f $PID ] &> /dev/null
if [ $? -eq 0 ]
then
netstat -anpt | grep squid
else
echo "squid is not running."
fi
;;
restart)
$0 stop &> /dev/null
echo "正在关闭squid..."
$0 start &> /dev/null
echo "正在启动squid..."
;;
reload)
$CMD -k reconfigure
;;
check)
$CMD -k parse
;;
*)
echo "用法:$0 {start | stop | restart | reload | check | status}"
;;
esac
以上脚本使用了我们之前的cass语句。
之后将squid脚本添加为系统服务,并设置每次开机自动运行
[root@centos1 squid-3.4.6]# cp /tools/squid /etc/init.d/
[root@centos1 squid-3.4.6]# chmod +x /etc/init.d/squid
[root@centos1 squid-3.4.6]# chkconfig --add squid
[root@centos1 squid-3.4.6]# chkconfig squid on
[root@centos1 squid-3.4.6]# service squid start
squid is running
[root@centos1 squid-3.4.6]# service squid restart
正在关闭squid...
正在启动squid...
这个服务与之前的系统服务没有什么区别,只是简化了一些。基本的配置就完成了,下面我们开始构建代理服务器
三、构建代理服务器
1、传统代理:
我们通过一个案例案进行解读
现在局域网内部需要通过域名www.qwe.com访问web服务器,由于并发访问量过多,公司现在要求加快访问internet的速度,决定采用传统代理的方式。
公司要求禁止通过代理下载超过100MB的文件
实验步骤:
1)在外网的DNS添加一个A记录记录的IP地址执行squid服务器的地址
2)修改squid。conf配置文件实现公司的需求。
由于是测试环境,这里只需要三台计算机就可以了。并且与internet的IP地址采用了同一个网段,这里linux网关服务区兼squid代理服务器需要开启路由转发并且需要设置iptables的snat共享上网。
实验拓扑就按图3搭建。
开始实验
web/dns
建一个a记录ip地址指向web服务器地址。
安装iis7.0不需要做任何配置。
squid/linux网关服务器
DNS指向dns服务器
开启路由转发
[root@centos1 ~]# echo "1" > /proc/sys/net/ipv4/ip_forward
建立防火墙规则
[root@centos1 ~]# iptables -t nat -F
[root@centos1 ~]# iptables -t nat -I POSTROUTING -o eth0 -s 192.168.1.0/24 -j SNAT --to 172.16.16.1
[root@centos1 logs]# iptables -I INPUT -p udp --dport 53 -j ACCEPT
[root@centos1 ~]# service iptables save
iptables: Saving firewall rules to /etc/sysconfig/iptables:[ OK ]
将防火墙规则保存
squid/linux网关服务器
vim /etc/squid.conf
reply_body_max_size 10 MB 限制最大缓存大小
http_access allow localnet 允许所有地址使用squid缓存 需要在http_access_之前添加,具体为什么,我们之后在讲解。
acl domain dstdomain .qwe.com 定义可以缓存的目标域,匹配域内所有站点 如果需要访问多个网站则使用空格为分隔符写入就好了
http_access allow domain 应用acl规则
dns_children 40 MB 定义dns缓存的大小
[root@centos1 ~]# service squid restart
重新加载配置文件
局域网pc
在web游览器中找到工具——internet选项——点击链接选项卡——局域网(LAN)设置
按照下图所写输入
图5
现在可以通过www.qwe.com上网了
到此为止传统代理就做完了。
总结一下:我们主要就是在dns服务器上建立一个a记录,在squid服务器上允许了所有的地址使用squid,并且可以缓存qwe.com目标域的所有地址,并且在网关上开启路由转发,并且可以共享上网,允许53端口入站。配置客户端指向squid缓存代理
ps:如果不用域名的时候不用这么麻烦,网关什么都不需要操作,也不需要开启路由转发,只需要修改配置文件即可
通过上面的配置我们可以看出局域网有少量的PC时还可以应用,但是一旦数量过多的时候就不好设置了,这时我们可以通过透明代理,前面说过了,透明代理,不需要在客户端进行任何操作。
拓扑图还是一样
默认的squid.conf配置文件并不支持透明代理,这里我们只需在配置文件中修改一下就可以了。
前面说过了透明代理必须设置在网关上,否则是不能进行配置的,这是为什么呢?我们可以想象一下客户端访问网站的过程,首先客户端访问的目标端口为80或443端口去访问网站,网站收到之后响应请求之后建立连接,这是整个过程,但是中间加了一个缓存代理之后,就不一样了,因为有了代理客户端访问的目标地址其实是squid代理服务器,这时目标端口依然是80或443,squid代理服务器不可能响应客户端的请求,因为squid代理服务并不监听80或443端口。所以这里需要将80或443端口重定向为3128端口这是squid服务器就可以响应客户端的请求了,根据数据包的头部进行判断,如果缓存中存在则直接应答,如果不存在则访问之后应答。
2、配置透明代理
我们开始进行透明代理的案例:
squid/网关服务器
[root@centos1 ~]# vim /etc/squid.conf
http_port 192.168.1.1: 3128 transparent
这个地址就是连接局域网接口的IP地址,后面的是开启透明模式的选项。
之后在防火墙上添加两条规则
[root@centos1 logs]# iptables -t nat -nL
[root@centos1 logs]# iptables -t nat -I PREROUTING -s 192.168.1.0 -i eth1 -p tcp --dport 80 -j REDIRECT --to 3128
[root@centos1 logs]# iptables -t nat -I PREROUTING -s 192.168.1.0 -i eth1 -p tcp --dport 443 -j REDIRECT --to 3128
上诉两条规则就是将来自以192.168.1.0的http或https请求交给了3128端口进行处理
[root@centos1 logs]# service iptables save
iptables: Saving firewall rules to /etc/sysconfig/iptables:[ OK ]
将防火墙的规则进行保存。
现在我们将客户端上指定的缓存服务器地址去掉
去掉勾之后在使用域名访问
如果访问不成功的时候,建议将之前的操作全部删除,并且将iptables规则表全部清除重新启动计算机在重新配置防火墙,在将之前删除的配置项恢复回来,在访问就可以了。
3.反向代理:
我们之后在演示如何构建反向代理,因为反向代理还需要重新编译安装,所以我们先来看一下今天的第三个给内容acl
四、ACL访问控制
squid提供了强大的代理控制机制,通过合理的设置acl并进行限制,可以针对源地址,目标地址,目标url路径等条件进行过滤,
在配置文件中ACL需要通过两个步骤来实现:其一,使用acl配置项定义需要过滤的条件,之后使用http_access 的方式应用允许或者拒绝。
1、定义访问控制列表
每一行acl配置可以定义一条访问控制列表,格式如下。
acl 列表名称 列表类型 列表内容
其中列表名称有管理员自行定义,用来识别控制条件“列表类型必须使用squid预定义的值对应不同类别的控制条件;列表内容是要具体控制的对象列表内容可以有多个,使用空格间隔。”
我们来看一下具体的列表类型分别对应了那些列表内容
列表类型
列表内容
用途、含义
Src
192.168.1.100
源IP地址、网段、IP范围
192.168.1.0/24
192.168.1.0-192.168.3.0/24
dst
216.163.137.3
目标IP地址、网段、主机名
67.135.167.0/24
www.lzg.com
Port
80 443 8080 21 20
目标端口
Dstdomain
.qq.com .sina.com
目标域、匹配域内所有站点
Time
MTWHFAS
12:30-13:00
M-Monday、T-Tuesday、W-Wednesday 、H-Thursday
F-Friday、A-Saurday、S-Sunday
maxconn
20
每个客户的并发连接数
url_regex
url_regex -i ^rtsp://
目标资源的RUL路径 -i不区分大小写
urlpath_regex
Urlpath_regex -i /.mp3 /.png /.mp4
目标资源的整个URL路径 -i表示忽略大小写
下面我来写几个规则并解释,但是不验证结果。
[root@centos1 ~]# vim /etc/squid.conf
acl localhost src 127.0.0.1/255.255.255.255 //源地址为127.0.0.1
acl MYLANsrc 192.168.1.0/24 192.168.4.0./24
acl to_localhost dst 127.0.0.0/8 //目标地址为127.0.0.0/8网段
acl MC20 maxconn 20 //最大并发连接数20
acl BlackURL url_regex -i ^rtsp:// ^emule //以rtsp开头的 ^开头
acl MEDIAFILE urlpath_regex -i \.mp3$ /.mp4$ //以mp3、MP4、为结尾$结尾
acl WORKTIME time MTWHF 08:30-17:30 //时间为周一至周五8:30-17:30
上面规则定义好了,下面使用http_access 来确定允许还是拒绝。
http_access deny BlackURL //拒绝以rtsp开头的url路径
http_access deny MEDIAFILE //拒绝以.mp3 .mp4结尾的完整url路径
http_access deny MC20 //并发量超过20时江北拒绝
http_access allow MYLAN WORKTIME //允许1.0 4.0网段在工作时间上网
http_access dney all/默认禁止所有客户机使用代理
执行访问控制室时,squid将按照各规则顺序依次检查,如果找到一条规则匹配就停止(有点类似以路由器的acl)因此规则的顺序安排是非常重要的有两点需要注意
没有设置任何规则时squid服务器将拒绝所有客户端的请求
有规则但没有找到匹配的规则:squid则与最后一条规则相反的权限,即最后一条为允许,那么就拒绝反之就是允许
策略上最好将常用的规则放到前面,这样可以减轻squid的负担,在访问控制的整体策略上建议采用先拒绝后允许的方式,先拒绝小范围,在允许大范围。。以上所讲就是acl的内容我们做一个实验来看一下acl的具体应用
1、需求:1.局域网的主机在上班时间可以使用代理服务。2.WEB站点的图片(gif)拒绝访问
2、验证:图片被拒绝浏览
[root@centos1 ~]# vim /etc/squid.conf
acl image urlpath_regex -i \.png$
acl WORKTIME time MTWHF 08:30-17:50
acl LAN_IP src 192.168.1.0/24
http_access deny image
http_access LAN_IP WORKTIME
已经不能访问到图片了,但是还是可以访问网站的只是以.png为结尾的图片不能访问了以.jpg格式的图片还是可以访问的