TrumanWong

Squid透明代理搭建及配置详解

TrumanWong
8/31/2023

简介

代理服务器Proxy Server的主要功能就是代理网络用户去取得网络信息,网络信息则是通过代理服务器进行中转的。代理服务器是介于浏览器和Web服务器之间的一台服务器,是以HTTP协议为基础的、建立在TCP/IP协议应用层上的一种服务软件。其工作过程可以概括为4步:

  1. 客户端向服务器发送的请求到达代理服务器。
  2. 代理服务器把请求转发给客户端真正需要联系的服务器。
  3. 服务器向代理服务器返回响应。
  4. 代理服务器把响应返回给客户端。

Squid是一个高性能的缓存代理服务器,支持HTTPHTTPSFTP等协议。通过使用缓存代理缓存和重用经常访问的web页面,可以节约带宽和提高服务响应。Squid具有权限管理灵活、性能好以及网络加速能力。Squid提供了多种操作系统版本,并使用GPL协议发布。

Squid Server安装

Ubuntu

$ sudo apt install squid

CentOS

$ sudo yum install squid

访问控制元素

ACL元素是Squid的访问控制的基础。这里告诉你如何指定包括IP地址,端口号,主机名,和URL匹配等变量。每个ACL元素有个名字,在编写访问控制规则时需要引用它们。基本的ACL元素语法如下:

acl name type value1 value2 ...

例如:

acl localnet src 10.0.0.0/8

在多数情况下,可以对一个ACL元素列举多个值。也可以有多个ACL行使用同一个名字。例如,下列两个配置是等价的:

acl Http_ports port 80 8000 8080

acl Http_ports port 80
acl Http_ports port 8000
acl Http_ports port 8080

一些基本的ACL类型

Squid大约有25个不同的ACL类型,其中的一些有通用基本类型。例如,srcdstACL使用IP地址作为它们的基本类型。为避免冗长,这里主要讲一些常用的基本类型:

src

IP地址在访问控制元素里是最普遍使用的。可以使用IP地址来控制客户允许或不允许访问Squidsrc类型指客户源IP地址。例如,假如你的单位使用172.17.0.0子网,你可以这样指定ACL:

acl MyNetwork src 172.17.0.0

假如你有许多子网,你能在同一个acl行里面列举它们:

acl MyNetwork src 172.17.0.0 10.0.1.0/24 10.0.5.0/24 172.16.0.0/12

dst

dst类型指向原始服务器(目标)IP地址。在某些情况下,你能使用该类型来阻止你的用户访问特定web站点。例如:

GET http://www.web-cache.com/ HTTP/1.0

这里,www.web-cache.com是主机名。当访问列表规则包含了dst元素时,squid必须找到该主机名的IP地址。假如SquidIP缓存包含了该主机名的有效接口,这条ACL被立即检测。否则,在DNS查询忙碌时,Squid会延缓处理该请求。这对某些请求来说会造成延时。为了避免延时,你该尽可能地使用dstdomain ACL类型来代替dst

如下是简单的dst ACL示例:

acl AdServers dst 1.2.3.0/24

请注意,dst ACL存在的问题是,你试图允许或拒绝访问的原始服务器可能会改变它的IP地址。假如你不关心这样的改变,那就不必麻烦去更新squid.conf配置文件。你可以在acl行里放上主机名,但那样会延缓启动速度。假如你的ACL需要许多主机名,你也许该预处理配置文件,将主机名转换成IP地址。

myip

myip类型指Squid的IP地址,它被客户连接。大部分Squid安装不使用该类型。通常所有的客户连接到同一个IP地址,所以该ACL元素仅仅当系统有多个IP地址时才有用。

dstdomain

检查请求url里的主机名。可以使用基于域名的访问控制去阻塞对某些站点的访问,去控制Squid如何转发请求,以及让某些响应不可缓存。例如:

acl A dst www.squid-cache.org
acl B dstdomain www.squid-cache.org

A实际上是IP地址ACL。当Squid解析配置文件时,它查询www.squid-cache.orgIP地址,并将它们存在内存里。它不保存名字。假如在Squid运行时IP地址改变了,Squid会继续使用旧的地址。

然而dstdomain ACL以域名形式存储,并非IP地址。当Squid检查ACL B时,它对URL的主机名部分使用字符串比较功能。在该情形下,它并不真正关心是否www.squid-cache.org的IP地址改变了。

srcdomain

客户机所在域。它要求对每个客户IP地址进行所谓的反向DNS查询。

port

port ACL允许定义单独的端口或端口范围。使用port ACL来限制对某些目标服务器端口号的访问。默认的squid.conf包含了下面的安全端口ACL:

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

myport

port ACL指向原始服务器的端口号,myport指向Squid自己的端口号,用以接受客户请求。假如你在http_port指令里指定不止一个端口号,那么squid就可以在不同的端口上侦听。

假如你将Squid作为站点HTTP加速器和用户代理服务器,那么myport ACL特别有用。你可以在80端口上接受加速请求,在3128端口上接受代理请求。你可能想让所有人访问加速器,但仅仅你自己的用户能以代理形式访问Squid。你的ACL可能如下:

acl AccelPort myport 80
acl ProxyPort myport 3128
acl MyNet src 172.16.0.0/22
http_access allow AccelPort         # anyone
http_access allow ProxyPort MyNet   # only my users
http_access deny ProxyPort          # deny others

method

method ACLHTTP请求方法(包括GETPOSTPUT等)。例如:

acl Uploads method PUT POST

proto

该类型指明URI访问(或传输)协议。支持httphttpsftpgopherurnwhoiscache_object。如果你想拒绝所有ftp请求,可以使用如下指令:

acl FTP proto FTP
http_access deny FTP

cache_object机制是squid的特性。它用于访问squid的缓存管理接口。

time

time ACL允许控制基于时间(每天中的具体时间,和每周中的每天)的访问。日期以单个字母来表示,如下表所示。时间以24小时制来表示。开始时间必须小于结束时间。

Code Day
S Sunday
M Monday
T Tuesday
W Wednesday
H Thursday
F Friday
A Saturday
D All weekdays (M-F)

为了编写time ACL来匹配你的工作时间,你可以这样写:

acl Working_hours MTWHF 09:00-18:00
或
acl Working_hours D 09:00-18:00

假如你需要设置20:00到凌晨04:00这段时间允许访问,由于开始时间必须大于结束时间,因此你不能编写20:00-04:00。你需要将它们分成两个ACL来写。例如:

acl Offpeak1 20:00-23:59
acl Offpeak2 00:00-04:00
http_access allow Offpeak1 ...
http_access allow Offpeak2 ...

proxy_auth

通过外部程序进行用户认证。Squid当前支持三种技术以接受用户验证:HTTP基本协议,数字认证协议,和NTLM

proxy_auth ACL取用户名作为值。然而,大部分安装里简单的使用特殊值REQUIRED:

auth_param ...
acl Auth1 proxy_auth REQUIRED

在该情况中,任何具有有效信用选项的请求会匹配该ACL。假如你需要细化控制,你可以指定独立的用户名:

auth_param ...
acl Auth1 proxy_auth username1 username2 username3
acl Auth2 proxy_auth username4 username5 username6

访问控制实战

限制指定IP使用代理

编辑/etc/squid.conf,加入如下配置:

# 定义授权组
acl access_ip src 172.17.0.0/16 172.18.118.128
# 允许授权组
http_access allow access_ip
# 拒绝其它所有未定义的
http_access deny all

验证:

$ curl --proxy http://yourip:port https://api.openai.com

限制使用用户名和密码访问代理

生成Squid代理身份验证密码

使用htpasswd生成代理用户身份验证密码:

# 如果没有安装htpasswd,需要先安装httpd/apache2-utils
# Ubuntu
$ sudo apt install apache2-utils
# CentOS
$ sudo yum install httpd-tools

$ htpasswd -c /etc/squid/.squid_users proxy_user
New password: 
Re-type new password: 
Adding password for user proxy_user

# 验证用户名和密码是否适用于squid代理。对于每一个正确的条目,您应该看到如下所示显示:OK
$ /usr/lib64/squid/basic_ncsa_auth /etc/squid/.squid_users 
proxy_user password
OK

配置Squid代理身份验证

编辑/etc/squid.conf,加入如下配置:

# 使用basic_ncsa_auth程序,并在文件中查找用户名和密码。
auth_param basic program /usr/lib64/squid/basic_ncsa_auth /etc/squid/.squid_users
# 指定要向客户报告身份验证方案的保护范围
auth_param basic realm Squid proxy-caching web server
# 24小时后,将再次询问用户/密码
auth_param basic credentialsttl 24 hours
# 不区分用户名大小写
auth_param basic casesensitive off
# 为允许身份验证的用户定义Squid身份验证 ACL。
acl authenticated proxy_auth proxy_user
# 允许授权组
http_access allow authenticated
# 拒绝其它所有未定义的
http_access deny all

完成配置后,保存文件并重新启动Squid

$ sudo systemctl restart squid

验证:

$ curl --proxy http://proxy_user:password@yourip:port https://api.openai.com