一、缓存代理概述

1、代理的工作原理。

wKioL1g66QiysJuoAACnW7rtJcc055.png

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操作系统的防火墙上进行操作。操作上不是很灵活。

    说完了两种正向代理,我们来看一反向代理的工作原理:

wKiom1g66RmQc54fAADgu93vRWY271.png

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

    使用变量$?来判断是否安装正确。返回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  $?

0

    正确执行了,之后我们启动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、传统代理:

我们通过一个案例案进行解读

wKioL1g66S2A29zrAAEavhwClYE869.png

3


    现在局域网内部需要通过域名www.qwe.com访问web服务器,由于并发访问量过多,公司现在要求加快访问internet的速度,决定采用传统代理的方式。

    公司要求禁止通过代理下载超过100MB的文件

    实验步骤:

        1)在外网的DNS添加一个A记录记录的IP地址执行squid服务器的地址

        2)修改squid。conf配置文件实现公司的需求。

    由于是测试环境,这里只需要三台计算机就可以了。并且与internet的IP地址采用了同一个网段,这里linux网关服务区兼squid代理服务器需要开启路由转发并且需要设置iptables的snat共享上网。

    实验拓扑就按图3搭建。

开始实验

web/dns

wKiom1g66UKwkdFCAAAV6cOUqfk807.png


4


    建一个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)设置

    按照下图所写输入

wKioL1g66VHBG_JQAAA2VDnMkG0161.png

5

    现在可以通过www.qwe.com上网了

wKiom1g66WaiCQphAAOQ6XcGsCo629.png

6

    到此为止传统代理就做完了。

    总结一下:我们主要就是在dns服务器上建立一个a记录,在squid服务器上允许了所有的地址使用squid,并且可以缓存qwe.com目标域的所有地址,并且在网关上开启路由转发,并且可以共享上网,允许53端口入站。配置客户端指向squid缓存代理

    ps:如果不用域名的时候不用这么麻烦,网关什么都不需要操作,也不需要开启路由转发,只需要修改配置文件即可

    通过上面的配置我们可以看出局域网有少量的PC时还可以应用,但是一旦数量过多的时候就不好设置了,这时我们可以通过透明代理,前面说过了,透明代理,不需要在客户端进行任何操作。

    拓扑图还是一样

wKioL1g66XShpqWoAADYlVSicyE204.png

7

    默认的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  ]

    将防火墙的规则进行保存。

    现在我们将客户端上指定的缓存服务器地址去掉

wKiom1g66YaiYS3sAAAxlh2c3Jw320.png

8

    去掉勾之后在使用域名访问

wKioL1g66ZnhDI1TAAOPsDNDSD4273.png

9

    如果访问不成功的时候,建议将之前的操作全部删除,并且将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

wKiom1g66anz_o-0AAAMQw2soe4649.png

10

    已经不能访问到图片了,但是还是可以访问网站的只是以.png为结尾的图片不能访问了以.jpg格式的图片还是可以访问的