web缓存技术之squid

一、web缓存

什么是 web 缓存

Web 缓存是指一个 Web 资源(如 html 页面,图片,js,数据等)存在于 Web 服务器和客户端(浏览器)之间的副本。缓存会根据进来的请求保存输出内容的副本;当下一个请求来到的时候,如果是相同的 URL,缓存会根据缓存机制决定是直接使用副本响应访问请求,还是向源服务器再次发送请求。比较常见的就是浏览器会缓存访问过网站的网页,当再次访问这个 URL 地址的时候,如果网页没有更新,就不会再次下载网页,而是直接使用本地缓存的网页。只有当网站明确标识资源已经更新,浏览器才会再次下载网页。

1.2 web 缓存的作用

1. 减少源站网络带宽消耗
2. 降低服务器压力
3. 减少服务器压力 10,1
4. 减少网络延迟,加快页面打开速度

1.3 web 缓存的类型

1.3.1 数据库缓存

Web 应用,特别是 SNS 类型的应用,往往关系比较复杂,数据库表繁多,如果频繁进行数据库查询,很容易导致数据库不堪重荷。为了提供查询的性能,会将查询后的数据放到内存中进行缓存,下次查询时,直接从内存缓存直接返回,提供响应效率。比如常用的缓存方案有 memcached redis 等。

1.3.2 CDN 缓存

CDN 缓存,也叫网关缓存、反向代理缓存。CDN 缓存一般是由网站管理员自己部署,为了让他们的网站更容易扩展并获得更好的性能。浏览器先向 CDN 网关发起 web 请求,网关服务器后面对应着一台或多台负载均衡源服务器,会根据它们的负载请求,动态将请求转发到合适的源服务器上。虽然这种架构负载均衡源服务器之间的缓存没法共享,但却拥有更好的处扩展性。

1.3.3 代理服务器缓存

代理服务器缓存是浏览器和源服务器之间的中间服务器,浏览器先向这个中间服务器发起 web 请求,经过处理后(比如权限验证,缓存匹配等),再将请求转发到源服务器。代理服务器缓存的运作原理跟浏览器的运作原理差不多,只是规模更大。

1.3.4 浏览器缓存

每个浏览器都实现了 HTTP 缓存,我们通过浏览器使用 HTTP 协议与服务器交互的时候,浏览器就会根据一套与服务器约定的规则进行缓存工作

浏览器缓存分为强缓存和协商缓存:

1、强缓存:浏览器在加载资源时,先根据这个资源的一些http header判断它是否命中强缓存。强缓存如果命中,浏览器直接从子集的缓存中读取资源,不会发送请求到服务器。比如某个css文件,如果浏览器在加载它所在的网页时,这个css文件的缓存配置命中了强缓存,浏览器就直接从缓存中加载这个css,请求是不会发送到网页所在的服务器。

2、协商缓存:当强缓存没有命中时,浏览器一定会发送一个请求到服务器,通过服务器端依据资源的另外一些http header验证这个资源是否命中协商缓存,如果命中协商缓存,服务器就会将这个请求返回(304),但是不会返回这个资源的数据,而是告诉客户端可以直接从缓存中加载这个资源,于是浏览器就会又从自己的缓存中去加载这个资源;如未命中请求,则将资源返回客户端,并更新本地缓存数据(200);

强缓存和协商缓存的区别:强缓存不发请求到服务器,协商缓存会发请求到服务器。

强制缓存:

image-20221125212358067

协商缓存

image-20221125212434387

浏览器缓存存放到那里?

这里我们以博客的请求为例,状态码为灰色的请求则代表使用了强制缓存,请求对应的Size值则代表该缓存存放的位置,分别为from memory cache 和 from disk cache。

那么from memory cache 和 from disk cache又分别代表的是什么呢?什么时候会使用from disk cache,什么时候会使用from memory cache呢?

from memory cache代表使用内存中的缓存,from disk cache则代表使用的是硬盘中的缓存,浏览器读取缓存的顺序为memory –> disk –> 服务器请求。

内存缓存(from memory cache):内存缓存具有两个特点,分别是速度快和时间限制。硬盘缓存(from disk cache):硬盘缓存则是直接将缓存写入硬盘文件中,读取缓存需要对该缓存存放的硬盘文件进行I/O操作,然后重新解析该缓存内容,读取复杂,速度比内存缓存慢

在浏览器中,浏览器会在js和图片等文件解析执行后直接存入内存缓存中,那么当刷新页面时只需直接从内存缓存中读取(from memory cache),而css文件则会存入硬盘文件中,所以每次渲染页面都需要从硬盘读取缓存(from disk cache)。

总结:

强制缓存优先于协商缓存进行,若强制缓存(Expires和Cache-Control)生效则直接使用缓存,若不生效则进行协商缓存(Last-Modified / If-Modified-Since和Etag / If-None-Match),协商缓存由服务器决定是否使用缓存,若协商缓存失效,那么代表该请求的缓存失效,重新获取请求结果,再存入浏览器缓存中;生效则返回304,继续使用缓存

img

1.3.5 应用层缓存

应用层缓存是指我们在代码层面上做的缓存。通过代码逻辑,把曾经请求过的数据或资源等,缓存起来,再次需要数据时通过逻辑上的处理选择可用的缓存的数据。

今天我们主要讨论和前端密切想着的浏览器 HTTP 缓存机制。浏览器 HTTP 缓存可以分为强缓存和协商缓存。强缓存和协商缓存最大区别是:强缓存命中的话不会发请求到服务器(比如 chrome 中的 200 from memory cache),协商缓存一定会发请求到服务器,通过资源的请求首部字段难资源是否命中协商缓存,如果协商缓存命中,服务器会将这个请求返回,但是不会返回这个资源的实体,而是通知客户端可以从缓存中加载这个资源(304 not modifend)。流程图如下:

在这里插入图片描述

1.4 缓存命中率:公式hit/(hit+miss)

(0,1)

 页面命中率:基于页面数量进行衡量
 字节命中率:基于页面的体积进行衡量
 查询命中率:基于数据查询数量进行衡量
 
 缓存与否:
 私有数据:private,private cache;
 公共数据:public, public or private cache;

1.5 缓存的特点

提高cache缓存命中
增强热区局部性;
改善提高时效性:
在缓存空间耗尽时使用LRU(最近最少使用算法);
过期:缓存清理

1.6 缓存有效性判断机制和对应首部

1.6.1、Expires过期时间控制法
  • Expires是HTTP 1.0所提供的控制字段,是web服务器响应报文的字段,用于告诉客户端浏览器在Expires所指定的过期时间到来前,浏览器可直接从浏览器本地缓存中读取缓存响应请求,无需再次发送请求到服务器。

    image-20221125211519031

    如图上述图中,Data表示请求报文发送的时间,而Expires则表示缓存在此日期到来前都是有效的。因此客户再次访问这类资源时,浏览器会直接从本地缓存中响应。

1.6.2、Cache-control

Cache-control是HTTP/1.1协议所提供的缓存控制标识,Cache-Control和Expires的作用差不多,都是用于指明当前资源的缓存有效期。通知客户端浏览器是从本地缓存中直接读取数据还是说重新发送请求到服务器中获取数据。Cache-control提供了多种资源有效期的选择,其优先级高于Expires。下面我们来一起看下Cache-control可使用的值。

image-20221125211604503

public:用于指示客户端请求的资源科被任何缓存区所缓存。

private:用于指示对于当前某个用户的全部或部分响应信息,不能被共享缓存区所缓存处理

image-20221125211354097

no-cache:指示说明当前带请求或响应的消息不能被缓存。
no-store:用于防止重要的信息被无意的发布,在请求消息中附带此Cache-control值将使得请求和响应消息都不能使用缓存。
max-age:在响应报文中max-age通常用于告知客户端当前请求资源的缓存有效期的最大值(以秒为单位);而在请求报文中通常使用max-age=0,表示客户端向服务器发送请求确认,确认当前请求的资源是否有修改,如果没有则直接使用本地缓存,否则从服务器中获取请求资源。
min-fresh:要求缓存服务器返回至少还未过指定时间的缓存资源。
max-stale:该指令表示客户机可以接收超出超时期间的响应消息。如果指定max-stale消息的值,那么客户机可以接收超出超时期指定值之内的响应消息。
1.6.3、Last-Modified/If-Modified-Since

Last-Modified/If-Modified-Since需要配置Cache-control一起使用。

 Last-Modified:web服务器在响应请求时,会使用此字段来告诉浏览器,其请求的资源的最后修改时间。
 If-Modified-Since:当资源过期时或者请求中带有Cache-Control:max-age=0,并且发现该资源的缓存具有Last-Modified声明,则向web服务器发送请求时带上If-Modified-Since。web服务器收到请求后,将比较If-Modified-Since与被请求资源的最后修改时间。如果最后修改时间比If-Modified-Since的值更新,说明资源已经被改动过,服务器会响应此请求的资源,响应状态码为200;否则,说明资源没更新,则响应HTTP 304,告知浏览器可继续使用本地缓存。
 
  缺点:last-modified标注的最后修改时间精确到秒,如果资源在1秒内多次修改,它不能标注文件的准确修改时间;如果某些文件被定期生成,内容没有发生任何变化,但是last-modified却修改了,导致文件不能使用缓存;也可能存在服务器时间没有准确获取文件修改时间,或者与代理服务器时间不一致等情形,导致不能使用缓存。

image-20221125211819111

1.6.4、Etag/If-None-Match

Etag:web服务器响应请求时,告诉浏览器当前资源在服务器的唯一标识(生成规则由服务器决定)。Apache中,ETag的值,默认是对文件的索引节(INode),大小(Size)和最后修改时间(MTime)进行Hash后得到的。 Etag 可以解决 Last-Modified 无法解决的一些问题。

1、一些文件也许会周期性的更改,但是他的内容并不改变(仅仅改变的修改时间),这个时候我们并不希望客户端认为这个文件被修改了,而重新发起GET请求
2、某些文件修改非常频繁,比如在秒以下的时间内进行修改,(比方说1s内修改了N次),If-Modified-Since能检查到的粒度是s级的,这种修改无法判断(或者说UNIX记录MTIME只能精确到秒)
3、某些服务器不能精确的得到文件的最后修改时间

image-20221125212747115

二、squid的基本概述

2.1、什么是squid nginx varnish

Squid(Squid cache,简称Squid)是Linux系统中最常用的一款开源代理服务软件,可以很好地实现HTTP和FTP,以及DNS查询、SSL等应用的缓存代理,功能十分强大。

squid的官方网站为http://www.squid-cache.org

Squid是一个支持HTTP,HTTPS,FTP等服务的Web缓存代理软件,它可以通过缓存页面来提高服务器的相应速度并降低带宽占用。并且,Squid还具有强大的访问控制功能。Squid可以运行在各种操作系统平台上。

Squid会将访问页面的结果缓存在硬盘和内存上。所以Squid对硬盘和内存的空间大小具有较高的要求。内存和硬盘越大,缓存的命中率就越高。但是真实服务器数据是实时更新的,因此,我们就需要不定期的清空缓存数据以保证用户访问结果的准确性。

Squid 将数据元缓存在内存和硬盘中,同时也缓存 DNS 查询的结果。Squid 支持 SSL,支持访问控制。由于使用了 ICP(轻量 Internet 缓存协议),Squid 能够实现层叠的代理阵列,从而最大限度的节约带宽。 Squid Cache(简称 Squid)是一个流行的代理服务器和 Web 缓存服务器软件。Squid 可以做正向代理,也可以做反向代理。

image-20211209160554693

2.2、什么是squid代理服务器?

squid是一种用来缓存Internet数据的软件。接受来自客户机需要下载的目标的请求并适当的处理这些请求。也就是说,如果一个客户端想要打开默认网站,它请求squid为它取得这个页面。squid随之连接到远程服务器并向这个页面发出请求。然后,squid显式地聚集数据到客户端机器,而且同时复制一份。当下一次有人需要同一页面时,squid可以简单的从磁盘中读到它,那样数据会立即传输到客户机上。

2.3、squid代理的作用

1)通过缓存方式为用户提供Web加速访问

我们都知道CDN(内容分发网络)是用来给网站加速用的,通过在现有的Internet中增加一层新的网络架构,将网站的内容发布到最接近用户的网络的“边缘”,使用户可以就近取得所需的内容,以提高用户访问网站的响应速度,目前国外的CDN技术已经是如火如荼,而国内也已经是异军突起,像网宿、帝联、cdn联盟、蓝汛等等纷纷加入到CDN的行列.那么到底CDN是通过什么技术来实现的呢?

其实说白了目前国内众多CDN厂商都是使用软件技术—Squid也就是代理服务器的方式实现,其本身成本比较低、配置方便灵活.其内容服务模式是基于缓存服务器,也叫做代理缓存.主要的技术是网络负载均衡(多个squid代理服务器)、动态内容分发复制和缓存技术,简单的说当一个用户访问已经加入CDN服务(squid代理)的网站时,用户的请求并不直接发送到后端web服务器,而是发送到squid服务器(CDN中称节点),squid再根据本地的DNS记录向后端的目标web服务器发送请求,请求有响应并返回数据时squid会先将数据缓存一份到本地服务器上,然后返回结果给用户,当下一位客户访问相同的内容时直接从squid上返回结果而不经过后端web服务器,从而节约网站带宽,加速客户访问速度

image-20211209150401107

2)对用户的Web访问请求进行过滤控制

网站在访问的过程中,请求的数据类型比较多有Js,css,php,html,png等其他的类型,这些类型的数据有静态的也有动态的数据,静态的数据由于其数据类型比较简单,因此请求的速度比较快,但是动态的数据类型,由于其数据需要和数据库等进行交互,因此不宜成为被缓存的对象,所有我们在数据缓存的过程中,要有选择性的选择的缓存的对象。而不是将所有的缓存一起缓存起来。

2.4 什么时候使用squid?

1、节省带宽,节省企业运行成本
2、提升用户体验
3、源站压力过大

2.5 haproxy和squid的代理区别

haproxy是专业的反向代理服务器

squid具有反向代理和缓存的功能,一般主要使用缓存功能

image-20221125215629840

三、squid的代理的类型

3.1、标准的代理服务器(传统代理)

  一个标准的代理缓冲服务被用于缓存静态的网页(例如:html文件和图片文件等)到本地网络上的一台主机上(即代理服务器)。当被缓存的页面被第二次访问的时候,浏览器将直接从本地代理服务器那里获取请求数据而不再向原web站点请求数据。这样就节省了宝贵的网络带宽,而且提高了访问速度。但是,要想实现这种方式,必须在每一个内部主机的浏览器上明确指明代理服务器的IP地址和端口号。客户端上网时,每次都把请求送给代理服务器处理,代理服务器根据请求确定是否连接到远程web服务器获取数据。如果在本地缓冲区有目标文件,则直接将文件传给用户即可。如果没有的话则先取回文件,先在本地保存一份缓冲,然后将文件发给客户端浏览器。

image-20211209154333896

3.2、透明代理服务器

  透明代理缓冲服务和标准代理服务器的功能完全相同。但是,代理操作对客户端的浏览器是透明的(即不需指明代理服务器的IP和端口)。透明代理服务器阻断网络通信,并且过滤出访问外部的HTTP(80端口)流量。如果客户端的请求在本地有缓冲则将缓冲的数据直接发给用户,如果在本地没有缓冲则向远程web服务器发出请求,其余操作和标准的代理服务器完全相同。对于Linux操作系统来说,透明代理使用Iptables或者Ipchains实现。因为不需要对浏览器作任何设置,所以,透明代理对于ISP(Internet服务器提供商)特别有用。

image-20211209154413210

3.3、反向代理服务器

  反向代理是和前两种代理完全不同的一种代理服务。使用它可以降低原始WEB服务器的负载。反向代理服务器承担了对原始WEB服务器的静态页面的请求,防止原始服务器过载。它位于本地WEB服务器和Internet之间,处理所有对WEB服务器的请求,组织了WEB服务器和Internet的直接通信。如果互联网用户请求的页面在代理服务器上有缓冲的话,代理服务器直接将缓冲内容发送给用户。如果没有缓冲则先向WEB服务器发出请求,取回数据,本地缓存后再发送给用户。这种方式通过降低了向WEB服务器的请求数从而降低了WEB服务器的负载。

image-20211209154433109

注意区分:代理服务器一定是缓存服务器,缓存服务器则不一定是代理服务器。

四、squid的配置文件详解

4.1 安装squid:源码编译安装

[root@squid ~]# yum -y install gcc gcc-c++    ##安装c++
[root@squid ~]# tar zxvf squid-3.5.28.tar.gz -C /usr/local/
[root@squid squid-3.5.28]# ./configure --prefix=/usr/local/squid --enable-epoll --enable-htcp --enable-stacktraces --enable-storeio=ufs,aufs,diskd --enable-removal-policies=lru,heap --enable-icmp --enable-default-err-language=Simplify_Chinese --enable-err-languages="Simplify_Chinese English" --enable-cache-digests --enable-auth --enable-auth-basic="NCSA" --enable-useragent-log --enable-referer-log --enable-linux-netfilter --enable-delay-pools --enable-follow-x-forwarded-for --enable-kill-parent-hack --enable-gnuregex --enable-underscore --enable-arp-acl --enable-x-accelerator-vary --with-filedescriptors=65535

[root@squid squid-3.5.28]# make -j 8
[root@squid squid-3.5.28]# make -j 8 install

参数说明

./configure --prefix=/usr/local/squid \
--enable-epoll  指定使用epoll()函数,提升性能
--enable-htcp HTCP 是超文本缓存协议--类似于ICP的内部缓存协议
--enable-stacktraces 系统支持在程序崩溃时,自动产生数据追踪,数据追踪信息被写到cache.log文件
--enable-storeio=ufs,aufs,diskd Squid支持大量的不同存储模块,可以在这里指定
--enable-removal-policies=lru,heap  Squid缓存替换策略
--enable-icmp 加入icmp支持
--enable-default-err-language=Simplify_Chinese \
--enable-err-languages="Simplify_Chinese English" \
--enable-cache-digests 使能缓存摘要,加快检索缓存的速度
--enable-auth  启用模块身份认证
--enable-auth-basic="NCSA"  持NCSA身份验证
--enable-useragent-log 激活来自客户请求的HTTP用户代理头的日志
--enable-referer-log  激活来自客户请求的HTTP referer日志
--enable-linux-netfilter 可以支持透明代理
--enable-delay-pools  支持限制带宽配置
--enable-follow-x-forwarded-for 当一个请求被另一些代理服务器转发时通过从http头中寻找X-Forwarded-For来发现直接或间接的客户端的IP地址
--enable-kill-parent-hack 掉suqid的时候,要不要连同父进程一起关掉
--enable-gnuregex  支持GNU正则表达式。
--enable-underscore 允许解析的URL中出现下划线
--enable-arp-acl         可在规则中设置通过MAC地址进行管理,防止IP欺骗
--enable-x-accelerator-vary  该功能squid被配置成加速器时使用,在响应请求时,从后台原始服务中读取X-Accelerator-Vary头信息。
--disable-ident-lookups 防止系统使用RFC931规定的身份识别方法
--disable-ssl  禁用squid的SSL/TLS 安全连接
--disable-wccp 用于阻止或分发HTTP请求到一个或多个caches
--disable-internal-dns 禁用内部DNS查询
--disable-mempools   关闭内存池,以防止squid运行时间长了会变慢
--with-default-user=squid 默认用户,应首先创建
--with-pthreads  支持POSIX线程
--with-aio         支持POSIX AIO
--with-large-files 支持大文件,如日志文件等
--with-filedescriptors=65535 文件描述符个数,必须是64的整数倍

4.2 squid的配置文件

安装完成后,默认会生成如下的文件和目录

[root@squid squid]# tree -L 2 /usr/local/squid/
/usr/local/squid/
├── bin
│   ├── purge         ##强制删除缓存对象
│   └── squidclient  ##squid的简单http客户端,可以对缓存管理
├── etc  
│   ├── cachemgr.conf   ##缓存管理配置
│   ├── cachemgr.conf.default
│   ├── errorpage.css
│   ├── errorpage.css.default
│   ├── mime.conf
│   ├── mime.conf.default
│   ├── squid.conf      ##主配置文件
│   ├── squid.conf.default
│   └── squid.conf.documented   ##配置指导文件
├── libexec
│   ├── basic_ncsa_auth
│   ├── cachemgr.cgi    ##squid管理的cgi接口,可以通过web界面来管理squid
│   ├── digest_file_auth
│   ├── diskd
│   ├── ext_delayer_acl
│   ├── ext_file_userip_acl
│   ├── ext_sql_session_acl
│   ├── ext_unix_group_acl
│   ├── ext_wbinfo_group_acl
│   ├── helper-mux.pl
│   ├── log_db_daemon
│   ├── log_file_daemon
│   ├── negotiate_wrapper_auth
│   ├── ntlm_fake_auth
│   ├── ntlm_smb_lm_auth
│   ├── pinger
│   ├── storeid_file_rewrite
│   ├── unlinkd
│   ├── url_fake_rewrite
│   └── url_fake_rewrite.sh
├── sbin
│   └── squid   ##服务启动程序
├── share
│   ├── errors
│   ├── icons
│   ├── man
│   └── mib.txt
└── var
    ├── cache     #缓存目录
    ├── logs    ##日志文件
    └── run      ##运行时pid存放文件

12 directories, 33 files

4.3 配置文件启动管理

/usr/local/squid/sbin/squid -z 初始化缓存空间
/usr/local/squid/sbin/squid 启动
/usr/local/squid/sbin/squid -k shutdown 停止
/usr/local/squid/sbin/squid -k reconfigure 重新载入配置文件
/usr/local/squid/sbin/squid -k rotate 轮循日志
/usr/local/squid/sbin/squid -k parse 检查语法
[root@squid sbin]# ./squid -z
提示有失败:
[root@squid sbin]# ./squid -z
WARNING: Cannot write log file: /usr/local/squid/var/logs/cache.log
/usr/local/squid/var/logs/cache.log: Permission denied
         messages will be sent to 'stderr'.
[root@squid sbin]# WARNING: Cannot write log file: /usr/local/squid/var/logs/cache.log
/usr/local/squid/var/logs/cache.log: Permission denied
         messages will be sent to 'stderr'.
2024/01/02 21:13:03 kid1| Set Current Directory to /usr/local/squid/var/cache/squid
2024/01/02 21:13:03 kid1| Creating missing swap directories
2024/01/02 21:13:03 kid1| No cache_dir stores are configured.

如下操作,新建用户和目录
[root@squid sbin]# useradd -s /sbin/nologin -M squid
[root@squid sbin]# mkdir -p /usr/local/squid/var/logs
[root@squid sbin]# chown squid.squid /usr/local/squid/var/logs/ -R
[root@squid sbin]# chmod 777 /usr/local/squid/var/logs -R
[root@squid sbin]# mkdir -p /usr/local/squid/var/cache/squid
[root@squid sbin]# chown squid.squid /usr/local/squid/var/cache/squid
[root@squid sbin]#chmod 777 /usr/local/squid/var/cache/squid -R


当你看到如下的输出,说明配置是正确的
[root@squid sbin]# ./squid -z
[root@squid sbin]# 2021/12/09 22:57:38 kid1| Set Current Directory to /usr/local/squid/var/cache/squid
2021/12/09 22:57:38 kid1| Creating missing swap directories
2021/12/09 22:57:38 kid1| /var/spool/squid exists
2021/12/09 22:57:38 kid1| Making directories in /var/spool/squid/00
2021/12/09 22:57:38 kid1| Making directories in /var/spool/squid/01
2021/12/09 22:57:38 kid1| Making directories in /var/spool/squid/02
2021/12/09 22:57:38 kid1| Making directories in /var/spool/squid/03
2021/12/09 22:57:38 kid1| Making directories in /var/spool/squid/04
2021/12/09 22:57:38 kid1| Making directories in /var/spool/squid/05
2021/12/09 22:57:38 kid1| Making directories in /var/spool/squid/06
2021/12/09 22:57:38 kid1| Making directories in /var/spool/squid/07
2021/12/09 22:57:38 kid1| Making directories in /var/spool/squid/08
2021/12/09 22:57:38 kid1| Making directories in /var/spool/squid/09
2021/12/09 22:57:38 kid1| Making directories in /var/spool/squid/0A
2021/12/09 22:57:38 kid1| Making directories in /var/spool/squid/0B
2021/12/09 22:57:38 kid1| Making directories in /var/spool/squid/0C
2021/12/09 22:57:38 kid1| Making directories in /var/spool/squid/0D
2021/12/09 22:57:38 kid1| Making directories in /var/spool/squid/0E
2021/12/09 22:57:38 kid1| Making directories in /var/spool/squid/0F

4.4 管理脚本

#!/bin/bash
#chkconfig: 2345 90 25
PID="/usr/local/squid/var/run/squid.pid"
CONF="/usr/local/squid/etc/squid.conf"
CMD="/usr/local/squid/sbin/squid"

case "$1" in
start)
netstat -natp | grep squid &> /dev/null
if [ $? -eq 0 ]
then
echo "squid is running"
else
echo "正在启动 squid..."
$CMD
fi
;;
stop)
$CMD -k kill &> /dev/null
rm -rf $PID &> /dev/null
;;
status)
[ -f $PID ] &> /dev/null
if [ $? -eq 0 ]
then
netstat -natp | 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|status|reload|check|restart}"
;;
esac
[root@squid etc]# chmod +x /etc/init.d/squid
[root@squid etc]# chkconfig --add squid
[root@squid etc]# chkconfig --level 35 squid on
[root@squid etc]# service squid start

4.5 有效配置文件

##有效配置行
[root@squid etc]# egrep -v '^#|^$' squid.conf
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 localnet src fc00::/7       # RFC 4193 local private network range
acl localnet src fe80::/10      # RFC 4291 link-local (directly plugged) machines
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 Safe_ports port 591		# filemaker
acl Safe_ports port 777		# multiling http
acl CONNECT method CONNECT
http_access deny !Safe_ports
http_access deny CONNECT !SSL_ports
http_access allow localhost manager
http_access deny manager
http_access allow localnet
http_access allow localhost
http_access deny all
http_port 3128
coredump_dir /usr/local/squid/var/cache/squid
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

4.6 其他设置

4.6.1 设置squid 用户和组
cache_effective_user squid
cache_effective_group squid

如果不设置用户和组,默认是nobody用户

4.6.2 设置日志目录
access_log /usr/local/squid/var/logs/access.log squid
4.6.3 设置缓存存储日志
cache_store_log  /usr/local/squid/var/logs/store.log
4.6.4设置cache目录
cache_dir ufs /usr/local/squid/var/cache/squid 100 16 256

4.7 修改后的最终配置文件

更多配置,请参考结尾附录1:

[root@squid etc]# grep -Ev '^#|^$' squid.conf
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 localnet src fc00::/7       # RFC 4193 local private network range
acl localnet src fe80::/10      # RFC 4291 link-local (directly plugged) machines
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 Safe_ports port 591		# filemaker
acl Safe_ports port 777		# multiling http
acl CONNECT method CONNECT
http_access deny !Safe_ports
http_access deny CONNECT !SSL_ports
http_access allow localhost manager
http_access deny manager
http_access allow localnet
http_access allow localhost
http_access deny all
http_port 3128
coredump_dir /usr/local/squid/var/cache/squid
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
cache_effective_user squid
cache_effective_group squid
visible_hostname wuchaofeng.com
access_log /usr/local/squid/var/logs/access.log squid
cache_store_log  /usr/local/squid/var/logs/store.log
cache_dir ufs /usr/local/squid/var/cache/squid 100 16 256
cache_mgr wuchaofeng@qq.com

五、实战配置

5.1 实战1:传统代理

5.1.1、网络拓扑图

image-20221126174018779

5.1.2、我们先配置squid

在添加一个新的网卡,用于和web端进行通信

[root@squid 00]# ifconfig
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.1.106  netmask 255.255.255.0  broadcast 192.168.1.255
        inet6 fe80::c9d5:a9f6:4b24:ba  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:32:a6:41  txqueuelen 1000  (Ethernet)
        RX packets 27854  bytes 18926948 (18.0 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 25359  bytes 30169039 (28.7 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

ens37: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 100.100.1.100  netmask 255.255.255.0  broadcast 100.100.1.255
        inet6 fe80::20c:29ff:fe32:a64b  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:32:a6:4b  txqueuelen 1000  (Ethernet)
        RX packets 11  bytes 1226 (1.1 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 26  bytes 2552 (2.4 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
5.1.3、将我们已有的配置文件备份,然后进行修改
[root@squid etc]# cat /usr/local/squid/etc/squid.conf.bak |grep -v "^#" |grep -v "^$" >squid.conf
5.1.4、在新生成的文件下添加新的配置
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 localnet src fc00::/7       # RFC 4193 local private network range
acl localnet src fe80::/10      # RFC 4291 link-local (directly plugged) machines
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 Safe_ports port 591         # filemaker
acl Safe_ports port 777         # multiling http
acl CONNECT method CONNECT
http_access allow localhost manager
http_access allow localnet
http_access allow localhost
http_access deny all
http_port 3128
coredump_dir /usr/local/squid/var/cache/squid
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
添加新的配置如下:
cache_mem 64 MB       #设置缓存内存的大小
maximum_object_size 4 MB   #允许保存到缓存空间的最大对象大小,超过大小限制的文件将不被缓存,而是直接转发给客户端  
cache_dir ufs /var/spool/squid 100 16 256  #设置cache目录的文件系统类型和目录层级
access_log /var/log/squid/access.log  #设置访问日志
visible_hostname squid         #设置可见的主机名
cache_mgr wuchaofeng@163.com   #设置缓存管理者
5.1.5、squid初始化,先关闭squid服务
[root@squid sbin]# ./squid -z
提示有失败:
如下操作,新建用户和目录
[root@squid sbin]# useradd -s /sbin/nologin -M squid
[root@squid etc]# mkdir -p /usr/local/squid/var/logs   #创建日志目录
[root@squid etc]# chown squid.squid /usr/local/squid/var/logs/ -R
[root@squid sbin]# mkdir /var/spool/squid -p
[root@squid sbin]# chown squid.squid /var/spool/squid/ -R
[root@squid sbin]# mkdir /var/log/squid/ -p
[root@squid sbin]# chown squid.squid /var/log/squid/ -R


当你看到如下的输出,说明配置是正确的
[root@squid sbin]# ./squid -z
[root@squid sbin]# 2021/12/09 22:57:38 kid1| Set Current Directory to /usr/local/squid/var/cache/squid
2021/12/09 22:57:38 kid1| Creating missing swap directories
2021/12/09 22:57:38 kid1| /var/spool/squid exists
2021/12/09 22:57:38 kid1| Making directories in /var/spool/squid/00
2021/12/09 22:57:38 kid1| Making directories in /var/spool/squid/01
2021/12/09 22:57:38 kid1| Making directories in /var/spool/squid/02
2021/12/09 22:57:38 kid1| Making directories in /var/spool/squid/03
2021/12/09 22:57:38 kid1| Making directories in /var/spool/squid/04
2021/12/09 22:57:38 kid1| Making directories in /var/spool/squid/05
2021/12/09 22:57:38 kid1| Making directories in /var/spool/squid/06
2021/12/09 22:57:38 kid1| Making directories in /var/spool/squid/07
2021/12/09 22:57:38 kid1| Making directories in /var/spool/squid/08
2021/12/09 22:57:38 kid1| Making directories in /var/spool/squid/09
2021/12/09 22:57:38 kid1| Making directories in /var/spool/squid/0A
2021/12/09 22:57:38 kid1| Making directories in /var/spool/squid/0B
2021/12/09 22:57:38 kid1| Making directories in /var/spool/squid/0C
2021/12/09 22:57:38 kid1| Making directories in /var/spool/squid/0D
2021/12/09 22:57:38 kid1| Making directories in /var/spool/squid/0E
2021/12/09 22:57:38 kid1| Making directories in /var/spool/squid/0F
5.1.6、查看文件
[root@squid sbin]# cd  /var/spool/squid
[root@squid squid]# ls
00  01  02  03  04  05  06  07  08  09  0A  0B  0C  0D  0E  0F
[root@squid squid]# 
5.1.7、启动服务
[root@squid sbin]# ./squid 
[root@squid sbin]# netstat -antup |grep squid
tcp6       0      0 :::3128                 :::*                    LISTEN      3595/(squid-1)    
udp        0      0 0.0.0.0:36211           0.0.0.0:*                           3595/(squid-1)    
udp6       0      0 :::50044                :::*                                3595/(squid-1)    
udp6       0      0 ::1:50262               ::1:55155               ESTABLISHED 3595/(squid-1)    
5.1.8、web端配置

1)IP地址配置

image-20211209205829293

2)安装http

[root@localhost ~]# yum  -y install httpd

3)生成网站内容

[root@localhost ~]# echo "正向代理" >/var/www/html/index.html

4)启动服务

[root@localhost ~]# systemctl start httpd
[root@localhost ~]# systemctl enable httpd
5.1.9、浏览器验证

image-20221126205906616

image-20211209212437536

5.2 实战2:透明代理

image-20221126223703249

5.2.1、配置squid

之前的配置项可以继续保留,我们只需要修改一下squid的配置文件

将:http_port 3128

改:http_port 3128 transparent --透明模式

image-20211209212713564

5.2.2、开启路由转发功能
[root@squid etc]# echo "net.ipv4.ip_forward=1" >/etc/sysctl.conf 
[root@squid etc]# sysctl -p
net.ipv4.ip_forward = 1
5.2.3、添加防火墙规则
[root@squid etc]#iptables  -F
[root@squid etc]#iptables -t nat -F
[root@squid etc]# iptables -t nat -I PREROUTING -i ens33 -s 192.168.1.0/24 -p tcp --dport 80 -j REDIRECT --to-port 3128
[root@squid etc]# iptables-save >/root/iptables.txt
5.2.4、将squid的服务重启
[root@squid etc]# service squid restart

image-20221126224448309

5.2.5、配置客户端

将客户端网卡的网关指向squid服务器的相邻口的IP

image-20221126224105233

5.2.6、配置web端
[root@web ~]#yum -y install nginx
[root@web ~]#echo "transparent" >>/usr/share/nginx/html/index.html
[root@web ~]#systemctl enable --now nginx
5.2.7、客户端测试

image-20221126224221868

5.2.8、将后端服务器停止,查看是否还能正常访问

image-20221126224934581

image-20221126225030176

可以看到,依旧可以访问,但是是访问的缓存服务器中的数据。

5.3 使用squid进行限制下载

5.3.1 编辑squid.conf配置文件,在最后加入如下策略
reply_body_max_size 10 Mb  #超过10Mb的文件不允许通过squid下载
5.3.2 在web服务器上生成2个文件,分别是5Mb和20Mb,测试下载
dd if=/dev/zero of=./test1.txt bs=1M count=5

dd if=/dev/zero of=./test.txt bs=1M count=20
5.3.3 重启squid服务
systemctl restart squid
5.3.4 测试

image-20220411204830478

image-20220411204900945

从上实验可以看到超过10M的文件是无法下载的!

5.4 实战3:反向代理

5.4.1 实验拓扑

image-20220411231049974

5.4.2 配置步骤

1、将2两台web服务器的网关指向squid的IP地址

RS1:

image-20211209231718928

image-20220411224123197

RS2:

image-20211209231747449

image-20220411224211060

2、web服务器测试访问

image-20211209232015329

image-20211209232033264

3、squid配置

在/etc/squid/squid.conf添加如下内容:

http_port 192.168.31.100:80  accel vhost vport
cache_peer 10.10.10.12 parent 80 0  no-query  originserver round-robin weight=1 name=web01
cache_peer 10.10.10.13 parent 80 0  no-query  originserver round-robin weight=1 name=web02

#说明
http_port 80 accel vhost vport #squid从一个缓存变成了一个Web服务器反向代理加速模式,这个时候squid在80端口监听请求,同时和web server的请求端口(vhost vport)绑定,这个时候请求到了squid,squid是不用转发请求的,而是直接要么从缓存中拿数据要么向绑定的端口直接请求数据。
accel :反向代理加速模式
vhost :支持域名或主机名来表示代理节点
vport :支持IP和端口来表示代理节点

parent :代表为父节点,上下关系,非平级关系
80 :代理内部web服务器的80端口
0 :没有使用icp(电信运营商),表示就一台squid服务器
no-query :不做查询操作,直接获取数据
originserver :指定是源服务器
round-robin :指定 squid 通过轮询方式将请求分发到其中一台父节点
max_conn :指定最大连接数
weight : 指定权重
name :设置别名

4.squid服务器开启路由转发

[root@localhost ~]# sysctl -p
net.ipv4.ip_forward = 1
[root@localhost ~]# 

5、浏览器测试

image-20220411231206443

image-20220411231231114

6、关闭后端2个web服务器

image-20220411231434148

image-20220411231456108

7、再次访问:

image-20220411231527251

发现还是可以访问的,而且是访问到的10.10.10.13,是因为最后一次缓存的是10.10.10.13,文件特征码还是保存的是当前这个服务器,所以再次访问出现的内容是10.10.10.13。

六、squid缓存管理

6.1、查看缓存

想要查看缓存,需要先配置squid.conf,加入如下的参数

# should be allowed
acl manager proto cache_object
acl localhost src 192.168.1.106/32     ##此处为访问缓存的IP
6.1.1 查看缓存信息
[root@squid bin]# ./squidclient -h 192.168.1.106 -p 80  mgr:objects ##查看缓存对象
HTTP/1.1 200 OK
Server: squid/3.5.28
Mime-Version: 1.0
Date: Sun, 27 Nov 2022 17:00:32 GMT
Content-Type: text/plain;charset=utf-8
Expires: Sun, 27 Nov 2022 17:00:32 GMT
Last-Modified: Sun, 27 Nov 2022 17:00:32 GMT
X-Cache: MISS from wuchaofeng.com
X-Cache-Lookup: MISS from wuchaofeng.com:80
Via: 1.1 wuchaofeng.com (squid/3.5.28)
Connection: close

KEY 5C215321A35405C40F0801E08E6604D7
	STORE_OK      IN_MEMORY     SWAPOUT_NONE PING_NONE
	SPECIAL,VALIDATED
	LV:1669568375 LU:1669568375 LM:1667202479 EX:-1
	0 locks, 0 clients, 0 refs
	Swap Dir -1, File 0XFFFFFFFF
	GET http://wuchaofeng.com/squid-internal-static/icons/silk/page_white_picture.png
	inmem_lo: 0
	inmem_hi: 869
	swapout: 0 bytes queued
	object_sz: 869

KEY 0D42AF60A919A34580B337E2989BC45D
	STORE_OK      IN_MEMORY     SWAPOUT_NONE PING_NONE
	SPECIAL,VALIDATED
	LV:1669568375 LU:1669568375 LM:1667202479 EX:-1
	0 locks, 0 clients, 0 refs
	Swap Dir -1, File 0XFFFFFFFF
	GET http://wuchaofeng.com/squid-internal-static/icons/silk/page_white_acrobat.png
	inmem_lo: 0
	inmem_hi: 810
	swapout: 0 bytes queued
	object_sz: 810

KEY 3B2285AF6FA734E39786998DEAC4B742
	STORE_OK      IN_MEMORY     SWAPOUT_NONE PING_NONE
	SPECIAL,VALIDATED
	LV:1669568375 LU:1669568375 LM:1667202479 EX:-1
	0 locks, 0 clients, 0 refs
	Swap Dir -1, File 0XFFFFFFFF
	GET http://wuchaofeng.com/squid-internal-static/icons/silk/page_white_cplusplus.png
	inmem_lo: 0
	inmem_hi: 840
	swapout: 0 bytes queued
	object_sz: 840

[root@squid bin]# ./squidclient -h 192.168.1.106 -p 80  mgr:info   ##查看缓存信息
HTTP/1.1 200 OK
Server: squid/3.5.28
Mime-Version: 1.0
Date: Sun, 27 Nov 2022 17:10:09 GMT
Content-Type: text/plain;charset=utf-8
Expires: Sun, 27 Nov 2022 17:10:09 GMT
Last-Modified: Sun, 27 Nov 2022 17:10:09 GMT
X-Cache: MISS from wuchaofeng.com
X-Cache-Lookup: MISS from wuchaofeng.com:80
Via: 1.1 wuchaofeng.com (squid/3.5.28)
Connection: close

Squid Object Cache: Version 3.5.28
Build Info:
Service Name: squid
Start Time:	Sun, 27 Nov 2022 16:59:35 GMT
Current Time:	Sun, 27 Nov 2022 17:10:09 GMT
Connection information for squid:
	Number of clients accessing cache:	3
	Number of HTTP requests received:	46
	Number of ICP messages received:	0
	Number of ICP messages sent:	0
	Number of queued ICP replies:	0
	Number of HTCP messages received:	0
	Number of HTCP messages sent:	0
	Request failure ratio:	 0.00
	Average HTTP requests per minute since start:	4.4
	Average ICP messages per minute since start:	0.0
	Select loop called: 1221 times, 519.330 ms avg
Cache information for squid:
	Hits as % of all requests:	5min: 23.5%, 60min: 8.7%
	Hits as % of bytes sent:	5min: 50.0%, 60min: 60.8%
	Memory hits as % of hit requests:	5min: 0.0%, 60min: 0.0%
	Disk hits as % of hit requests:	5min: 0.0%, 60min: 0.0%
	Storage Swap size:	68 KB
	Storage Swap capacity:	 0.1% used, 99.9% free
	Storage Mem size:	288 KB
	Storage Mem capacity:	 0.1% used, 99.9% free
	Mean Object Size:	22.67 KB
	Requests given to unlinkd:	15
Median Service Times (seconds)  5 min    60 min:
	HTTP Requests (All):   0.00000  0.00000
	Cache Misses:          0.00000  0.00000
	Cache Hits:            0.00000  0.00000
	Near Hits:             0.00000  0.00000
	Not-Modified Replies:  0.00000  0.00000
	DNS Lookups:           0.02231  0.02336
	ICP Queries:           0.00000  0.00000
Resource usage for squid:
	UP Time:	634.102 seconds
	CPU Time:	0.121 seconds
	CPU Usage:	0.02%
	CPU Usage, 5 minute avg:	0.02%
	CPU Usage, 60 minute avg:	0.02%
	Maximum Resident Size: 40256 KB
	Page faults with physical i/o: 0
Memory accounted for:
	Total accounted:          621 KB
	memPoolAlloc calls:     12732
	memPoolFree calls:      12861
File descriptor usage for squid:
	Maximum number of file descriptors:   1024
	Largest file desc currently in use:     17
	Number of file desc currently in use:   10
	Files queued for open:                   0
	Available number of file descriptors: 1014
	Reserved number of file descriptors:   100
	Store Disk files open:                   0
Internal Data Structures:
	    56 StoreEntries
	    56 StoreEntries with MemObjects
	    55 Hot Object Cache Items
	     3 on-disk objects

[root@squid bin]# ./squidclient -h 192.168.1.106 -p 80  mgr:mem   ##查看squid内存使用情况
HTTP/1.1 200 OK
Server: squid/3.5.28
Mime-Version: 1.0
Date: Sun, 27 Nov 2022 17:14:10 GMT
Content-Type: text/plain;charset=utf-8
Expires: Sun, 27 Nov 2022 17:14:10 GMT
Last-Modified: Sun, 27 Nov 2022 17:14:10 GMT
X-Cache: MISS from wuchaofeng.com
X-Cache-Lookup: MISS from wuchaofeng.com:80
Via: 1.1 wuchaofeng.com (squid/3.5.28)
Connection: close

Current memory usage:
Pool	 Obj Size	Chunks							Allocated					In Use					Idle	     Allocations Saved			Rate
 	 (bytes)	KB/ch	 obj/ch	(#)	 used	 free	 part	 %Frag	 (#)	 (KB)	 high (KB)	 high (hrs)	 %Tot	(#)	 (KB)	 high (KB)	 high (hrs)%alloc	(#)	 (KB)	 high (KB)	(#)	 %cnt	 %vol	(#)/sec
mem_node            	 4136	 	 	 	 	 	 	 	 78	 316	 316	 0.09	 50.466	 73	 295	 316	 0.09	 93.590	 5	 2185	 97	 0.564	 6.876	 0.000
16KB Strings        	 16384	 	 	 	 	 	 	 	 3	 48	 48	 0.24	 7.689	 1	 16	 48	 0.24	 33.333	 2	 3248	 62	 0.361	 17.411	 0.000
Short Strings       	   40	 	 	 	 	 	 	 	 1066	 42	 42	 0.03	 6.670	 1061	 42	 42	 0.03	 99.531	 5	 13	 8025	 46.692	 5.502	 0.000
16K Buffer          	 16384	 	 	 	 	 	 	 	 2	 32	 32	 0.24	 5.126	 0	 0	 32	 0.24	 0.000	 2	 3232	 45	 0.262	 12.637	 0.000
HttpHeaderEntry     	   56	 	 	 	 	 	 	 	 412	 23	 23	 0.03	 3.609	 408	 23	 23	 0.03	 99.029	 4	 12	 1980	 11.520	 1.900	 0.000
MimeEntry           	  128	 	 	 	 	 	 	 	 177	 23	 23	 0.24	 3.544	 177	 23	 23	 0.24	 100.000	 00	 0	 0	 0.000	 0.000	 0.000
MemObject           	  328	 	 	 	 	 	 	 	 56	 18	 18	 0.12	 2.873	 56	 18	 18	 0.12	 100.000	 0
6.1.2查看图片缓存记录

在后端服务器添加一些图片来资源,然后通过squid访问,将其缓存下来

image-20221128212502740

image-20221128220127582

[root@squid bin]# ./squidclient -h 192.168.1.106 -p 80  mgr:objects|grep 1.png
	GET http://192.168.1.106/1.png     ##存在记录
[root@squid bin]#

6.2 删除缓存

首先在squid 的主配置文件中添加acl 列表,并允许受信任的主机有权限清除缓存   
acl managercache src 192.168.1.106 127.0.0.1
acl Purge method PURGE
http_access allow managercache Purge
http_access deny Purge
6.2.1 删除一条缓存
/usr/local/squid/bin/squidclient -h  192.168.1.106 -p 80 -m PURGE http://192.168.1.106/1.png

删除完成后,由于缓存已经没有了,因此,当客户端再次去curl的时候,就没有缓存,直接就MISS,直接去后端源站获取数据了。

image-20221128221032031

再次curl查看,可以看到已经HIT到了缓存。

image-20221128221125361

七、squid ACL

7.1、先看一个案例

修改squid.conf的配置文件,将如下这行注释:

image-20220411231852699

重启squid服务查看

image-20220411231928691

访问被拒绝了!说明这里的配置是会影响到我们的访问策略,这就是ACL的策略!

ACL配置由两部分组成,之所以我们没有做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 localnet src fc00::/7       # RFC 4193 local private network range
acl localnet src fe80::/10      # RFC 4291 link-local (directly plugged) machines

7.2、ACL用法

ACL访问控制的步骤:

  1、使用acl配置项定义需要控制的条件

  2、通过http_access配置项对已定义的列表做“允许”或“拒绝”访问的控制
  
  注意:需要同步使用,否则默认是拒绝

(1)定义ACL访问列表

定义格式:acl  列表名称  列表类型  列表内容 
支持类型列表:
1)src             源地址
  例子:
  acl localhost src 127.0.0.1
  
2)dst              目标地址  
  例子:
   acl myip dst 192.168.1.100
   http_access deny !myip
   
3)port             目标端口
  例子:acl test port 80
       acl test port 80-88
       acl test port 80 82 84
       http_access allow test
     
4)dstdomain         目标域
  例子:拒绝用户访问目标域名为www.hopu.org的网站
  
acl mydomain dstdomain www.hopu.org
http_access deny mydomain
     


     
5)time     访问时间
  例子:  

  
acl worktime time D 08:30-17:30  或者  acl  WORKTIME  time  MTWHF  08:30-17:30 #周一到周五
acl idletime time SA   #表示周六和周天

http_access deny worktime    #拒绝
http_access allow idletime   #允许

  
6)maxconn          最大并发连接
    例子:
    acl  connlimit maxconn 50
    http_access  deny connlimit
  
7)url_regex         目标URL地址  # 可以定义大的范围比如http://www.baidu.com
   例子: 
   acl music url_regex -i ^http://www
         acl denyavi url_regex -i ^http://.*\.avi$
         http_access  deny denyavi 
8)urlpath_regex     整个目标URL路径  # 可以定位到每个网站的具体目标的url,比如百度音乐的一首歌的url(a.html)
    例子:
    acl PURL urlpath_regex -i \.mp3$ \.mp4$ \.rmvb$  \.txt$          //以mp3、mp4、rmvb结尾的URL路径
    http_access deny PURL                //禁止客户机下载mp3、mp4等文件
     
     
===========================其他例子===================================== 
 
9)防盗链

acl right_referer referer_regex -i ^http://test.com  ^http://.*.test.com  

http_access deny test_domain !right_referer

10)防止别人利用HTTP代理,设置允许访问的IP
   acl myip dst 192.168.1.100
   http_access deny !myip
   
11)控制上网例子:限制下载BT文件下载mp3

#修改squid.conf
acl BT urlpath_regex -i \.torrent$
acl BT urlpath_regex -i \.torrent$\.mp3$
http_access deny BT

12)控制访问sex网站
#修改squid.conf
acl sex url_regex -i ^http://.*sex.*$
http_access deny sex



13)单个IP每秒最多请求(并发)30个:
可以用来防止多线程下载,爬虫等
acl OverConnLimit maxconn 30
http_access deny OverConnLimit

注意规则顺序:
一定要写到http_access deny all或者http_access allow all前,否则不生效.
例:控制源IP网段

vim etc/squid.conf

acl mylan src 192.168.31.0/24

image-20220411232440775

(2)ACL访问控制

 定义好各种访问控制列表以后,需要使用httpd_access配置项来进行控制

格式:

http_access  allow或deny  列表名……

打开配置文件:

vim /etc/squid.conf

  image-20220411232539523

在每一条http_access规则中,可以同时包含多个访问控制列表名,各个列表之间以空格分隔,为“与”的关系,表示必须满足所有访问控制列表对应的条件才会进行限制

  规则匹配原理:没有设置任何规则时,Squid服务将拒绝客户端的请求,有规则但找不到相匹配的项时,Squid将采用与最后一条规则相反的权限,即如果最后一条规则时allow,就拒绝客户端的请求,否则允许该请求,但是我们要尽量避免找不到相匹配的情况。

image-20220411232658581

如果只定义列表规则,则默认是拒绝

7.3、ACL实战演示

1、禁止任何客户机使用此代理服务:定义一条名为all的列表,匹配来自任意源地址的代理访问;然后拒绝此列表,注意ACL列表要写在前面

 vim  /etc/squid.conf
 
 acl  all src 0.0.0.0/0.0.0.0
 http_access  deny  all
 
 重启服务:
 systemctl restart squid

2、允许多个局域网段在工作时间上网

vim /etc/squid.conf

acl all src 0.0.0.0/0.0.0.0  (有些版本要这么写acl all src all)
acl MYLAN src  192.168.1.0/24   192.168.4.0/24
acl  WORKTIME  time  MTWHF  08:30-17:30   (其中MTWHF是周一到周五的英文首字母)
http_access allow  MYLAN  WORKTIME
http_access  deny  all

 重启服务:
systemctl restart squid
注意要先写http_access allow  MYLAN  WORKTIME再写http_access  deny  all,因为先执行前面的,后面的就不执行了

3、通过黑名单限制目标网站

(1)首先创建地址列表文件(直接在配置文件里写也行,但是这种用列表文件的方式适合拒绝或允许的网站域名比较多的情况,而且方便增删管理)

vim /etc/squid/ipblock.list
61.135.167.36
60.28.14.0/24

(2)配置acl

vim /etc/squid.conf
 acl IPBLOCK dst "/etc/squid/ipblock.list"
 http_access  deny  IPBLOCK
systemctl restart squid

7.4、 配置web图形化查看squid缓存

1)在squid服务器上安装http

[root@squid ~]# yum -y install httpd

2)将squid文件拷贝到apache服务器下的cgi-bin目录下,假设安装了apache后未更改根目录设置

[root@squid conf]# cd /var/www/cgi-bin/
[root@squid cgi-bin]# cp /usr/local/squid/libexec/cachemgr.cgi .

3)用apache自带的htpasswd工具生成访问密码文件,htpasswd建立和更新用于基本认证的存储用户名/密码的文本文件

[root@squid etc]# htpasswd -c squid.passwd squidadmin
New password:
Re-type new password:
Adding password for user squidadmin
[root@squid etc]#

[root@squid etc]# chown apache.apache squid.passwd # 将认证口令文件的所属权改为apache

4)修改配置文件httpd.conf,假设apache安装在/etc/httpd,加入下面内容

<Location /cgi-bin/cachemgr.cgi>
AuthType Basic
AuthName "squidadmin"
AuthUserFile  /usr/local/squid/etc/squid.passwd
require valid-user
</Location>

5)重启http,通过浏览器访问

[root@squid conf]# systemctl restart httpd

http://192.168.1.110/cgi-bin/cachemgr.cgi
##输入刚才设置的squidadmin和密码

image-20221127003035108

image-20221127003130472

点击“continue”出现错误.,配置Squid Cache Manager,设定允许访问Cache Manager服务的ip及端口号

[root@squid etc]# vim /usr/local/squid/etc/cachemgr.conf
注释掉这行
#localhost
添加这行
192.168.1.106:3128   ##注意:192.168.1.106是缓存服务器IP,而192.168.1.110是单独设置的查看缓存IP

访问控制安全设定

[root@squid etc]# vim /usr/local/squid/etc/squid.conf

注释掉这两行
#http_access allow localhost manager
#http_access deny manager
添加这两行
acl manager proto cache_object
http_access allow manager

#设置cache登录的账号密码(默认是空)
cachemgr_passwd secret shutdown  

重启squid和http后再次登录

image-20221127005742070

image-20221127005827105

八、squid日志

8.1、查看日志

[root@squid sbin]# cat /usr/local/squid/var/logs/access.log|grep TCP_MEM_HIT
1667210021.412      0 192.168.1.34 TCP_MEM_HIT/200 13079 GET http://wuchaofeng.com/squid-internal-static/icons/SN.png - HIER_NONE/- image/png
1669556267.440      0 192.168.1.12 TCP_MEM_HIT/200 368 GET http://192.168.1.106/ - HIER_NONE/- text/html


如果看到很多的TCP_MEM_HIT ,这表明该文件是从内存缓存读取的,squid已经起作用了!你再用浏览器打开该文件,应该是快如闪电了。。呵呵,大功告成了!还有其他类型的HIT,如 TCP_HIT等等,这些是从磁盘读取的,我觉得加速的意义不大,只不过缓解了apache的压力而已。

相应于HTTP请求,下列标签可能出现在access.log文件的第四个域。

TCP_HIT

Squid发现请求资源的貌似新鲜的拷贝,并将其立即发送到客户端。

TCP_MISS

Squid没有请求资源的cache拷贝。

TCP_REFERSH_HIT

Squid发现请求资源的貌似陈旧的拷贝,并发送确认请求到原始服务器。原始服务器返回304(未修改)响应,指示squid的拷贝仍旧是新鲜的。

TCP_REF_FAIL_HIT

Squid发现请求资源的貌似陈旧的拷贝,并发送确认请求到原始服务器。然而,原始服务器响应失败,或者返回的响应Squid不能理解。在此情形下,squid发送现有cache拷贝(很可能是陈旧的)到客户端。

TCP_REFRESH_MISS

Squid发现请求资源的貌似陈旧的拷贝,并发送确认请求到原始服务器。原始服务器响应新的内容,指示这个cache拷贝确实是陈旧的。

TCP_CLIENT_REFRESH_MISS

Squid发现了请求资源的拷贝,但客户端的请求包含了Cache-Control: no-cache指令。Squid转发客户端的请求到原始服务器,强迫cache确认。

TCP_IMS_HIT

客户端发送确认请求,Squid发现更近来的、貌似新鲜的请求资源的拷贝。Squid发送更新的内容到客户端,而不联系原始服务器。

TCP_SWAPFAIL_MISS

Squid发现请求资源的有效拷贝,但从磁盘装载它失败。这时squid发送请求到原始服务器,就如同这是个cache丢失一样。

TCP_NEGATIVE_HIT

在对原始服务器的请求导致HTTP错误时,Squid也会cache这个响应。在短时间内对这些资源的重复请求,导致了否命中。 negative_ttl指令控制这些错误被cache的时间数量。请注意这些错误只在内存cache,不会写往磁盘。下列HTTP状态码可能导致否定 cache(也遵循于其他约束): 204, 305, 400, 403, 404, 405, 414, 500, 501, 502, 503, 504。

TCP_MEM_HIT

Squid在内存cache里发现请求资源的有效拷贝,并将其立即发送到客户端。注意这点并非精确的呈现了所有从内存服务的响应。例如,某些cache在内存里,但要求确认的响应,会以TCP_REFRESH_HIT, TCP_REFRESH_MISS等形式记录。

TCP_DENIED

因为http_access或http_reply_access规则,客户端的请求被拒绝了。注意被http_access拒绝的请求在第9域的值是NONE/-,然而被http_reply_access拒绝的请求,在相应地方有一个有效值。

TCP_OFFLINE_HIT

当offline_mode激活时,Squid对任何cache响应返回cache命中,而不用考虑它的新鲜程度。

TCP_REDIRECT

重定向程序告诉Squid产生一个HTTP重定向到新的URI(见11.1节)。正常的,Squid不会记录这些重定向。假如要这样做,必须在编译squid前,手工定义LOG_TCP_REDIRECTS预处理指令。

NONE

无分类的结果用于特定错误,例如无效主机名。

相应于ICP查询,下列标签可能出现在access.log文件的第四域。

UDP_HIT

Squid在cache里发现请求资源的貌似新鲜的拷贝。

UDP_MISS

Squid没有在cache里发现请求资源的貌似新鲜的拷贝。假如同一目标通过HTTP请求,就可能是个cache丢失。请对比UDP_MISS_NOFETCH。

UDP_MISS_NOFETCH

跟UDP_MISS类似,不同的是这里也指示了Squid不愿去处理相应的HTTP请求。假如使用了-Y命令行选项,Squid在启动并编译其内存索引时,会返回这个标签而不是UDP_MISS。

UDP_DENIED

因为icp_access规则,ICP查询被拒绝。假如超过95%的到某客户端的ICP响应是UDP_DENIED,并且客户端数据库激活了(见附录A),Squid在1小时内,停止发送任何ICP响应到该客户端。若这点发生,你也可在cache.log里见到一个警告。

UDP_INVALID

Squid接受到无效查询(例如截断的消息、无效协议版本、URI里的空格等)。Squid发送UDP_INVALID响应到客户端。

8.2 自定义日志格式

##我们可以将squid的格式定义成如下的格式:
logformat squid %>a %ui %un %ts "%rm %ru HTTP/%rv" %Hs %<st "%{Referer}>h" "%{User-Agent}>h" %Ss:%Sh
access_log /usr/local/squid/var/logs/access.log squid

##再次查看日志输出
192.168.1.10 - - 1669559954 "GET http://192.168.1.106/ HTTP/1.1" 304 337 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36" TCP_INM_HIT:HIER_NONE


Field name syntax keys:
{} modifier or argument. Also used to specify header names
> request (client) 客户请求
< reply (server) 服务端回应
a address 访问用户ip地址
A address name 访问用户电脑名称
h all headers 浏览器头信息
i ident 
p port 端口
r request line (no query)
t time 访问时间
u user
l local address/port (where request was accepted)
%>a
Client source IP address
%>A
Client FQDN
%>p
Client source port
%<a
Server or peer IP address
%<p
Server or peer port number
%<A
Server IP address or peer name
%la
Local IP address where the request was accepted
%lp
Local port where the request was accepted
%lA
Local port name where the request was accepted
%ts
Date of request, seconds since epoch
%{format}tl
Date of request, strftime format (localtime)
%{format}tg
Date of request, strftime format (gmt)
%tu
Date of request, sub-second component
%tr
Time to serve the request, in milliseconds
%{header}>h
Request header
%{header:element}>h
Named request header field element (list headers)
%{header:separator element}>h
Named request header field element, using "separator" as field separator (it can be any non-alphanumeric single character)
%>h
All request header
%{header}<h
Request headers, as for <..h above
%un
Authenticated user name or dash
%ur
Authenticated user realm or dash
%us
Authenticated user scheme or dash
%ui
Ident user name or dash
%Hs
HTTP status code (200, 404, 407, etc)
%Ht
HTTP status text (Not found, etc)
%Ss
Squid status code (TCP_HIT, TCP_MISS etc)
%Se
Squid error code (ERR_DENIED, ERR_...)
%Sh
Squid hierarchy code (FIRST_UP_PARENT, etc)
%mt
MIME type of the request
%rm
Request method
%ru
Request URL, without the query string
%rq
Request query string, including ?
%rp
Request protocol (i.e. HTTP/1.1)
%ps
Peer selection status (DIRECT, PARENT, CD_PARENT_HIT, etc. including the TIMEDOUT_ variant)
%>sl
Size of request line
%>sh
Size of request headers, including request line
%>sH
Size of request headers, excluding request line
%>sb
Size of request body, raw received bytes
%>sB
Size of request body, excluding transfer encoding
%>st
Total size of request
%<sl
Size of reply status line
%<sh
Size of reply headers, including status line
%<sH
Size of reply headers, excluding status line
%<sb
Size of reply body, raw transmitted bytes
%<sB
Size of reply body, excluding transfer encoding
%<st
Total size of reply
%%
A literal %

附录1:

# 官网推荐配置,允许访问的IP和端口的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 localnet src fc00::/7       # RFC 4193 local private network range
acl localnet src fe80::/10      # RFC 4291 link-local (directly plugged) machines

#定义了Safe_ports所代表的端口
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 Safe_ports port 591         # filemaker
acl Safe_ports port 777         # multiling http
#定义CONNECT代表http里的CONNECT请求方法
acl CONNECT method CONNECT
acl PURGE method PURGE

http_access deny !Safe_ports
http_access deny CONNECT !SSL_ports
http_access allow localhost manager
http_access allow PURGE localhost
http_access allow PURGE localnet
http_access deny PURGE all
http_access deny manager
http_access allow localnet
http_access allow localhost
#错误页面缓存设置
acl badurl http_status 403-404 500-
http_access deny badurl
#自定义允许访问域名的ACL,协议,端口
acl denyHost dstdomain app.wuchaofeng.com
acl accessHostA dstdomain .wuchaofeng.com
acl accessHostB dstdomain .test.com
acl accessProtocol proto HTTP
acl accessPort port 80

#设定对ACL的访问策略
http_access allow accessProtocol accessPort accessHostA
http_access allow accessProtocol accessPort accessHostB
http_access deny accessProtocol accessPort denyHost

#拒绝其他所有请求
http_access deny all

###########反向代理相关设置#################################
#设置反向代理服务器监听的端口为80,accel表示开启squid的accel加速模式,
#vhost和vport表示支持虚拟主机和虚拟端口,如果再加上transparent表示支持透明代理
http_port 80 accel  vhost vport

#cache_peer表示如果本机缓存中找不到客户端请求的数据,将与主机www.abc.com以parent类型进行联系,no-query表示不使用ICP协议进行联系,
#而是使用HTTP协议进行联系,no-digest表示代理服务器之间不做摘要表查询,直接用ICP协议沟通(同级代理)。端口是80,orginserver表示此服务器是源服务器,name表示别名。
cache_peer 192.168.1.101 parent 80 0 no-query no-digest originserver name=RS1
cache_peer 192.168.1.102 parent 80 0 no-query no-digest originserver name=RS2

offline_mode on    ##离线模式
#设置别名所对应的域名,如果cache_peer中使用域名而不是IP的话,那么cache_peer_domain中一定要用相同的域名,否则无法访问
cache_peer_domain Server_te image.wuchaofeng.com
cache_peer_domain Server_go www.wuchaofeng.com

#################缓存相关参数设置################
#设置缓存内存大小,最大使用内存为512M,
#当使用超过95%时开始对缓存进行替换,直到下降到90%后停止
cache_mem 512 MB
cache_swap_low 90
cache_swap_high 95
#设置内存中最大可缓存的最大文件大小
maximum_object_size_in_memory 128 KB
#设置磁盘中可缓存的最大文件大小
maximum_object_size 65536 KB
minimum_object_size 0 KB
#设置缓存文件夹的路径和参数,10240表示10G大小,目录下面分为16级,每级又有256个目录
cache_dir ufs /data/cache 10240 16 256
#内存和硬盘cache的替换策略
memory_replacement_policy lru
cache_replacement_policy lru

#设置缓存日志文件路径
logformat main %>a  %{%Y-%m-%d %H:%M:%S}tl  %>Hs     %<st    %ru     %{Referer}>h    %Ss:%Sh
access_log /usr/local/squid/var/logs/access.log main
cache_log /dev/null
cache_store_log none
#关闭该项,这样就可以显示用户的整个请求内容
strip_query_terms off 
#禁止squid的出错页面总会在网页的最下方显示主机相关信息和squid的版本信息
httpd_suppress_version_string on

#设置用户请求的HTTP头大小
request_header_max_size 128 KB
#设置用户的真实IP地址通过X-Forwarded-For中传递下去
forwarded_for on 
#http1.0的vary信息里带有过期时间的话,squid还是不能缓存住。打开此选项提高缓存命中率
vary_ignore_expire on
#修改默认缓存时间,默认是60s,解决当Expires设置为60秒以内时都不会Cache,但当设置成61秒时就能Cache
minimum_expiry_time 10 seconds
#合并回源,多个回源流量变成一个回源,这个在大文件时,也比较有用。
collapsed_forwarding on

#refresh_pattern 控制文件过期的,percent与Min、Max(都是分钟)两个值是完全没有关系
#1.缓冲对象在squid的cache缓冲的时间大于refresh_pattern定义的max,该响应过期
#2.缓冲对象在squid的cache缓冲的时间大于(原始数据进入squid的缓冲的时间-原始web数据所规定的Last-Modified时间)*percent,该响应过期
#开头是ftp的话,那么在一天(1440分钟)后,如果proxy 再次取用这个档案时,则cache内的数据会被更新
refresh_pattern ^ftp:           1440(min)    20%(percentage)     10080(max)
refresh_pattern ^gopher:        1440             0%                1440
refresh_pattern (cgi-bin|\?)    0                0%                0
refresh_pattern .               0                20%               4320

Min:是指一个object在缺少明确的Expires的情况下,能够确定的在cache中被认为最新的分钟数(小于此值肯定是最新的)。这个参数推荐设为0,否则会造成动态应用中的内容被不正确地缓存住。

Max:是指一个object在缺少明确的Expires的情况下,在 cache中可能被认为最新的分钟数的最大值(大于此值肯定是过期的)。

percentage是指,一个object在缺少明确的Expires的情况下,它的LM-factor的最大值(LM-factor超过此值则认为过期,否则最新)
(LM-factor= (当前时间-到达cache的时间) / (到达cache的时间 – Last-Modified) * 100%)

#设置squid 用户和组
cache_effective_user squid
cache_effective_group squid
#设置代理服务器名称
visible_hostname wuchaofeng.com
#设置缓存服务器管理员邮箱
cache_mgr wuchaofeng@qq.com
#squid挂掉后,错误信息的存放目录
coredump_dir /usr/local/squid/var/cache

#不记图片类访问日志设置
acl nolog urlpath_regex \\.gif \\.jpg \\.css \\.js \\.swf
access_log /data/squid/var/logs/access.log common !nolog