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 类型 | 语法 | 说明 |
|---|---|---|
src | src IP/mask | 源 IP 地址 |
dst | dst IP/mask | 目标 IP 地址 |
dstdomain | dstdomain .example.com | 目标域名 |
dstdom_regex | dstdom_regex -i ^www\. | 域名正则 |
url_regex | url_regex -i \.exe$ | URL 正则 |
urlpath_regex | urlpath_regex -i /admin/ | URL 路径正则 |
port | port 443 | 目标端口 |
myport | myport 3128 | 本地监听端口 |
proto | proto HTTP | 协议 |
method | method GET | HTTP 方法 |
time | time MTWHF 08:00-18:00 | 时间段 |
proxy_auth | proxy_auth REQUIRED | 认证用户 |
maxconn | maxconn 50 | 最大连接数 |
max_user_ip | max_user_ip 3 | 用户最大 IP 数 |
browser | browser Chrome | 浏览器 User-Agent |
referer_regex | referer_regex -i example.com | Referer 头 |
req_header | req_header X-Custom ^value | 请求头匹配 |
rep_header | rep_header Content-Type text/html | 响应头匹配 |
rep_mime_type | rep_mime_type text/html | 响应 MIME 类型 |
external | external my_acl | 外部 ACL helper |
note | note 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 |