目录
Squid
Squid是一款开源代理服务软件,可以很好的实现HTTP、FTP、DNS查询、SSL等应用的缓存代理,功能强大
缓存代理
作为应用层的代理服务软件,Squid主要提供缓存加速、应用层过滤控制的功能
Web代理的工作机制
- 缓存网页对象,减少重复请求
- 只缓存静态内容,不缓存动态内容
当客户端通过代理来请求网页时,指定的代理服务器会先检查自己的缓存,如果缓存中已经有请求URL中需要的页面,则直接将缓存的页面返回给客户端。
如果缓存中没有客户端要访问的页面,就由代理服务器向请求URL中的Web服务器发送请求,获得Web服务器的响应后,将网页数据保存到缓存中,然后再发送给客户端
代理类型
-
传统代理
- 一般是为某个应用程序做代理而不是整个主机,比如浏览器、QQ
- 需要在应用程序中指定代理服务器,通常不在同一个局域网内,通过互联网通信
当客户端的浏览器访问一个网站时,浏览器会先把报文发给代理服务器,代理服务器根据请求的URL把请求报文转发给该网站的Web服务器
Web服务器收到请求后,把结果响应给代理服务器,代理服务器自己缓存一份,再转发给客户端一份
-
透明代理
- 客户机不需要指定代理服务器的地址和端口,而是通过默认路由、防火墙策略将Web访问重定向给代理服务器处理
- 代理服务器将是你的网关,只需要正确设置网络信息(IP、网关地址),而不需要专门指定代理服务器
使用代理的好处
- 提高Web访问速度
- 隐藏客户机的真实IP地址
示例和案例
Squid安装示例
不管是传统代理还是透明代理,Squid安装的方式都是一样的,所以我们这里先演示安装的步骤,然后做一个快照,方便后续实验
使用源码包安装Squid
本次示例不能关闭防火墙,因为Squid做代理的时候需要用到防火墙来配置转发策略
打开一台CentOS 7虚拟机,并连接上XShell
首先,导入Squid的源码包
然后安装所需环境,先暂时安装gcc*相关软件包
[root@localhost ~]# yum -y install gcc*
解压,进入解压目录,执行./configure脚本并配置安装参数,待检查完毕后使用make && make install命令进行安装,安装用时较长……
[root@localhost ~]# tar zxvf squid-3.5.23.tar.gz
[root@localhost squid-3.5.23]# ./configure --prefix=/usr/local/squid --sysconfdir=/etc --enable-linux-netfilter --enable-gnuregex
[root@localhost squid-3.5.23]# make && make install
- --enable-linux-netfilter:启用内核过滤功能,能够支持透明代理,让Squid拥有网关的功能(转发数据包),因此也要为防火墙配置转发策略
- --enable-gnuregex:启用访问过滤,在配置文件中使用正则表达式来配置
一些其他的安装参数(安装用时较长)
- --enable-async-io=240:开启异步io功能,240表示在进行异步io时提供的线程数
- --enable-default-err-language=Simplify_Chinese:指定错误信息的语言为简体中文
- --disable-poll:禁用poll函数,poll函数的性能并不好,我们要使用性能更好的epoll函数
- --enable-epoll:启用epoll函数
为什么异步io要指定线程数?
Squid是一个代理服务器,每个用户需要通过这个代理服务器访问网站的时候,当用户访问量很大时,需要保存每一个用户请求的数据,所以需要支持更多的用户能够同时的、并发的访问
因为CPU需要内核把一个进程拆解成若干个线程,然后让CPU对每一个线程进行单独的运算
超线程:所以现在市面上的CPU都有超线程的功能,一个内核一次可以处理两个线程,这也是为什么我们看到有的CPU是8核16线程
配置和初始化Squid
然后创建软链接来优化命令路径,使我们可以直接在终端里像使用系统命令一样来使用Squid的命令
[root@localhost ~]# ln -s /usr/local/squid/sbin/* /usr/local/sbin/
由于Squid是一个缓存机制,所以要有地方去存放这些缓存数据,我们cd进入Squid安装目录下的var/目录
使用ll命令查看权限,可以发现都是root,但是在运行该程序的时候,我们不能以root用户的身份去运行,因为在程序运行时,一旦有黑客劫持了该程序,那就意味着该程序运行用户的权限了,也就获取了root用户的权限了
[root@localhost ~]# cd /usr/local/squid/var/
[root@localhost var]# ll
总用量 0
drwxr-xr-x. 3 root root 19 8月 14 22:16 cache
drwxr-xr-x. 2 root root 6 8月 14 22:16 logs
drwxr-xr-x. 3 root root 19 8月 14 22:16 run
所以为了安全性考虑,可以让专门运行该程序的程序用户来控制该程序,也就是要修改这些文件的属主和属组
创建程序用户,-M指定不创建家目录,-s不能用于登录
[root@localhost var]# useradd -M -s /sbin/nologin squid
使用cd ..命令返回上一级目录,然后使用chown命令加-R选项来修改var目录下及其所有子目录下的文件或目录的属主和属组
然后再cd进入var/目录下,使用ll命令可以看到属主和属组都被改变
[root@localhost var]# cd ..
[root@localhost squid]# chown -R squid:squid var/
[root@localhost squid]# cd var/
[root@localhost var]# ll
总用量 0
drwxr-xr-x. 3 squid squid 19 8月 14 22:16 cache
drwxr-xr-x. 2 squid squid 6 8月 14 22:16 logs
drwxr-xr-x. 3 squid squid 19 8月 14 22:16 run
因为在安装Squid的时候并没有指定运行该程序的用户,所以要在配置文件中指定一下程序用户
打开Squid的配置文件,在第62行把注释去掉,指定缓存目录的相关参数
[root@localhost var]# vim /etc/squid.conf
cache_dir ufs /usr/local/squid/var/cache/squid 100 16 256
- ufs:是一种数据的存储格式
- 100:缓存大小,单位100兆(Mb)
- 16:一级目录的目录数量
- 256:二级目录的目录数量
然后在整个配置文件的末尾,添加程序用户的参数,如下图
指定运行程序的用户和基本组
- effective:有效的
cache_effective_user squid
cache_effective_group squid
然后在第26行下方,添加参数,允许所有客户端访问本代理服务器,如下图
http_access allow all
运行测试
保存并退出,使用squid -k parse命令解析配置文件来检查语法是否正确,如果配置文件的语法无误,就会把配置文件的内容输出一遍
[root@localhost var]# squid -k parse
再使用squid -z命令初始化缓存目录
[root@localhost var]# squid -z
那么在当前的/usr/local/squid/var目录下,我们cd进入cache/squid/目录下,也就是缓存目录
使用ls命令可以看到在配置文件中指定的16个一级目录
[root@localhost var]# cd cache/squid/
[root@localhost squid]# ls
00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
在任意进入一个一级目录就可以看到在配置文件中指定的256个二级目录(00 ~ FF)
[root@localhost squid]# cd 00/
[root@localhost 00]# ls
00 0B 16 21 2C 37 42 4D 58 FF
# 省略...
此时可以使用squid命令来启动squid程序,然后使用netstat命令查看该服务是否运行
可以发现squid在传统模式下默认监听的端口号是:3128
[root@localhost ~]# squid
[root@localhost ~]# netstat -anpt | grep squid
tcp6 0 0 :::3128 :::* LISTEN 53860/(squid-1)
如果要关闭Squid服务,需要使用pkill命令加上-9信号强制杀死
[root@localhost ~]# pkill -9 squid
[root@localhost ~]# netstat -anpt | grep squid
最后可以关机或不关机做一个快照,方便后续实验
传统代理案例
这个案例是设置Squid代理服务器如何实现传统代理的模式提供服务
案例拓扑图
因为本案例的环境是3台主机都能通过互联网通信,所以只需要让3台主机能互相ping通就行了
操作系统 | IP 地址 | 角色 |
CentOS | 192.168.10.101 | Squid 代理服务器 |
CentOS | 192.168.10.102 | Web服务器 |
Windows(宿主机或虚拟机) | 客户端,使用浏览器测试 |
测试机设置代理
在客户端操作
在刚才安装过一台Squid服务器的基础下,再启动1台CentOS虚拟机,并连接上XShell
如果刚才的Squid服务器关机做快照了,现在就启动Squid服务器,并且启动Squid服务
在Windows自带的浏览器中,打开设置,然后搜索 "代理" 来打开计算机的代理设置,如下图
然后将IP和端口都设为Squid服务器的IP,这里的端口号是在Squid服务器使用netstat命令查看到的Squid程序的端口3128
然后点击保存就可以了
部署Web服务器
代理服务器设置好了,还需要有一个Web服务器给客户端提供服务
在102(Web服务器)操作
为了方便实验关闭防火墙和内核安全机制,然后使用yum命令快速的安装一个Apache HTTP Server
[root@localhost ~]# systemctl stop firewalld
[root@localhost ~]# setenforce 0
[root@localhost ~]# yum -y install httpd
cd进入Apache存放网页文件的目录下,编写一个测试的页面
[root@localhost ~]# cd /var/www/html/
[root@localhost html]# vim index.html
这里编写了一个使用超链接下载文件的网页,保存并退出,在/var/www/html/目录下,除了编写的网页文件以外,还需要把超链接的这两个文件从宿主机导入到当前目录下
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>无标题文档</title>
</head>
<body>
<p>软件下载1:<a href="test01.zip">测试01.zip</a></br>
软件下载2:<a href="test02.rar">测试02.rar</a>
</p>
</body>
</html>
保存退出后,启动服务
[root@localhost html]# systemctl start httpd
但是此时代理服务器还没有配置防火墙的转发策略,所以当前还无法实现代理的效果
配置代理服务器
在101(代理服务器)操作
注意:这里的配置是只针对代理服务器的防火墙策略,而不是针对配置文件的修改,配置文件的修改在上面安装Squid的示例已经修改了,所以在本次实现传统代理的案例中,代理服务器的配置是基于安装时修改的配置文件来实现的
添加允许访问http服务的流量通过,由于防火墙没有针对3128端口的服务策略,所以使用添加端口的方式允许3128端口的流量通过
因为我们添加策略是永久的,所以需要重载防火墙
[root@localhost ~]# firewall-cmd --add-service=http --permanent
[root@localhost ~]# firewall-cmd --add-port=3128/tcp --permanent
[root@localhost ~]# firewall-cmd --reload
来到客户端的浏览器测试,访问Web服务器,此时就可以由代理服务器转发请求给Web服务器实现代理访问了
查看访问日志
在102(Web服务器)操作
此时来到Web服务器查看访问日志,可以发现访问的IP都是101的,验证了代理的效果
[root@localhost html]# tail /var/log/httpd/access_log
192.168.10.101 - - [15/Aug/2024:09:25:49 +0800] "GET / HTTP/1.1" 200 469 "-"
192.168.10.101 - - [15/Aug/2024:09:25:49 +0800] "GET /favicon.ico HTTP/1.1"
192.168.10.101 - - [15/Aug/2024:09:26:51 +0800] "GET / HTTP/1.1"
# 省略...
在101(代理服务器)操作
查看Squid的访问日志,这里记录的就是客户端的IP了
[root@localhost ~]# tail /usr/local/squid/var/logs/access.log
1723685225.337 282090 192.168.10.1 TCP_TUNNEL/200 6547 CONNECT access-point.cloudmessaging.edge.microsoft.com:443 - HIER_DIRECT/20.187.186.89 -
1723685225.350 90391 192.168.10.1 TCP_TUNNEL/200 39014 CONNECT img-s-msn-com.akamaized.net:443 - HIER_DIRECT/23.32.238.168 -
# 省略...
而如果此时关闭101主机的Squid服务,那么客户端就不能访问了
[root@localhost ~]# pkill -9 squid
透明代理案例
透明代理服务器已经成为你的网关了,因此不需要客户端手动设置代理地址,只需要正确配置网管地址就可以了
案例拓扑图
操作系统 | IP 地址 | 桥接 | 角色 |
CentOS | 外网接口地址:172.16.16.1 内网接口地址:192.168.10.101 | NAT | Squid 代理服务器 |
CentOS | 172.16.16.172 | ens33:NAT ens36:VMnet1 | Web服务器 |
虚拟机 | 备注:(不推荐使用宿主机,因为要修改网关地址) | 客户端,使用浏览器测试 |
在实现本次案例时,代理服务器(101)和Web服务器(102)可以继续使用刚才实现传统代理的状态,或者101主机(代理服务器)恢复安装完Squid的快照也可以
使用netstat命令查看Squid是否运行,如果没有,使用squid命令启动
案例基本设置
在Windows的设置关闭代理功能
在101(Squid代理服务器)操作
由于实现透明代理的代理服务器作为网关,所以需要有两个网卡,这里我们打开101虚拟机的设置,再添加一块网卡
那么既然外网网卡要单独和外网的Web服务器在同一网段,这里就把代理服务器的外网接口和外网的Web服务器的桥接模式都改为VMnet1
因为Web服务器(102)的桥接模式修改完以后XShell就连接不上了,所以我们先配置代理服务器
先使用ifconfig命令查看新添加网卡的插槽标识,注意不同的系统或主机可能网卡的标识会不一样
可以发现新加的网卡是ens36,我们来为ens36配置IP地址
[root@localhost ~]# ifconfig
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.10.101 netmask 255.255.255.0 broadcast 192.168.10.255
# 省略...
ens36: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
ether 00:0c:29:bc:15:29 txqueuelen 1000 (Ethernet)
# 省略...
cd进入存放网卡配置文件的目录下, 拷贝出ens36的网卡配置文件,然后编辑
[root@localhost ~]# cd /etc/sysconfig/network-scripts/
[root@localhost network-scripts]# cp ifcfg-ens33 ifcfg-ens36
[root@localhost network-scripts]# vim ifcfg-ens36
在网卡配置文件中修改下方几行的内容,注意网关地址和UUID要注释掉,然后保存并退出
IPADDR=172.16.16.1
NETMASK=255.255.255.0
#GATEWAY=192.168.10.254
DNS1=114.114.114.144
DNS2=8.8.8.8
#UUID...
NAME=ens36
DEVICE=ens36
重启网络,然后使用ifconfig命令查看ens36的IP是否被修改成功了
[root@localhost network-scripts]# systemctl restart network
[root@localhost network-scripts]# ifconfig
ens36: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.16.16.1 netmask 255.255.255.0 broadcast 172.16.16.255
配置Web服务器
在102(外网Web服务器)操作
因为Web服务器已开经和XShell断连接了,所以来到虚拟机的TTY终端进行操作
修改网卡配置文件,修改IP为拓扑图中的IP,把网关地址注释掉
[root@localhost ~]# vim /etc/sysconfig/network-scripts/ifcfg-ens33
IPADDR=172.16.16.172
NETMASK=255.255.255.0
#GATEWAY=192.168.10.254
保存并退出,重启服务,查看IP是否被修改
[root@localhost network-scripts]# systemctl restart network
[root@localhost network-scripts]# ifconfig
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.16.16.172 netmask 255.255.255.0 broadcast 172.16.16.255
在101(Squid代理服务器)操作
此时测试代理服务器能否访问外网的Web服务器,如果能访问,那Web服务器就配置好了
[root@localhost ~]# curl 172.16.16.172
# 省略网页内容...
配置代理服务器
在101(Squid代理服务器)操作
先打开Squid的配置文件,把配置文件改为透明代理的配置,在大概61行,因为当前代理服务器有两个IP地址,指定用内网网卡的IP来监听,然后添加transparent参数,指定为透明代理模式
[root@localhost ~]# vim /etc/squid.conf
http_port 192.168.10.101:3128 transparent
保存并退出,重启服务(pkill杀死,再启动),然后使用netstat命令检查是否启动
[root@localhost ~]# pkill -9 squid
[root@localhost ~]# squid
[root@localhost ~]# netstat -anpt | grep squid
tcp 0 0 192.168.10.101:3128 0.0.0.0:* LISTEN 2236/(squid-1)
在客户端操作
把客户端的修改网关地址改为代理服务器的内网IP
配置防火墙策略
在101(Squid代理服务器)操作
为了不影响透明代理案例的实现,我们先删除刚才传统代理配置的防火墙策略
[root@localhost ~]# firewall-cmd --remove-service=http --permanent
[root@localhost ~]# firewall-cmd --remove-port=3128/tcp --permanent
[root@localhost ~]# firewall-cmd --reload
既然两个网卡一个连接外网一个连接内网,那两个网卡的区域也要修改
把ens36网卡加入到external的区域就自动拥有了地址伪装的功能,才能拥有网关的源地址转换功能
- 外部区域(external):这个区域通常代表企业外部的网络环境,通常包括互联网或其他不受信任的网络。
- 在这个区域中的计算机或设备可能包含潜在的安全风险,因此对它们的访问和控制会更加严格,以保护企业内部网络不受外部侵害。
[root@localhost ~]# firewall-cmd --zone=external --change-interface=ens36
success
因为默认网卡的区域的public,所以我们修改ens33到的区域到internal,也就是内网
- 内部区域(internal):这个区域通常代表企业内部网络或受信任的网络环境。
- 在这个区域中的计算机或设备被认为是可信的,它们之间的通信受到较少的限制,以便于企业内部的数据交换和通信。
[root@localhost ~]# firewall-cmd --zone=internal --change-interface=ens33
success
允许http(80端口)和3128端口TCP协议的流量通过
[root@localhost ~]# firewall-cmd --zone=internal --add-service=http
[root@localhost ~]# firewall-cmd --zone=internal --add-port=3128/tcp
使用直接规则来实现:如果客户端请求访问的是80端口,代理服务器接收到请求后,就要转发给3128端口,也就说明该请求就被Squid进程接收到了
[root@localhost ~]# firewall-cmd --direct --add-rule ipv4 nat PREROUTING 0 -i ens33 -p tcp --dport 80 -j REDIRECT --to-ports 3128
success
- -i:input,流量的方向
如果在添加策略的时候没有设为永久时,可以使用runtime-to-permanent选项把策略从运行时改为永久时
[root@localhost ~]# firewall-cmd --runtime-to-permanent
测试
在客户端操作
最后,来到客户端输入外网Web服务器的IP地址进行访问,使用内网客户端也可以访问到了,实现透明代理
ACL访问控制
控制特定IP范围的用户访问
定义针对特定IP范围的列表
IP的限制列表
[root@localhost ~]# vim /opt/ipBlock.list
172.16.16.172
定义针对特定域名的列表
域名的限制列表
[root@localhost ~]# vim /opt/dmBlock.list
qq.com
修改配置文件
在第25行下方,修改匹配192.168.0.0网段的ACL语句 名称为test
[root@localhost ~]# vim /etc/squid.conf
acl test src 192.168.0.0/16 # 修改acl名称为test
# 省略...
acl ipBlock dst "/opt/ipBlock.list"
acl dmBlock dstdomain "/opt/dmBlock.list"
http_access deny test ipBlock
http_access deny test dmBlock
- 定义一个名为 ipBlock 的 ACL,它匹配目标 IP 地址在/opt/ipBlock.list文件中列出的地址
- 定义一个名为 dmBlock 的 ACL,它匹配目标域名在/opt/dmBlock.list文件中列出的域名
- 拒绝任何来自 test ACL(即 IP 地址在 192.168.0.0/16 范围内)并且目标在 ipBlock ACL 列表中的请求
- 拒绝任何来自 test ACL 并且目标在 dmBlock ACL 列表中的请求
使用客户端测试,此时访问就被拒绝了