Debian Squid 代理与反向代理:ACL、3128 端口与验证
1. 服务介绍
Squid 是 Linux 上常用的 HTTP/HTTPS 代理服务,主要有两类用途:正向代理让客户端通过统一出口访问外部 Web,并实施来源、域名和端口控制;反向代理接收外部请求,再转发到后端 Web 服务,可用于统一入口、缓存和后端隐藏。
正向代理和反向代理的请求方向、监听端口、ACL 和验证方式不同。本文分别给出安全的正向代理配置,以及基于 cache_peer 的简单反向代理配置;两种模式不要在生产环境中混用,也不要直接使用无来源限制的 http_access allow all,避免形成开放代理。
2. 准备运行环境
• 操作系统:Debian 系 Linux;示例命令按 Debian 10 软件包布局编写。
• 操作权限:root 或具备 sudo 权限的管理员账号。
• 正向代理:准备客户端网段,例如 192.0.2.0/24,只允许该网段访问代理。
• 反向代理:准备 Squid 入口地址、后端 Web 地址和后端端口,例如 192.0.2.171:9090。
• 网络:防火墙和安全组按模式放行 TCP 3128,反向代理按实际需要放行 TCP 80/443。
• DNS:客户端能解析目标域名;反向代理使用虚拟主机时,客户端发送的 Host 头必须与配置匹配。
• 操作建议:修改 /etc/squid/squid.conf 前备份;先执行 squid -k parse,再 reload 或 restart。
3. 相关知识
• Squid 正向代理通常监听 TCP 3128。客户端通过 http_proxy、https_proxy 或浏览器代理设置使用它。
• acl 定义来源、目标地址、端口或域名;http_access 按从上到下顺序匹配。最后应保留 http_access deny all,防止未匹配流量通过。
• HTTPS 正向代理通常使用 CONNECT。必须限制 Safe_ports 和 SSL_ports,否则客户端可能借代理访问任意端口。
• cache_peer 用于定义上级缓存或后端服务器。反向代理通常配合 originserver、accel 和 vhost 使用。
• cache_mem 只控制内存对象缓存,不等于总内存占用;cache_dir 控制磁盘缓存。修改缓存大小前先评估磁盘、内存和访问模式。
• 代理配置生效要同时检查 Squid 监听端口、客户端代理设置、ACL 命中、访问日志和目标站点响应;只看到端口监听不能证明代理链路正常。
4. 实验步骤
4.1 安装并检查 Squid
bash
apt update
apt -y install squid
squid -v
systemctl enable --now squid
systemctl --no-pager --full status squid
备份默认配置:
bash
cp -a /etc/squid/squid.conf /etc/squid/squid.conf.bak.$(date +%Y%m%d%H%M%S)
4.2 配置安全的正向代理
编辑 /etc/squid/squid.conf,保留必要的默认 ACL,并加入以下核心规则。把 192.0.2.0/24 替换为实际客户端网段:
conf
http_port 3128
acl localnet src 192.0.2.0/24
acl SSL_ports port 443
acl Safe_ports port 80
acl Safe_ports port 21
acl Safe_ports port 443
acl Safe_ports port 70
acl Safe_ports port 210
acl Safe_ports port 1025-65535
acl CONNECT method CONNECT
http_access deny !Safe_ports
http_access deny CONNECT !SSL_ports
http_access allow localnet
http_access deny all
配置原则:
• localnet 只允许指定客户端网段。
• Safe_ports 限制普通 HTTP 请求目标端口。
• CONNECT 只允许连接 SSL_ports,防止代理被用于连接任意内部或管理端口。
• http_access deny all 必须位于允许规则之后。
检查并加载配置:
bash
squid -k parse
systemctl reload squid
ss -lntp | grep -E ':3128\b'
4.3 正向代理客户端测试
在客户端临时设置代理变量:
bash
export http_proxy=http://192.0.2.150:3128
export https_proxy=http://192.0.2.150:3128
curl -I http://example.com
curl -I https://example.com
unset http_proxy https_proxy
也可以显式指定代理,避免影响当前 Shell:
bash
curl -x http://192.0.2.150:3128 -I https://example.com
服务端查看访问日志:
bash
tail -f /var/log/squid/access.log
日志中应能看到客户端地址、请求方法、目标域名、状态码和字节数。若出现 TCP_DENIED,按 ACL 顺序检查来源网段、目标端口和 CONNECT 规则。
4.4 配置简单反向代理
反向代理与正向代理使用不同配置逻辑。以下示例让 Squid 监听 TCP 80,把带指定 Host 的请求转发到后端 192.0.2.171:9090:
conf
http_port 80 accel vhost
acl web_host dstdomain web.example.com
cache_peer 192.0.2.171 parent 9090 0 no-query originserver name=web_backend
cache_peer_access web_backend allow web_host
cache_peer_access web_backend deny all
never_direct allow web_host
http_access allow web_host
http_access deny all
说明:
• accel 表示加速/反向代理模式,vhost 根据 Host 头区分虚拟主机。
• cache_peer 的地址和端口必须是后端 Web 服务真实监听地址;不能把后端端口误写成 Squid 端口。
• dstdomain、cache_peer_access 和 http_access 共同限制请求范围。
• 反向代理正式使用前要确认后端应用能处理 Host、X-Forwarded-For 和 HTTPS 终止方式。
检查并加载反向代理配置:
bash
squid -k parse
systemctl reload squid
ss -lntp | grep -E ':80\b'
如果同一台机器同时提供正向和反向代理,必须使用不同监听端口并分别设计 ACL;更复杂的多域名场景应单独维护配置文件。
4.5 缓存参数检查
默认配置中常见缓存参数包括:
conf
cache_mem 256 MB
cache_dir ufs /var/spool/squid 100 16 256
cache_swap_low 90
cache_swap_high 95
这些参数需要结合内存和磁盘容量调整。修改后检查缓存目录权限和磁盘空间:
bash
df -h /var/spool/squid
ls -ld /var/spool/squid
squid -z
没有明确缓存需求时,不要盲目增大 cache_mem;动态站点和 HTTPS 流量也不一定适合缓存。
5. 验证结果
5.1 服务和配置验证
bash
squid -k parse
systemctl is-active squid
systemctl --failed
journalctl -u squid -n 80 --no-pager
预期结果:配置检查无 error;Squid 状态为 active;日志没有持续启动失败或权限错误。
5.2 端口验证
bash
ss -lntp | grep -E ':(80|3128)\b'
正向代理应监听 3128;反向代理按配置监听 80 或 443。客户端访问错误端口时,Squid 日志不会出现预期请求。
5.3 正向代理验证
bash
curl -x http://127.0.0.1:3128 -I http://example.com
curl -x http://127.0.0.1:3128 -I https://example.com
grep -E 'TCP_(HIT|MISS|TUNNEL|DENIED)' /var/log/squid/access.log | tail -n 20
能看到目标 HTTP 状态和 TCP_MISS、TCP_TUNNEL 等记录,说明客户端请求进入 Squid;TCP_DENIED 说明请求被 ACL 拒绝,需要按规则排查。
5.4 反向代理验证
bash
curl -i -H 'Host: web.example.com' http://127.0.0.1/
curl -i http://192.0.2.171:9090/
tail -n 80 /var/log/squid/access.log
比较直接访问后端和通过 Squid 访问的状态码、响应头和页面内容。若反向代理返回 403、503 或空响应,检查 Host ACL、后端连通性和后端服务日志。
5.5 连通性和抓包验证
bash
ip addr
ip route
nc -vz 192.0.2.171 9090
tcpdump -ni any 'tcp port 3128 or tcp port 80 or tcp port 9090'
抓包可区分客户端到 Squid、Squid 到后端两个链路。只有第一段有流量,通常表示后端地址、端口或防火墙配置有问题。
6. 常见问题
6.1 `http_access allow all` 导致开放代理
不要使用无来源限制的 allow all。改为允许明确客户端网段,并保留最后的 deny all。修改后用非授权客户端测试,确认请求被拒绝。
6.2 客户端访问被 `TCP_DENIED`
查看 access.log,检查 ACL 定义、规则顺序、来源网段、目标端口和 CONNECT 方法。Squid 按顺序匹配,前面的 deny 可能在 allow 之前生效。
6.3 正向代理能连 HTTP,不能连 HTTPS
检查客户端是否使用 https_proxy=http://代理地址:3128,不要把代理协议误写成目标站点协议;再检查 CONNECT、SSL_ports 和防火墙规则。
6.4 反向代理返回 503
检查 cache_peer 后端地址、端口和路由:
bash
nc -vz 192.0.2.171 9090
curl -i http://192.0.2.171:9090/
journalctl -u squid -n 100 --no-pager
6.5 同一后端存在多个端口
为每个后端端口定义独立的 cache_peer 和访问规则,或使用不同入口域名映射到不同后端。不要把一个 cache_peer 同时当作多个端口使用,也不要用错误的 DNS 记录掩盖端口配置问题。
6.6 缓存目录或权限错误
确认目录存在、属主正确、磁盘空间足够,并执行:
bash
squid -z
ls -ld /var/spool/squid
6.7 配置修改后服务启动失败
先回退到备份,再逐段恢复配置:
bash
squid -k parse
systemctl status squid --no-pager
journalctl -u squid -n 100 --no-pager