Squid 完全指南 / 04 - 正向代理
第四章:正向代理
4.1 正向代理概述
正向代理(Forward Proxy)是 Squid 最经典的应用场景。客户端将请求发送给代理,由代理代替客户端向目标服务器发起请求,并将响应返回给客户端。
┌──────────────┐ ┌─────────────────┐ ┌──────────────┐
│ 客户端 │──────→│ Squid 正向代理 │──────→│ 目标服务器 │
│ (浏览器) │←──────│ 3128 端口 │←──────│ (互联网) │
│ │ │ ACL + 认证 │ │ │
│ 代理设置: │ │ 缓存 + 日志 │ │ │
│ proxy:3128 │ │ 内容过滤 │ │ │
└──────────────┘ └─────────────────┘ └──────────────┘
4.2 基础正向代理配置
4.2.1 最小配置
# /etc/squid/squid.conf — 基础正向代理
# 监听端口
http_port 3128
# 基础 ACL
acl localnet src 192.168.1.0/24
acl SSL_ports port 443
acl Safe_ports port 80 443 21 70 8080
# 访问控制
http_access deny !Safe_ports
http_access deny CONNECT !SSL_ports
http_access allow localhost
http_access allow localnet
http_access deny all
# 日志
access_log /var/log/squid/access.log squid
cache_log /var/log/squid/cache.log
# 缓存
cache_dir ufs /var/spool/squid 1000 16 256
cache_mem 256 MB
# 主机名
visible_hostname proxy.example.com
4.2.2 多网段配置
# 定义多个内网段
acl office_net src 192.168.1.0/24
acl dev_net src 10.0.0.0/24
acl guest_net src 172.16.0.0/24
acl management src 192.168.100.10 192.168.100.11
# 分层访问控制
http_access allow management
http_access allow office_net
http_access allow dev_net
http_access deny guest_net !Safe_ports
http_access allow guest_net
http_access deny all
4.2.3 监听多个端口
# 标准 HTTP 代理
http_port 3128
# 透明代理端口(配合 iptables REDIRECT)
http_port 3129 intercept
# HTTPS 拦截端口(SSL Bump)
http_port 3130 ssl-bump \
generate-host-certificates=on \
dynamic_cert_mem_cache_size=20MB \
cert=/etc/squid/ssl/myCA.pem \
key=/etc/squid/ssl/myCA.key
4.3 客户端配置
4.3.1 浏览器手动配置
Firefox:
- 设置 → 网络设置 → 手动代理配置
- HTTP 代理:
192.168.1.1,端口:3128 - 勾选「为所有协议使用相同代理」
Chrome(通过系统设置):
- 设置 → 网络 → 代理 → 手动设置代理
- HTTP 代理:
192.168.1.1,端口:3128
4.3.2 通过 PAC 文件自动配置
创建 PAC (Proxy Auto-Config) 文件:
// /var/www/html/proxy.pac
function FindProxyForURL(url, host) {
// 本地地址直连
if (isPlainHostName(host) ||
dnsDomainIs(host, ".local") ||
isInNet(host, "192.168.0.0", "255.255.0.0") ||
isInNet(host, "10.0.0.0", "255.0.0.0")) {
return "DIRECT";
}
// 特定域名走特定代理
if (dnsDomainIs(host, ".example.com")) {
return "PROXY proxy1.example.com:3128; PROXY proxy2.example.com:3128";
}
// 其他流量走默认代理
return "PROXY proxy.example.com:3128; DIRECT";
}
在 Squid 配置中提供 PAC 文件:
# 通过 Squid 自身提供 PAC 文件
# 将 proxy.pac 放在可访问的 Web 服务器上
# 浏览器配置自动代理 URL: http://proxy.example.com/proxy.pac
4.3.3 WPAD 自动发现
# WPAD (Web Proxy Auto-Discovery) 需要 DNS 或 DHCP 配置
# DNS 方式:创建 wpad.example.com 记录指向 Web 服务器
# 在 Web 服务器上提供 /wpad.dat 文件(内容同 PAC 文件)
# DHCP 方式:在 DHCP 服务器中配置 option 252
# option 252 "http://wpad.example.com/wpad.dat"
4.3.4 系统级代理设置
# Linux 环境变量
export http_proxy=http://192.168.1.1:3128
export https_proxy=http://192.168.1.1:3128
export ftp_proxy=http://192.168.1.1:3128
export no_proxy=localhost,127.0.0.1,.local,.example.com
# 写入 ~/.bashrc 或 /etc/environment 持久化
# apt 代理配置
# /etc/apt/apt.conf.d/99proxy
# Acquire::http::Proxy "http://192.168.1.1:3128";
# Acquire::https::Proxy "http://192.168.1.1:3128";
# yum/dnf 代理配置
# /etc/dnf/dnf.conf
# proxy=http://192.168.1.1:3128
# proxy_username=user
# proxy_password=pass
4.4 透明代理 (Transparent Proxy)
4.4.1 配置透明代理端口
# 在 Squid 配置中添加 intercept 端口
http_port 3128 # 标准代理端口
http_port 3129 intercept # 透明代理端口(旧写法 transparent)
4.4.2 iptables 流量重定向
# 方法一:REDIRECT(同机部署)
# 将本机发出的 HTTP 流量重定向到 Squid
iptables -t nat -A OUTPUT -p tcp --dport 80 \
-m owner ! --uid-owner proxy \
-j REDIRECT --to-port 3129
# 方法二:DNAT(网关部署)
# 将内网到外网的 HTTP 流量重定向到 Squid
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 \
-j REDIRECT --to-port 3129
# 仅对特定子网生效
iptables -t nat -A PREROUTING -s 192.168.1.0/24 \
-p tcp --dport 80 \
-j REDIRECT --to-port 3129
# 保存规则
iptables-save > /etc/iptables.rules
4.4.3 nftables 流量重定向
# nftables 配置
nft add table inet squid_redirect
nft add chain inet squid_redirect prerouting \
{ type nat hook prerouting priority dstnat \; }
nft add rule inet squid_redirect prerouting \
ip saddr 192.168.1.0/24 tcp dport 80 \
redirect to :3129
# 持久化
nft list ruleset > /etc/nftables.conf
4.4.4 透明代理注意事项
| 问题 | 说明 | 解决方案 |
|---|---|---|
| HTTPS 不可透明代理 | 加密流量无法中间人拦截 | 需要 SSL Bump 或使用 PAC |
| 客户端绕过 | 修改 hosts 或使用 VPN | 结合 DNS 和出口策略 |
| 绕过 Squid 自身流量 | 防止 Squid 代理自己 | mangle 表排除 Squid 用户 |
| 流量回环 | Squid 流量再次被重定向 | 排除 proxy 用户/进程 |
4.5 认证集成
4.5.1 Basic 认证
# NCSA 密码文件认证
auth_param basic program /usr/lib/squid/basic_ncsa_auth /etc/squid/passwd
auth_param basic children 5 startup=2 idle=1
auth_param basic realm "Squid Proxy - Please enter your credentials"
auth_param basic credentialsttl 2 hours
# 创建密码文件
# htpasswd -c /etc/squid/passwd user1
# htpasswd /etc/squid/passwd user2
# 认证 ACL
acl authenticated proxy_auth REQUIRED
# 应用认证
http_access allow authenticated
http_access deny all
4.5.2 LDAP 认证
# LDAP 认证
auth_param basic program /usr/lib/squid/basic_ldap_auth \
-b "dc=example,dc=com" \
-D "cn=squid,ou=service,dc=example,dc=com" \
-W /etc/squid/ldap_pass.txt \
-f "(&(uid=%s)(objectClass=person))" \
-H ldap://ldap.example.com:389 \
-R
auth_param basic children 10 startup=3 idle=1
auth_param basic realm "Corporate Proxy"
auth_param basic credentialsttl 1 hour
acl ldap_auth proxy_auth REQUIRED
http_access allow ldap_auth
http_access deny all
4.5.3 基于用户组的 ACL
# LDAP 组验证
external_acl_type ldap_group %LOGIN /usr/lib/squid/ext_ldap_group_acl \
-b "ou=groups,dc=example,dc=com" \
-D "cn=squid,ou=service,dc=example,dc=com" \
-W /etc/squid/ldap_pass.txt \
-f "(&(memberUid=%u)(cn=%g))" \
-H ldap://ldap.example.com
acl proxy_users external ldap_group proxy_users
acl admins external ldap_group admins
# 允许 proxy_users 使用基本代理
http_access allow proxy_users
# 允许 admins 访问所有站点
http_access allow admins
http_access deny all
4.6 ACL 高级控制
4.6.1 按目标域名控制
# 禁止访问特定域名
acl blocked_domains dstdomain "/etc/squid/blocked_domains.txt"
http_access deny blocked_domains
# /etc/squid/blocked_domains.txt 内容:
# .facebook.com
# .twitter.com
# .tiktok.com
# .gambling-site.com
# 仅允许访问白名单域名(白名单模式)
acl allowed_domains dstdomain "/etc/squid/allowed_domains.txt"
http_access deny !allowed_domains
4.6.2 按 URL 路径控制
# 禁止访问特定 URL 路径
acl blocked_urls url_regex "/etc/squid/blocked_urls.txt"
http_access deny blocked_urls
# /etc/squid/blocked_urls.txt 内容:
# ^https?://.*\.exe$
# ^https?://.*\.torrent$
# ^https?://.*download.*\.zip$
# 限制下载文件大小
reply_body_max_size 50 MB allow all
4.6.3 按时间控制
# 工作时间(周一至周五 8:00-18:00)
acl work_hours time MTWHF 08:00-18:00
# 限制非工作时间的访问
http_access allow work_hours
http_access deny all
# 允许特定用户在任何时间访问
acl vip_user proxy_auth "admin"
http_access allow vip_user
http_access deny !work_hours
4.6.4 带宽控制 (Delay Pools)
# 定义延迟池
delay_pools 2
# 延迟池 1:限制普通用户的带宽(每秒 1MB)
delay_class 1 2
delay_parameters 1 1000000/500000 250000/125000
# 延迟池 2:VIP 用户不限速
delay_class 2 1
delay_parameters 2 -1/-1
# ACL 匹配
acl normal_users proxy_auth "/etc/squid/normal_users.txt"
acl vip_users proxy_auth "/etc/squid/vip_users.txt"
delay_access 1 allow normal_users
delay_access 2 allow vip_users
delay_access 1 deny all
delay_access 2 deny all
4.7 CONNECT 隧道(HTTPS 代理)
4.7.1 CONNECT 基础
# CONNECT 方法用于代理 HTTPS 和其他 SSL/TLS 连接
# 客户端发送: CONNECT www.google.com:443 HTTP/1.1
# Squid 建立到目标的 TCP 连接
# 之后客户端和目标直接通过隧道通信
# 允许 CONNECT 到标准 HTTPS 端口
acl SSL_ports port 443
acl CONNECT method CONNECT
http_access deny CONNECT !SSL_ports
4.7.2 限制 CONNECT 隧道
# 限制 CONNECT 仅允许认证用户
acl authenticated proxy_auth REQUIRED
http_access deny CONNECT !authenticated
# 限制 CONNECT 到特定域名
acl allowed_https dstdomain "/etc/squid/allowed_https.txt"
http_access deny CONNECT !allowed_https
# 限制 CONNECT 隧道的保持时间
connect_timeout 30 seconds
4.8 转发策略
4.8.1 直连与父代理
# 始终通过父代理转发(不做直连)
never_direct allow all
# 始终直连(不使用父代理)
always_direct allow all
# 基于目标域名选择转发策略
acl cdn_domains dstdomain .cdn.example.com
always_direct allow cdn_domains
never_direct allow all
# 定义父代理
cache_peer parent.proxy.example.com parent 3128 0 no-query default
4.8.2 多父代理故障转移
# 定义多个父代理
cache_peer parent1.example.com parent 3128 0 \
no-query default weight=10
cache_peer parent2.example.com parent 3128 0 \
no-query default weight=5
# 故障检测
cache_peer_access parent1 allow all
cache_peer_access parent2 allow all
# 连接超时和重试
connect_timeout 10 seconds
peer_connect_timeout 5 seconds
4.9 企业正向代理完整示例
# /etc/squid/squid.conf — 企业正向代理配置
# ============ 网络端口 ============
http_port 3128
# ============ ACL 定义 ============
# 网络段
acl office_net src 192.168.1.0/24
acl dev_net src 10.10.0.0/24
acl mgmt_net src 192.168.100.0/24
# 端口
acl SSL_ports port 443 8443
acl Safe_ports port 80 443 21 70 8080 8443
# 时间
acl work_hours time MTWHF 08:30-18:00
acl lunch_time time MTWHF 12:00-13:30
# 认证
auth_param basic program /usr/lib/squid/basic_ldap_auth \
-b "dc=example,dc=com" \
-D "cn=squid,ou=service,dc=example,dc=com" \
-W /etc/squid/ldap_pass.txt \
-f "(uid=%s)" \
-H ldap://192.168.1.10
auth_param basic children 10
auth_param basic realm "Company Proxy"
auth_param basic credentialsttl 2 hours
acl authenticated proxy_auth REQUIRED
# URL 过滤
acl blocked_sites dstdomain "/etc/squid/blocked_sites.txt"
acl blocked_urls url_regex "/etc/squid/blocked_urls.txt"
acl streaming_sites dstdomain .youtube.com .netflix.com .bilibili.com
# 文件类型
acl download_ext url_regex -i "\.(exe|msi|bat|ps1|vbs|scr)$"
# ============ 访问控制 ============
# 基础安全
http_access deny !Safe_ports
http_access deny CONNECT !SSL_ports
# 允许管理网段免认证
http_access allow mgmt_net
# 要求认证
http_access deny !authenticated
# 内容过滤
http_access deny blocked_sites
http_access deny blocked_urls
http_access deny download_ext
# 流量限制(工作时间限制流媒体)
http_access deny streaming_sites !lunch_time
# 允许所有已认证流量
http_access allow office_net
http_access allow dev_net
# 默认拒绝
http_access deny all
# ============ 带宽控制 ============
delay_pools 2
delay_class 1 2
delay_parameters 1 1000000/500000 500000/250000
delay_class 2 1
delay_parameters 2 -1/-1
acl normal_users proxy_auth "/etc/squid/normal_users.txt"
acl vip_users proxy_auth "/etc/squid/vip_users.txt"
delay_access 1 allow normal_users
delay_access 2 allow vip_users
# ============ 缓存配置 ============
cache_dir ufs /var/spool/squid 10000 16 256
cache_mem 1024 MB
maximum_object_size 128 MB
maximum_object_size_in_memory 512 KB
cache_replacement_policy heap GDSF
memory_replacement_policy heap GDSF
# ============ 日志配置 ============
access_log /var/log/squid/access.log squid
cache_log /var/log/squid/cache.log
cache_store_log stdio:/var/log/squid/store.log
log_fqdn on
log_mime_hdrs on
# ============ 性能参数 ============
forwarded_for delete
via off
httpd_suppress_version_string on
client_db off
pipeline_prefetch on
# ============ 错误页面 ============
error_directory /usr/share/squid/errors/zh-cn
visible_hostname proxy.example.com
4.10 故障排查
# 检查配置语法
sudo squid -k parse
# 查看活跃连接
squidclient -h localhost mgr:active_requests
# 查看缓存信息
squidclient -h localhost mgr:info
# 查看客户端连接
squidclient -h localhost mgr:client_list
# 实时监控日志
tail -f /var/log/squid/access.log
# 查看连接数统计
squidclient -h localhost mgr:5min
4.11 本章小结
| 功能 | 配置要点 |
|---|---|
| 基础代理 | http_port + http_access |
| 透明代理 | http_port intercept + iptables |
| PAC 自动配置 | JavaScript PAC 文件 + 浏览器设置 |
| 认证 | auth_param basic + proxy_auth |
| ACL 控制 | 域名/URL/时间/用户组 |
| 带宽限制 | delay_pools + delay_parameters |
| 转发策略 | never_direct / always_direct + cache_peer |