强曰为道
与天地相似,故不违。知周乎万物,而道济天下,故不过。旁行而不流,乐天知命,故不忧.
文档目录

Squid 完全指南 / 07 - 访问控制 (ACL)

第七章:访问控制 (ACL)

7.1 ACL 概述

ACL(Access Control List,访问控制列表)是 Squid 安全模型的核心。通过 ACL,可以精确控制谁(Who)、在什么时间(When)、访问什么内容(What),以及如何处理(How)。

请求到达
    │
    ▼
┌───────────────────────┐
│    http_access 规则    │
│    按顺序逐条匹配       │
│                        │
│  规则1: allow/deny     │
│  规则2: allow/deny     │
│  ...                   │
│  最后: deny all        │ ← 默认拒绝
└───────────────────────┘

重要:Squid 的 ACL 规则按顺序匹配,第一条匹配的规则生效。理解这一点对编写正确的 ACL 至关重要。

7.2 ACL 类型一览

ACL 类型语法说明
srcsrc IP/mask源 IP 地址
dstdst IP/mask目标 IP 地址
dstdomaindstdomain .example.com目标域名
dstdom_regexdstdom_regex -i ^www\.域名正则
url_regexurl_regex -i \.exe$URL 正则
urlpath_regexurlpath_regex -i /admin/URL 路径正则
portport 443目标端口
myportmyport 3128本地监听端口
protoproto HTTP协议
methodmethod GETHTTP 方法
timetime MTWHF 08:00-18:00时间段
proxy_authproxy_auth REQUIRED认证用户
maxconnmaxconn 50最大连接数
max_user_ipmax_user_ip 3用户最大 IP 数
browserbrowser Chrome浏览器 User-Agent
referer_regexreferer_regex -i example.comReferer 头
req_headerreq_header X-Custom ^value请求头匹配
rep_headerrep_header Content-Type text/html响应头匹配
rep_mime_typerep_mime_type text/html响应 MIME 类型
externalexternal my_acl外部 ACL helper
notenote key value事务注解

7.3 基础 ACL 示例

7.3.1 基于源 IP

# 单个 IP
acl admin src 192.168.1.100

# 子网
acl office_net src 192.168.1.0/24
acl dev_net src 10.10.0.0/16

# 多个 IP/CIDR
acl management src 192.168.1.10 192.168.1.11 192.168.1.12

# 从文件加载
acl vip_ips src "/etc/squid/vip_ips.txt"

# IPv6
acl ipv6_net src fc00::/7

IP 文件格式(每行一个):

# /etc/squid/vip_ips.txt
192.168.1.100
192.168.1.101
10.0.0.0/24
# 注释行会被忽略

7.3.2 基于目标地址

# 域名(带点号前缀匹配所有子域名)
acl google dstdomain .google.com
acl github dstdomain .github.com

# 精确域名
acl mysite dstdomain www.example.com

# 从文件加载
acl allowed_domains dstdomain "/etc/squid/allowed_domains.txt"
acl blocked_domains dstdomain "/etc/squid/blocked_domains.txt"

# 域名正则
acl email_site dstdom_regex -i "mail|webmail|outlook"

7.3.3 基于 URL

# URL 正则匹配(完整 URL)
acl download_url url_regex -i "\.(exe|msi|bat|ps1|sh|apk)$"
acl torrent_url url_regex -i "\.torrent$"

# URL 路径匹配(仅路径部分)
acl admin_path urlpath_regex -i "^/admin/"
acl api_path urlpath_regex -i "^/api/"

# 从文件加载
acl blocked_urls url_regex -i "/etc/squid/blocked_urls.txt"

7.3.4 基于端口和协议

# 安全端口白名单
acl Safe_ports port 80 443 21 70 8080 8443
acl SSL_ports port 443 8443

# 连接方法
acl CONNECT method CONNECT

# 协议
acl HTTP proto HTTP
acl HTTPS proto HTTPS
acl FTP proto FTP

7.3.5 基于时间

# 工作日工作时间
acl work_hours time MTWHF 08:00-18:00

# 午休时间
acl lunch_break time MTWHF 12:00-13:30

# 周末
acl weekend time AS

# 具体日期范围(Squid 不直接支持,需要外部 ACL)
# 时间语法:
# S = Sunday, M = Monday, T = Tuesday, W = Wednesday
# H = Thursday, F = Friday, A = Saturday
# D = All days (Mon-Fri)

7.4 http_access 规则

7.4.1 规则匹配流程

# 规则按顺序匹配,第一条匹配的生效
# 推荐的规则顺序:

# 1. 基础安全检查
http_access deny !Safe_ports
http_access deny CONNECT !SSL_ports

# 2. 允许本地管理
http_access allow localhost
http_access allow admin

# 3. 要求认证
http_access deny !authenticated

# 4. 内容过滤
http_access deny blocked_domains
http_access deny blocked_urls

# 5. 时间限制
http_access deny !work_hours

# 6. 允许已认证用户
http_access allow authenticated

# 7. 默认拒绝
http_access deny all

7.4.2 ACL 逻辑组合

# AND 逻辑(在同一规则中使用多个 ACL)
# 允许 office_net 在 work_hours 访问
http_access allow office_net work_hours

# 否定(使用 ! 前缀)
http_access deny !authenticated

# 复杂组合
# 允许认证用户在工作时间访问非封锁域名
http_access allow authenticated work_hours !blocked_domains

# 允许管理组在任何时间访问任何内容
http_access allow admin_group

7.4.3 完整访问控制示例

# ========== ACL 定义 ==========

# 网络
acl localnet src 192.168.0.0/16
acl guest_net src 172.16.0.0/12

# 端口
acl Safe_ports port 80 443 21 70 8080 8443 1025-65535
acl SSL_ports port 443 8443

# 方法
acl CONNECT method CONNECT
acl POST method POST

# 时间
acl work_hours time MTWHF 08:00-18:00
acl off_hours time MTWHF 18:00-08:00
acl weekend time AS

# 认证
acl authenticated proxy_auth REQUIRED
acl admins proxy_auth admin1 admin2 admin3

# 过滤
acl blocked_sites dstdomain "/etc/squid/blocked.txt"
acl malware_urls url_regex -i "/etc/squid/malware.txt"
acl download_ext url_regex -i "\.(exe|msi|bat|apk|torrent)$"

# 连接限制
acl max_conn maxconn 100
acl max_user_conn maxconn 30

# ========== 规则 ==========

# 基础安全
http_access deny !Safe_ports
http_access deny CONNECT !SSL_ports

# 连接限制
http_access deny max_conn

# 管理员(免认证,任何时间)
http_access allow admins

# 认证
http_access deny !authenticated

# 安全过滤
http_access deny malware_urls
http_access deny blocked_sites

# 下载控制
http_access deny download_ext

# 带宽限制时间
http_access deny guest_net !work_hours !weekend

# 允许本地网络
http_access allow localnet
http_access allow guest_net

# 默认拒绝
http_access deny all

7.5 高级 ACL 技巧

7.5.1 基于 HTTP 头的 ACL

# User-Agent 过滤
acl bad_bot browser -i "SemrushBot|AhrefsBot|MJ12bot"
http_access deny bad_bot

# Referer 检查
acl hotlink referer_regex -i "^https?://(?!www\.example\.com)"
# 可用于防盗链(需配合 rep_header 或 url_rewrite)

# 自定义请求头
acl mobile_app req_header X-App-Version "^2\."

7.5.2 基于连接数的 ACL

# 单 IP 最大连接数
acl max_conn_per_ip maxconn 20
http_access deny max_conn_per_ip

# 单用户最大连接数(需认证)
acl max_user_conn maxconn 15
http_access deny max_user_conn

# 最大用户 IP 数(防账号共享)
acl max_user_ip max_user_ip 3
http_access deny max_user_ip

7.5.3 基于响应类型的 ACL

# 按 MIME 类型
acl flash_content rep_mime_type application/x-shockwave-flash
acl video_content rep_mime_type video/

# 按响应大小(reply_body_max_size)
reply_body_max_size 100 MB allow all

# 按响应码
# (Squid 不直接支持按响应码做 ACL,需要外部 helper)

7.5.4 文件列表 ACL

# 使用外部文件定义 ACL 列表

# IP 列表
acl whitelist src "/etc/squid/whitelist_ips.txt"
acl blacklist src "/etc/squid/blacklist_ips.txt"

# 域名列表
acl allowed_domains dstdomain "/etc/squid/allowed_domains.txt"
acl blocked_domains dstdomain "/etc/squid/blocked_domains.txt"

# URL 列表
acl blocked_urls url_regex -i "/etc/squid/blocked_urls.txt"

# 用户列表
acl vip_users proxy_auth "/etc/squid/vip_users.txt"

文件格式

# 域名列表文件格式
# 每行一个域名,带点号前缀匹配所有子域名
.example.com
.google.com
.github.com
# 精确匹配不带前导点号
www.specific-site.com

7.6 URL 过滤

7.6.1 基于域名的过滤

# 黑名单模式(禁止特定域名)
acl blocked dstdomain "/etc/squid/blacklist.txt"
http_access deny blocked

# 白名单模式(仅允许特定域名)
acl allowed dstdomain "/etc/squid/whitelist.txt"
http_access deny !allowed

7.6.2 基于关键词的过滤

# URL 关键词过滤
acl gambling url_regex -i "gambling|casino|poker|betting"
acl porn url_regex -i "porn|xxx|adult|sex"
acl violence url_regex -i "violence|weapon|gun"

http_access deny gambling
http_access deny porn
http_access deny violence

7.6.3 正则表达式模式

# 过滤可执行文件下载
acl exe_download url_regex -i "\.(exe|msi|bat|cmd|ps1|vbs|scr|com|pif)$"
http_access deny exe_download

# 过滤特定端口的连接
acl non_standard_port url_regex ":\d{5,}"
http_access deny non_standard_port

# 过滤 IP 地址形式的 URL(直接访问 IP)
acl direct_ip url_regex "^[a-z]+://\d+\.\d+\.\d+\.\d+"
http_access deny direct_ip

7.6.4 使用 SquidGuard 或 ufdbGuard

对于大规模 URL 过滤,建议使用外部 URL 过滤器:

# SquidGuard URL 重写器
url_rewrite_program /usr/bin/squidguard -c /etc/squidguard/squidguard.conf
url_rewrite_children 10 startup=3 idle=2 concurrency=0

# 或使用 ufdbGuard(性能更好)
url_rewrite_program /usr/local/ufdbguard/bin/ufdbgclient -m block
url_rewrite_children 20 startup=5 idle=3 concurrency=1

7.7 ACL 调试

7.7.1 测试 ACL 匹配

# 使用 squidclient 测试
squidclient -h localhost -p 3128 http://example.com

# 查看 ACL 匹配日志(启用 debug)
squidclient -h localhost mgr:5min | grep acl

# 检查配置语法
sudo squid -k parse

# 在 cache.log 中查看 ACL 拒绝信息
grep "Access Denied" /var/log/squid/cache.log

7.7.2 ACL 性能优化

# 将最常匹配的规则放在前面
# 1. 先检查 IP(最快)
# 2. 再检查域名(较快)
# 3. 最后检查 URL 正则(较慢)

# 使用域名文件而非 URL 正则(域名匹配更快)
acl bad_site dstdomain "/etc/squid/bad_sites.txt"  # 快
# 而非
acl bad_site url_regex -i "example\.com"  # 慢

# 避免过多的正则规则
# 正则匹配是 CPU 密集型操作

7.8 企业 URL 过滤方案

# /etc/squid/squid.conf — 企业级 URL 过滤

# ============ 基础 ACL ============
acl Safe_ports port 80 443 21 70 8080 8443
acl SSL_ports port 443 8443
acl CONNECT method CONNECT

# ============ 网络 ACL ============
acl office src 192.168.0.0/16
acl guest src 172.16.0.0/12
acl mgmt src 10.0.0.0/24

# ============ 认证 ============
auth_param basic program /usr/lib/squid/basic_ncsa_auth /etc/squid/passwd
auth_param basic children 10
auth_param basic realm Proxy
acl auth proxy_auth REQUIRED

# ============ 安全过滤 ============
# 恶意软件/钓鱼
acl malware url_regex -i "/etc/squid/filter/malware.txt"
acl phishing url_regex -i "/etc/squid/filter/phishing.txt"

# 内容分类
acl gambling dstdomain "/etc/squid/filter/gambling.txt"
acl social_media dstdomain "/etc/squid/filter/social_media.txt"
acl streaming dstdomain "/etc/squid/filter/streaming.txt"
acl adult dstdomain "/etc/squid/filter/adult.txt"
acl weapons dstdomain "/etc/squid/filter/weapons.txt"

# 文件下载
acl risky_download url_regex -i "\.(exe|msi|bat|cmd|ps1|vbs|scr|apk)$"

# ============ 时间策略 ============
acl work_time time MTWHF 08:30-18:00

# ============ 访问控制规则 ============

# 基础安全
http_access deny !Safe_ports
http_access deny CONNECT !SSL_ports

# 管理员
http_access allow mgmt

# 认证
http_access deny !auth

# 恶意内容(始终拒绝)
http_access deny malware
http_access deny phishing
http_access deny adult
http_access deny weapons

# 高风险下载
http_access deny risky_download

# 工作时间限制(工作时间禁止社交媒体和流媒体)
http_access deny social_media work_time
http_access deny streaming work_time

# 赌博(始终拒绝)
http_access deny gambling

# 允许所有其他
http_access allow office
http_access allow guest

# 默认拒绝
http_access deny all

7.9 本章小结

功能关键 ACL
IP 控制src / dst
域名控制dstdomain / dstdom_regex
URL 控制url_regex / urlpath_regex
时间控制time
认证控制proxy_auth
连接控制maxconn / max_user_ip
内容过滤文件列表 + 正则
访问规则http_access allow/deny

扩展阅读