16.3 正向代理

16.3.1 标准正向代理

Squid服务程序软件包在正确安装并启动后,默认就已经可以为用户提供标准正向代理模式服务了,而不再需要单独修改配置文件或者进行其他操作。接下来在运行Windows 7系统的客户端上面打开任意一款浏览器,然后单击“Internet选项”命令,如图16-4所示。

  1. [root@linuxprobe ~]# systemctl restart squid
  2. [root@linuxprobe ~]# systemctl enable squid
  3. ln -s '/usr/lib/systemd/system/squid.service' '/etc/systemd/system/multi-user.target.wants/squid.service'

浏览器设置

图16-4 单击浏览器中的“Internet选项”命令

要想使用Squid服务程序提供的标准正向代理模式服务,就必须在浏览器中填写服务器的IP地址以及端口号信息。因此还需要在“连接”选项卡下单击“局域网设置”按钮(见图16-5),并按照图16-6所示填写代理服务器的信息,然后保存并退出配置向导。

网络选项

图16-5 在“连接”选项卡中单击“局域网设置”按钮

填写Squid服务器的IP地址与端口号

图16-6 填写代理服务器的IP地址与端口号

现在,用户可以使用Squid服务程序提供的代理服务了。托代理服务器转发的福,网卡被设置为仅主机模式(Hostonly)的虚拟机也能奇迹般地上网浏览了,如图16-7所示。

16.3 正向代理 - 图4

图16-7 虚拟机可以正常网络外网

如此公开而没有密码验证的代理服务终归让人觉得不放心,万一有人也来“蹭网”该怎么办呢?Squid服务程序默认使用3128、3401与4827等端口号,因此可以把默认使用的端口号修改为其他值,以便起到一定的保护作用。现在大家应该都知道,在Linux系统配置服务程序其实就是修改该服务的配置文件,因此直接在/etc目录下的Squid服务程序同名目录中找到配置文件,把http_port参数后面原有的3128修改为10000,即把Squid服务程序的代理服务端口修改成了新值。最后一定不要忘记重启服务程序。

  1. [root@linuxprobe ~]# vim /etc/squid/squid.conf
  2. ………………省略部分输出信息………………
  3. 45 #
  4. 46 # INSERT YOUR OWN RULE(S) HERE TO ALLOW ACCESS FROM YOUR CLIENTS
  5. 47 #
  6. 48
  7. 49 # Example rule allowing access from your local networks.
  8. 50 # Adapt localnet in the ACL section to list your (internal) IP networks
  9. 51 # from where browsing should be allowed
  10. 52 http_access allow localnet
  11. 53 http_access allow localhost
  12. 54
  13. 55 # And finally deny all other access to this proxy
  14. 56 http_access deny all
  15. 57
  16. 58 # Squid normally listens to port 3128
  17. 59 http_port 10000
  18. 60
  19. http_port 10000
  20. ………………省略部分输出信息………………
  21. [root@linuxprobe ~]# systemctl restart squid
  22. [root@linuxprobe ~]# systemctl enable squid
  23. ln -s '/usr/lib/systemd/system/squid.service' '/etc/systemd/system/multi-user.target.wants/squid.service'

有没有突然觉得这一幕似曾相识?在10.5.3节讲解基于端口号来部署httpd服务程序的虚拟主机功能时,我们在编辑完httpd服务程序的配置文件并重启服务程序后,被系统提示报错。尽管现在重启Squid服务程序后系统没有报错,但是用户还不能使用代理服务。SElinux安全子系统认为Squid服务程序使用3128端口号是理所当然的,因此在默认策略规则中也是允许的,但是现在Squid服务程序却尝试使用新的10000端口号,而该端口原本并不属于Squid服务程序应该使用的系统资源,因此还需要手动把新的端口号添加到Squid服务程序在SElinux域的允许列表中。

  1. [root@linuxprobe ~]# semanage port -l | grep squid_port_t
  2. squid_port_t tcp 3128, 3401, 4827
  3. squid_port_t udp 3401, 4827
  4. [root@linuxprobe ~]# semanage port -a -t squid_port_t -p tcp 10000
  5. [root@linuxprobe ~]# semanage port -l | grep squid_port_t
  6. squid_port_t tcp 10000, 3128, 3401, 4827
  7. squid_port_t udp 3401, 4827

出现问题?大胆提问!

因读者们硬件不同或操作错误都可能导致实验配置出错,请耐心再仔细看看操作步骤吧,不要气馁~

Linux技术交流请加A群:560843(),B群:340829(推荐),C群:463590(推荐),点此查看全国群

*本群特色:通过口令验证确保每一个群员都是《Linux就该这么学》的读者,答疑更有针对性,不定期免费领取定制礼品。

16.3.2 ACL访问控制

在日常工作中,企业员工一般是通过公司内部的网关服务器来访问互联网,当将Squid服务程序部署为公司网络的网关服务器后,Squid服务程序的访问控制列表(ACL)功能将发挥它的用武之地。它可以根据指定的策略条件来缓存数据或限制用户的访问。比如很多公司会分时段地禁止员工逛淘宝、打网页游戏,这些禁止行为都可以通过Squid服务程序的ACL功能来实现。大家如果日后在人员流动较大的公司中从事运维工作,可以牢记本节内容,在公司网关服务器上部署的Squid服务程序中添加某些策略条件,禁止员工访问某些招聘网站或竞争对手的网站,没准还能有效降低员工的流失率。

Squid服务程序的ACL是由多个策略规则组成的,它可以根据指定的策略规则来允许或限制访问请求,而且策略规则的匹配顺序与防火墙策略规则一样都是由上至下;在一旦形成匹配之后,则立即执行相应操作并结束匹配过程。为了避免ACL将所有流量全部禁止或全部放行,起不到预期的访问控制效果,运维人员通常会在ACL的最下面写上deny all或者allow all语句,以避免安全隐患。

刘遄老师将通过下面的4个实验向大家演示Squid服务程序的ACL功能有多么强大。

实验1只允许IP地址为192.168.10.20的客户端使用服务器上的Squid服务程序提供的代理服务,禁止其余所有的主机代理请求。

下面的配置文件依然是Squid服务程序的配置文件,但是需要留心配置参数的填写位置。如果写的太靠前,则有些Squid服务程序自身的语句都没有加载完,也会导致策略无效。当然也不用太靠后,大约在26~32行的位置就可以,而且采用分行填写的方式也便于日后的修改。

  1. [root@linuxprobe ~]# vim /etc/squid/squid.conf
  2. 1 #
  3. 2 # Recommended minimum configuration:
  4. 3 #
  5. 4
  6. 5 # Example rule allowing access from your local networks.
  7. 6 # Adapt to list your (internal) IP networks from where browsing
  8. 7 # should be allowed
  9. 8 acl localnet src 10.0.0.0/8 # RFC1918 possible internal network
  10. 9 acl localnet src 172.16.0.0/12 # RFC1918 possible internal network
  11. 10 acl localnet src 192.168.0.0/16 # RFC1918 possible internal network
  12. 11 acl localnet src fc00::/7 # RFC 4193 local private network range
  13. 12 acl localnet src fe80::/10 # RFC 4291 link-local (directly plugged) mac hines
  14. 13
  15. 14 acl SSL_ports port 443
  16. 15 acl Safe_ports port 80 # http
  17. 16 acl Safe_ports port 21 # ftp
  18. 17 acl Safe_ports port 443 # https
  19. 18 acl Safe_ports port 70 # gopher
  20. 19 acl Safe_ports port 210 # wais
  21. 20 acl Safe_ports port 1025-65535 # unregistered ports
  22. 21 acl Safe_ports port 280 # http-mgmt
  23. 22 acl Safe_ports port 488 # gss-http
  24. 23 acl Safe_ports port 591 # filemaker
  25. 24 acl Safe_ports port 777 # multiling http
  26. 25 acl CONNECT method CONNECT
  27. 26 acl client src 192.168.10.20
  28. 27 #
  29. 28 # Recommended minimum Access Permission configuration:
  30. 29 #
  31. 30 # Deny requests to certain unsafe ports
  32. 31 http_access allow client
  33. 32 http_access deny all
  34. 33 http_access deny !Safe_ports
  35. 34
  36. [root@linuxprobe ~]# systemctl restart squid

上面的配置参数其实很容易理解。首先定义了一个名为client的别名。这其实类似于13.6节讲解的DNS分离解析技术,当时我们分别定义了两个名为china与american的别名变量,这样当再遇到这个别名时也就意味着与之定义的IP地址了。保存配置文件后重启Squid服务程序,这时由于客户端主机的IP地址不符合我们的允许策略而被禁止使用代理服务,如图16-8所示。

访问被拒绝

图16-8 使用代理服务浏览网页失败

实验2:禁止所有客户端访问网址中包含linux关键词的网站。

Squid服务程序的这种ACL功能模式是比较粗犷暴力的,客户端访问的任何网址中只要包含了某个关键词就会被立即禁止访问,但是这并不影响访问其他网站。

  1. [root@linuxprobe ~]# vim /etc/squid/squid.conf
  2. 1 #
  3. 2 # Recommended minimum configuration:
  4. 3 #
  5. 4
  6. 5 # Example rule allowing access from your local networks.
  7. 6 # Adapt to list your (internal) IP networks from where browsing
  8. 7 # should be allowed
  9. 8 acl localnet src 10.0.0.0/8 # RFC1918 possible internal network
  10. 9 acl localnet src 172.16.0.0/12 # RFC1918 possible internal network
  11. 10 acl localnet src 192.168.0.0/16 # RFC1918 possible internal network
  12. 11 acl localnet src fc00::/7 # RFC 4193 local private network range
  13. 12 acl localnet src fe80::/10 # RFC 4291 link-local (directly plugged) mac hines
  14. 13
  15. 14 acl SSL_ports port 443
  16. 15 acl Safe_ports port 80 # http
  17. 16 acl Safe_ports port 21 # ftp
  18. 17 acl Safe_ports port 443 # https
  19. 18 acl Safe_ports port 70 # gopher
  20. 19 acl Safe_ports port 210 # wais
  21. 20 acl Safe_ports port 1025-65535 # unregistered ports
  22. 21 acl Safe_ports port 280 # http-mgmt
  23. 22 acl Safe_ports port 488 # gss-http
  24. 23 acl Safe_ports port 591 # filemaker
  25. 24 acl Safe_ports port 777 # multiling http
  26. 25 acl CONNECT method CONNECT
  27. 26 acl deny_keyword url_regex -i linux
  28. 27 #
  29. 28 # Recommended minimum Access Permission configuration:
  30. 29 #
  31. 30 # Deny requests to certain unsafe ports
  32. 31 http_access deny deny_keyword
  33. 33 http_access deny !Safe_ports
  34. 34
  35. [root@linuxprobe ~]# systemctl restart squid

刘遄老师建议大家在进行实验之前,一定要先把前面实验中的代码清理干净,以免不同的实验之间产生冲突。在当前的实验中,我们直接定义了一个名为deny_keyword的别名,然后把所有网址带有linux关键词的网站请求统统拒绝掉。当客户端分别访问带有linux关键词和不带有linux关键词的网站时,其结果如图16-9所示。

访问又被拒绝

图16-9 当客户端分别访问带有linux关键词和不带linux关键词的网站时,所呈现的结果

实验3:禁止所有客户端访问某个特定的网站。

在实验2中,由于我们禁止所有客户端访问网址中包含linux关键词的网站,这将造成一大批网站被误封,从而影响同事们的正常工作。其实通过禁止客户端访问某个特定的网址,也就避免了误封的行为。下面按照如下所示的参数配置Squid服务程序并重启,然后进行测试,其测试结果如图16-10所示。

  1. [root@linuxprobe ~]# vim /etc/squid/squid.conf
  2. 24 acl Safe_ports port 777 # multiling http
  3. 25 acl CONNECT method CONNECT
  4. 26 acl deny_url url_regex http://www.linuxcool.com
  5. 27 #
  6. 28 # Recommended minimum Access Permission configuration:
  7. 29 #
  8. 30 # Deny requests to certain unsafe ports
  9. 31 http_access deny deny_url
  10. 33 http_access deny !Safe_ports
  11. 34
  12. [root@linuxprobe ~]# systemctl restart squid

16.3 正向代理 - 图7

图16-10 无法使用代理服务访问这个特定的网站

实验4:禁止员工在企业网内部下载带有某些后缀的文件。

在企业网络中,总会有一小部分人利用企业网络的高速带宽私自下载资源(比如游戏安装文件、电影文件等),从而对其他同事的工作效率造成影响。通过禁止所有用户访问.rar或.avi等后缀文件的请求,可以防止他们继续下载资源,让他们知难而退。下面按照如下所示的参数配置Squid服务程序并重启,然后进行测试,其测试结果如图16-11所示。

如果这些员工是使用迅雷等P2P下载软件来下载资源的话,就只能使用专业级的应用防火墙来禁止了。

  1. [root@linuxprobe ~]# vim /etc/squid/squid.conf
  2. 24 acl Safe_ports port 777 # multiling http
  3. 25 acl CONNECT method CONNECT
  4. 26 acl badfile urlpath_regex -i \.mp3$ \.rar$
  5. 27 #
  6. 28 # Recommended minimum Access Permission configuration:
  7. 29 #
  8. 30 # Deny requests to certain unsafe ports
  9. 31 http_access deny badfile
  10. 33 http_access deny !Safe_ports
  11. 34
  12. [root@linuxprobe ~]# systemctl restart squid

16.3 正向代理 - 图8

图16-11 无法使用代理服务下载具有指定后缀的文件

16.3.3 透明正向代理

正向代理服务一般是针对企业内部的所有员工设置的,鉴于每位员工所掌握的计算机知识不尽相同,如果您所在的公司不是IT行业的公司,想教会大家如何使用代理服务也不是一件容易的事情。再者,无论是什么行业的公司,公司领导都希望能采取某些措施限制员工在公司内的上网行为,这时就需要用到透明的正向代理模式了。

“透明”二字指的是让用户在没有感知的情况下使用代理服务,这样的好处是一方面不需要用户手动配置代理服务器的信息,进而降低了代理服务的使用门槛;另一方面也可以更隐秘地监督员工的上网行为。

在透明代理模式中,用户无须在浏览器或其他软件中配置代理服务器地址、端口号等信息,而是由DHCP服务器将网络配置信息分配给客户端主机。这样只要用户打开浏览器便会自动使用代理服务了。如果大家此时并没有配置DHCP服务器,可以像如图16-12所示来手动配置客户端主机的网卡参数。

配置网卡信息

图16-12 配置Windows客户端的网络信息

为了避免实验之间互相影响,更好地体验透明代理技术的效果,我们需要把客户端浏览器的代理信息删除(即图16-6的操作),然后再刷新页面,就会看到访问任何网站都失败了,如图16-13所示。 尝试访问网站失败

图16-13 停止使用代理服务后无法成功访问网站

有些时候会因为Windows系统的缓存原因导致依然能看到网页内容,这时可以换个网站尝试一下访问效果。

既然要让用户在无需过多配置系统的情况下就能使用代理服务,作为运维人员就必须提前将网络配置信息与数据转发功能配置好。前面已经配置好的网络参数,接下来要使用8.3.2节介绍的SNAT技术完成数据的转发,让客户端主机将数据交给Squid代理服务器,再由后者转发到外网中。简单来说,就是让Squid服务器作为一个中间人,实现内网客户端主机与外部网络之间的数据传输。

由于当前还没有部署SNAT功能,因此当前内网中的客户端主机是不能访问外网的:

  1. C:\Users\linuxprobe>ping www.linuxprobe.com
  2. Ping 请求找不到主机 www.linuxprobe.com。请检查该名称,然后重试。

第8章已经介绍了iptables与firewalld防火墙理论知识以及策略规则的配置方法,大家可以任选其中一款完成接下来的实验。刘遄老师觉得firewalld防火墙实在太简单了,因此决定使用纯命令行的iptables防火墙管理工具来演示部署方法。

要想让内网中的客户端主机能够访问外网,客户端主机首先要能获取到DNS地址解析服务的数据,这样才能在互联网中找到对应网站的IP地址。下面通过iptables命令实现DNS地址解析服务53端口的数据转发功能,并且允许Squid服务器转发IPv4数据包。sysctl -p命令的作用是让转发参数立即生效:

  1. [root@linuxprobe ~]# iptables -F
  2. [root@linuxprobe ~]# iptables -t nat -A POSTROUTING -p udp --dport 53 -o eno33554968 -j MASQUERADE
  3. [root@linuxprobe ~]# echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf
  4. [root@linuxprobe ~]# sysctl -p
  5. net.ipv4.ip_forward = 1

现在回到客户端主机,再次ping某个外网地址。此时可以发现,虽然不能连通网站,但是此时已经能够获取到外网DNS服务的域名解析数据。这个步骤非常重要,为接下来的SNAT技术打下了扎实的基础。

  1. C:\Users\linuxprobe>ping www.linuxprobe.com
  2. 正在 Ping www.linuxprobe.com [116.31.127.233] 具有 32 字节的数据:
  3. 请求超时。
  4. 请求超时。
  5. 请求超时。
  6. 请求超时。
  7. 116.31.127.233 Ping 统计信息:
  8. 数据包: 已发送 = 4,已接收 = 0,丢失 = 4 (100% 丢失),

与配置DNS和SNAT技术转发相比,Squid服务程序透明代理模式的配置过程就十分简单了,只需要在主配置文件中服务器端口号后面追加上transparent单词(意思为“透明的”),然后把第62行的井号(#)注释符删除,设置缓存的保存路径就可以了。保存主配置文件并退出后再使用squid -k parse命令检查主配置文件是否有错误,以及使用squid -z命令对Squid服务程序的透明代理技术进行初始化。

  1. [root@linuxprobe ~]# vim /etc/squid/squid.conf
  2. ………………省略部分输出信息………………
  3. 58 # Squid normally listens to port 3128
  4. 59 http_port 3128 transparent
  5. 60
  6. 61 # Uncomment and adjust the following to add a disk cache directory.
  7. 62 cache_dir ufs /var/spool/squid 100 16 256
  8. 63
  9. ………………省略部分输出信息………………
  10. [root@linuxprobe ~]# squid -k parse
  11. 2017/04/13 06:40:44| Startup: Initializing Authentication Schemes ...
  12. 2017/04/13 06:40:44| Startup: Initialized Authentication Scheme 'basic'
  13. 2017/04/13 06:40:44| Startup: Initialized Authentication Scheme 'digest'
  14. 2017/04/13 06:40:44| Startup: Initialized Authentication Scheme 'negotiate'
  15. 2017/04/13 06:40:44| Startup: Initialized Authentication Scheme 'ntlm'
  16. 2017/04/13 06:40:44| Startup: Initialized Authentication.
  17. ………………省略部分输出信息………………
  18. [root@linuxprobe ~]# squid -z
  19. 2017/04/13 06:41:26 kid1| Creating missing swap directories
  20. 2017/04/13 06:41:26 kid1| /var/spool/squid exists
  21. 2017/04/13 06:41:26 kid1| Making directories in /var/spool/squid/00
  22. 2017/04/13 06:41:26 kid1| Making directories in /var/spool/squid/01
  23. 2017/04/13 06:41:26 kid1| Making directories in /var/spool/squid/02
  24. 2017/04/13 06:41:26 kid1| Making directories in /var/spool/squid/03
  25. 2017/04/13 06:41:26 kid1| Making directories in /var/spool/squid/04
  26. 2017/04/13 06:41:26 kid1| Making directories in /var/spool/squid/05
  27. 2017/04/13 06:41:26 kid1| Making directories in /var/spool/squid/06
  28. 2017/04/13 06:41:26 kid1| Making directories in /var/spool/squid/07
  29. 2017/04/13 06:41:26 kid1| Making directories in /var/spool/squid/08
  30. 2017/04/13 06:41:26 kid1| Making directories in /var/spool/squid/09
  31. 2017/04/13 06:41:26 kid1| Making directories in /var/spool/squid/0A
  32. 2017/04/13 06:41:26 kid1| Making directories in /var/spool/squid/0B
  33. 2017/04/13 06:41:26 kid1| Making directories in /var/spool/squid/0C
  34. 2017/04/13 06:41:26 kid1| Making directories in /var/spool/squid/0D
  35. 2017/04/13 06:41:26 kid1| Making directories in /var/spool/squid/0E
  36. 2017/04/13 06:41:26 kid1| Making directories in /var/spool/squid/0F
  37. [root@linuxprobe ~]# systemctl restart squid

在配置妥当并重启Squid服务程序且系统没有提示报错信息后,接下来就可以完成SNAT数据转发功能了。它的原理其实很简单,就是使用iptables防火墙管理命令把所有客户端主机对网站80端口的请求转发至Squid服务器本地的3128端口上。SNAT数据转发功能的具体配置参数如下。

  1. [root@linuxprobe ~]# iptables -t nat -A PREROUTING -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 3128
  2. [root@linuxprobe ~]# iptables -t nat -A POSTROUTING -s 192.168.10.0/24 -o eno33554968 -j SNAT --to 您的桥接网卡IP地址
  3. [root@linuxprobe ~]# service iptables save
  4. iptables: Saving firewall rules to /etc/sysconfig/iptables:[ OK ]

这时客户端主机再刷新一下浏览器,就又能访问网络了,如图16-14所示。

再次尝试访问网站

图16-14 客户端主机借助于透明代理技术成功访问网络

现在肯定有读者在想,如果开启了SNAT功能,数据不就直接被转发到外网了么?内网中的客户端主机是否还依然使用Squid服务程序提供的代理服务呢?其实,只要仔细看一下iptables防火墙命令就会发现,刘遄老师刚才并不是单纯地开启了SNAT功能,而是通过把客户端主机访问外网80端口的请求转发到Squid服务器的3128端口号上,从而还是强制客户端主机必须通过Squid服务程序来上网。为了验证这个说法,我们编辑Squid服务程序的配置文件,单独禁止本书的配套站点(https://www.linuxprobe.com/),然后再次刷新客户端主机的浏览器,发现网页又被禁止显示了,如图16-15所示。

16.3 正向代理 - 图12

图16-15 客户端主机再次无法访问网络