目录
Squid
缓存代理
Web代理的工作机制
代理类型
传统代理
透明代理
使用代理的好处
示例和案例
Squid安装示例
使用源码包安装Squid
一些其他的安装参数(安装用时较长)
为什么异步io要指定线程数?
配置和初始化Squid
运行测试
传统代理案例
案例拓扑图
测试机设置代理
部署Web服务器
配置代理服务器
查看访问日志
透明代理案例
案例拓扑图
案例基本设置
配置Web服务器
配置代理服务器
配置防火墙策略
测试
ACL访问控制
定义针对特定IP范围的列表
定义针对特定域名的列表
修改配置文件
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 列表中的请求
使用客户端测试,此时访问就被拒绝了