Squid 代理服务器部署与使用完全指南:安装、三大场景配置、运维与排障
Squid 是 Linux 上最老牌、性能最稳的正向代理与缓存服务器,既可以给内网统一出口省带宽、加访问控制,也能当带用户名密码的跳板代理或透明代理。本文覆盖 CentOS/RHEL/Ubuntu 安装、squid.conf 核心指令(http_port/acl/http_access/cache_dir)、三大可直接复制的场景配置、运维与监控命令、以及常见报错(TCP_DENIED/503/407、缓存不生效、认证失败)的排障思路,所有配置都能直接抄。
Squid 代理服务器部署与使用完全指南:安装、三大场景配置、运维与排障
很多”内网统一出口”、“给服务器挂个代理去拉 GitHub 包”、“公司办公网加访问控制”这类需求,一上来就想自己写 Go/Node 转发程序或者拿 Nginx 硬撸。其实 Squid 作为 90 年代就存在的 C 语言项目,这些活它已经干了 30 年:ACL 细到按时间/域名关键词/方法/浏览器 UA、磁盘+内存双层缓存、支持用户名密码/NTLM/Kerberos 多种认证、还能做透明代理 TPROXY、HTTP 加速器(反向代理)。
唯一门槛就是 squid.conf 那个配置语法有点”古典”,很多人第一条 http_access 顺序写错就是 403,然后就放弃。本文把需要的指令按”必懂→场景→运维→排障”排好,保证你复制就能用。
一、你到底要不要上 Squid
先看下表,确认 Squid 是不是你要找的那个工具:
| 需求 | Squid 合适吗? | 推荐替代 |
|---|---|---|
| 给内网几百台机器统一出网,加黑白名单、访问日志 | ✅ 最合适 | Tinyproxy(轻量但功能弱) |
| 带用户名密码的”个人跳板代理”,让另一台机器走你 IP | ✅ 合适,NCSA 认证几行搞定 | 3proxy、Shadowtls(混淆流量) |
| 内网软件源/容器镜像缓存加速,省出口带宽(apt / docker / pip) | ✅ 很强,缓存命中率 70%+ 很常见 | Nginx proxy_cache |
| 反向代理/负载均衡(Web 站点前面加一台) | ⚠️ 能做,但现在基本用 Nginx/Envoy | Nginx、Caddy、HAProxy |
| 透明代理(内网客户端不用任何配置,网关自动劫持 HTTP(S) 流量) | ✅ 支持 TPROXY + iptables | V2Ray/Xray(需配合路由) |
| SOCKS5 代理(SSH 那种) | ❌ Squid 只做 HTTP(S) 代理 | dante-server、3proxy |
优点:C 语言、单进程多 worker、CPU/内存利用率高、ACL 语言极其丰富、支持 20+ 种外部认证 helper、可做磁盘持久化缓存、日志格式标准化方便进 ELK/Loki。 缺点:配置语法古老,http_access 是按顺序首条命中(不是”最精确匹配”),一写反就是 403;Squid 的 HTTPS 正向代理只做 CONNECT 隧道,如果你要”中间人看 HTTPS 内容并缓存”得自己装 SSL_bump + 造自签 CA,维护成本高。
二、5 个核心概念:看配置文件不头晕
1.1 正向代理 vs 反向代理 vs 透明代理
- 正向代理 (Forward Proxy):客户端主动配置”HTTP 代理=Squid 机器 IP:3128”,客户端知道代理存在;Squid 帮它访问外网,返回结果。这是 Squid 最常用的模式。
- 反向代理 (Web Accelerator):客户端不知道代理存在,访问
https://note.robinzen.cn→ 实际打到 Squid 443 → Squid 去后面的源站取内容再吐给你,用来给 Web 站加速。现基本被 Nginx 替代。 - 透明代理 (Transparent Proxy):Squid 部署在网关上,客户端不用改任何代理设置,iptables/nftables 在路由层把 80/443 包 DNAT 给 Squid。需要内核支持 TPROXY,不推荐新手一上来就搞。
1.2 缓存状态:HIT / MISS / MEM_HIT
Squid 日志第 3 列常见的就是这几个:
TCP_HIT:磁盘缓存里正好有 → 命中,没请求上游TCP_MEM_HIT:直接在内存里命中 → 最快TCP_MISS:缓存没命中 → 去上游取TCP_DENIED:被http_access deny规则拦了 → 403TCP_TUNNEL:HTTPS 通过 CONNECT 方法穿隧道(Squid 只转发,看不到内容)
1.3 ACL + http_access:首条命中原则(最重要)
Squid 里的”允许/拒绝访问”分两步:
- 先写一堆
acl 名字 类型 值,把”谁""访问什么""什么时候”分类 - 再写一堆
http_access allow/deny 名字,从上到下按顺序匹配,首条命中就执行,后面不再看
跟 iptables 一样!默认策略是 deny。如果你所有规则都没匹配,最后一定拒绝。最常见的错误就是把 http_access deny all 写在最开头,结果后面 allow 全白写。
1.4 端口与协议
- 默认
http_port 3128:正向代理标准端口,监听 TCP - 反向代理(加速器)模式写成
http_port 80 accel defaultsite=xxx vhost - HTTPS CONNECT 隧道不需要额外端口,客户端
CONNECT https://xxx:443走的就是同一个 3128
1.5 存储引擎:ufs / aufs / rock
cache_dir 第一个参数就是引擎:
- ufs(老默认):单线程磁盘 I/O,慢,现在别用
- aufs:异步 ufs,多线程磁盘 I/O,机械盘推荐
- rock:专门给 SSD 设计,连续写减少随机写,SSD 推荐
三、安装 + 初始化
所有命令以 root 执行为例(普通用户加 sudo)。
2.1 Ubuntu / Debian
apt update
# Ubuntu 20.04 / Debian 10 及更早(squid 包已内置 OpenSSL 支持):
apt install -y squid apache2-utils
# Ubuntu 22.04+ / Debian 11+(squid-openssl 提供 ssl_bump 所需的 helpers):
# apt install -y squid-openssl apache2-utils
# apache2-utils:提供 htpasswd(后面用户密码认证要用)2.2 CentOS 7 / RHEL 7(yum)
yum install -y epel-release
yum install -y squid httpd-tools2.3 RHEL 8+ / Rocky / AlmaLinux(dnf)
dnf install -y epel-release
dnf install -y squid httpd-tools2.4 systemd 启动 + 开机自启 + 验证
# 立即启动 + 开机自启
systemctl enable --now squid
# 看状态(active (running) 就 OK)
systemctl status squid --no-pager -l
# 看版本 + 编译特性,确认有 --enable-async-io 和 --enable-auth
squid -v
# 看默认 3128 端口是否监听
ss -lntp | grep 3128
# 正常输出:LISTEN 0 4096 *:3128 *:* users:(("squid",pid=...,fd=...))
# 防火墙放行(如果开了 firewalld)
firewall-cmd --permanent --add-port=3128/tcp 2>/dev/null
firewall-cmd --reload 2>/dev/null
# SELinux 宽容模式(CentOS/RHEL 如果 Enforcing 可能拦截 80/443 出站)
setenforce 0 2>/dev/null
sed -i 's/^SELINUX=enforcing/SELINUX=permissive/' /etc/selinux/config 2>/dev/null2.5 安装后你会得到的目录
| 路径 | 用途 |
|---|---|
/etc/squid/squid.conf | 主配置文件(最重要,下面全是围绕它) |
/etc/squid/conf.d/ | 拆分配置,最后被主文件 include 进来 |
/var/log/squid/access.log | 每次请求一行日志,排障必备 |
/var/log/squid/cache.log | Squid 进程自身日志(启动报错、认证 helper 异常) |
/var/spool/squid/ | 默认缓存目录(磁盘缓存文件落这里) |
/usr/lib/squid/ 或 /usr/libexec/squid/ | 外部 helper:basic_ncsa_auth 等 |
四、修改配置前的两个好习惯
3.1 先备份 + 做一份”最小可用 skeleton”
cp /etc/squid/squid.conf /etc/squid/squid.conf.bak.$(date +%Y%m%d)
# 以后改之前都先打备份很多发行版的默认 squid.conf 有 5000+ 行注释,读起来痛苦。建议直接把它清空,从空白开始写你要的规则(下面每个场景会给完整 conf)。
3.2 每次改完先检查语法,不要直接 restart
# 检查配置语法(会告诉你第几行什么错)
squid -k parse
# ✅ 正常:squid -k parse 没有任何 error 行
# ❌ 报错:一定要先修,不然 squid 启动失败⚠️ 线上千万不要
systemctl restart squid!生产环境先squid -k parse没问题后用systemctl reload squid(或squid -k reconfigure),热重载不丢任何连接、缓存不失效。只有改了cache_dir、workers这种”内存/磁盘结构级”的才需要 restart。
五、核心配置指令(每个都有示例)
下面指令按”你会在配置文件里出现的顺序”列。
4.1 http_port:监听哪里
# 最常用:所有网卡 3128(默认)
http_port 3128
# 更安全:只监听内网 IP(公网云服务器千万别裸开 0.0.0.0)
http_port 10.0.0.10:3128
# 同时监听 IPv4 + IPv6
http_port 0.0.0.0:3128
http_port [::]:3128
# 反向代理加速模式(Web 站点前面那台)
http_port 80 accel defaultsite=note.robinzen.cn vhost
cache_peer 10.0.0.20 parent 80 0 no-query originserver name=web14.2 visible_hostname:必须设(否则 403/500 报错里 host 是 (none))
visible_hostname proxy-01.infra.local
# 随便写,通常写主机名,用来排障时看是哪台 Squid 返回的错误页4.3 cache_mem:内存缓存
# 用来放热门对象的内存,建议总内存的 25%~50%,上限不超 8G,再大反而管理开销变高
cache_mem 2048 MB
# 内存里最多缓存多大的单个对象
maximum_object_size_in_memory 8 MB4.4 cache_dir:磁盘缓存
# aufs(机械盘):目录 引擎 总容量(MB) L1子目录数 L2子目录数
cache_dir aufs /var/spool/squid 20000 16 256
# 含义:/var/spool/squid 这个目录最多用 20GB,一级子目录 16 个,每个一级下 256 个二级子目录
# rock(SSD):不使用 L1/L2 子目录结构,参数为 目录 引擎 容量(MB) [选项]
cache_dir rock /var/spool/squid 20000 max-size=20971520
# 磁盘上单个对象最大/最小(超过就不缓存,省磁盘)
maximum_object_size 256 MB
minimum_object_size 0 KB改完 cache_dir 一定要跑这两步:
squid -k parse squid -z # 按你设定的 16 256 自动创建空的目录结构 systemctl restart squid忘了
squid -z的话启动日志会报storeAufsDirOpen: (2) No such file or directory。
4.5 acl:把流量分类
acl 的通用格式:
acl <名字> <类型> <值1> [值2 ...]常用类型一张表搞定:
| 类型 | 作用 | 示例 |
|---|---|---|
src | 客户端 IP 或子网 | acl mynet src 10.0.0.0/8 172.16.0.0/12 192.168.0.0/16 |
dst | 目标服务器 IP | acl blocked_ip dst 1.1.1.1/32 |
dstdomain / dstdomain . | 目标域名(前面加.匹配子域名) | acl taobao dstdomain .taobao.com .tmall.com |
url_regex | 整个 URL 正则匹配(包含关键词就中) | acl game_keyword url_regex -i game dota lol |
port | 目标端口 | acl ssl_ports port 443 |
method | HTTP 方法 | acl safe_methods method GET POST HEAD |
proto | HTTP/HTTPS/FTP | acl HTTPS proto HTTPS |
time | 时间 | acl work_hours time MTWHF 9:00-18:00 |
myip | Squid 自身监听的网卡 IP(多出口时分流) | acl line_b myip 203.0.113.22 |
proxy_auth REQUIRED | 需要通过用户名密码(见场景二) | acl login_users proxy_auth REQUIRED |
maxconn | 单个客户端 IP 最大并发数 | acl many_conn maxconn 30 |
时间缩写:M=周一 T=周二 W=周三 H=周四 F=周五 A=周六 S=周日。MTWHF 就是周一到周五工作日。
大小写不敏感:正则前面加 -i,比如 url_regex -i porn,大小写都匹配。
4.6 http_access:允许/拒绝按顺序匹配
经典”三段式”结构(推荐所有配置都按这个思路写):
# ========== 第 1 段:明确先 DENY 的 ==========
# 拒绝非安全方法(PUT/DELETE/CONNECT 到非 443 等)
http_access deny !Safe_ports
http_access deny CONNECT !SSL_ports
# ========== 第 2 段:明确 ALLOW 你要放行的 ==========
# 允许管理机 SSH 连过来的本机 127.0.0.1(维护用)
http_access allow localhost
# 允许内网网段(上班时间才允许逛非购物站点)
http_access allow mynet !taobao work_hours
# 下班后内网完全放行
http_access allow mynet
# ========== 第 3 段:兜底 DENY ALL ==========
http_access deny all划重点:兜底
http_access deny all必须写在最后一行,写在最前面就全拦截了。
4.7 request/reply_header_access:清洗头信息
# 不把客户端真实 IP 告诉上游(默认会加 X-Forwarded-For)
request_header_access X-Forwarded-For deny all
request_header_access Via deny all
# 对 HTTPS CONNECT 隧道不写 via(防上游识别代理特征)
reply_header_access Via deny all4.8 DNS 解析加速
# 单独指定 DNS(不用系统 /etc/resolv.conf),内网 DNS 更稳定
dns_nameservers 223.5.5.5 119.29.29.29 8.8.8.8
positive_dns_ttl 1 hour # DNS 命中后缓存 1h
negative_dns_ttl 30 sec # NXDOMAIN 不要缓存太久
# 注:dns_v4_first 指令已在 Squid 5+ 移除,新版默认双栈 Happy Eyeballs 自动选路;
# 若需强制 IPv4,改用 DNS 解析器过滤 AAAA 记录或 tcp_outgoing_address 控制。4.9 日志格式(默认足够,但推荐加 X-Forwarded-For)
# 原始 combined 格式 + XFF
logformat combined %{X-Forwarded-For}>h %ui %un [%tl] "%rm %ru HTTP/%rv" %>Hs %<st "%{Referer}>h" "%{User-Agent}>h" %Ss:%Sh
access_log /var/log/squid/access.log combined六、场景一:局域网正向代理(最常用,拿来就用)
需求:
- Squid 机内网 IP
10.0.0.10 - 内网三个段
10.0.0.0/8、172.16.0.0/12、192.168.0.0/16 - 只允许访问 80/443/8080/8443 这几个常见端口
- 工作日 9-18 点禁止访问淘宝/天猫/抖音
- 其他放行,默认 deny
完整 /etc/squid/squid.conf(直接复制覆盖)
# ========== 基础 ==========
visible_hostname proxy-01.infra.local
http_port 10.0.0.10:3128
# ========== 资源 ==========
cache_mem 2048 MB
maximum_object_size_in_memory 8 MB
cache_dir aufs /var/spool/squid 30000 16 256
maximum_object_size 256 MB
# ========== 端口安全 ==========
acl Safe_ports port 80 # http
acl Safe_ports port 443 # https
acl Safe_ports port 8080 8443 # 常见 web 管理端口
acl SSL_ports port 443 8443
acl CONNECT method CONNECT
http_access deny !Safe_ports
http_access deny CONNECT !SSL_ports
# ========== 客户端分类 ==========
acl mynet src 10.0.0.0/8 172.16.0.0/12 192.168.0.0/16
acl localhost src 127.0.0.1/32 ::1
# ========== 访问控制 ==========
acl work_hours time MTWHF 9:00-18:00
acl shopping dstdomain .taobao.com .tmall.com .jd.com .douyin.com .tiktok.com
# ========== 放行规则(顺序决定一切) ==========
http_access allow localhost
# 上班时间 + 非购物站点 → 放行
http_access allow mynet !shopping work_hours
# 非上班时间 → 全部放行
http_access allow mynet !work_hours
# ========== 默认拒绝 ==========
http_access deny all
# ========== 杂项 ==========
dns_nameservers 223.5.5.5 119.29.29.29
cache_mgr admin@example.com
# 隐藏 Via/X-Forwarded-For,让上游不知道经过了代理(可选)
# request_header_access X-Forwarded-For deny all
# request_header_access Via deny all
# reply_header_access Via deny all
coredump_dir /var/spool/squid
refresh_pattern ^ftp: 1440 20% 10080
refresh_pattern ^gopher: 1440 0% 1440
refresh_pattern -i (/cgi-bin/|\?) 0 0% 0
refresh_pattern . 0 20% 4320启动/重载:
squid -k parse
# 如果 cache_dir 是初次创建:
# squid -z
systemctl reload squid客户端怎么用
命令行测试(假设 Squid 机 IP 是 10.0.0.10):
# curl 走代理查外网 IP
curl -x http://10.0.0.10:3128 -s https://ifconfig.me
# 上面应该返回 Squid 机的公网出口 IP
# Ubuntu/Debian 临时让 apt 走代理
echo 'Acquire::http::Proxy "http://10.0.0.10:3128";' > /etc/apt/apt.conf.d/99proxy
echo 'Acquire::https::Proxy "http://10.0.0.10:3128";' >> /etc/apt/apt.conf.d/99proxy
# Docker 走代理(systemd 服务下 daemon)
mkdir -p /etc/systemd/system/docker.service.d
cat > /etc/systemd/system/docker.service.d/http-proxy.conf <<EOF
[Service]
Environment="HTTP_PROXY=http://10.0.0.10:3128"
Environment="HTTPS_PROXY=http://10.0.0.10:3128"
Environment="NO_PROXY=localhost,127.0.0.1,*.example.com"
EOF
systemctl daemon-reload && systemctl restart docker
# 普通 Linux 桌面:环境变量
cat >> ~/.bashrc <<'EOF'
export http_proxy=http://10.0.0.10:3128
export https_proxy=http://10.0.0.10:3128
export no_proxy=localhost,127.0.0.1,*.example.com
EOF
source ~/.bashrc
# Windows:设置 → 网络和 Internet → 代理 → 手动设置代理,填 IP:10.0.0.10 端口:3128七、场景二:带用户名密码的公网代理(NCSA 认证)
很多人图方便 Squid 监听公网 0.0.0.0:3128 又没加认证,结果被全网扫 3128 端口当肉鸡刷流量刷爆账单。只要 Squid 监听公网,就一定要加认证或至少 firewall 只放行你的 IP。
Squid 自带 basic_ncsa_auth helper,格式就是 Apache 的 htpasswd 文件,免装任何额外服务。
第 1 步:创建密码文件 + 生成用户
# 选一个 helper 路径(不同发行版位置不同)
# Debian/Ubuntu:
HELPER=/usr/lib/squid/basic_ncsa_auth
# CentOS/RHEL:
# HELPER=/usr/lib64/squid/basic_ncsa_auth
# 先确认存在
ls -l $HELPER
# 密码文件放这里(不要让非 root 可读)
PASS=/etc/squid/htpasswd
touch $PASS
chown squid:squid $PASS 2>/dev/null || chown proxy:proxy $PASS 2>/dev/null
chmod 640 $PASS
# 第一个用户:robin,密码回车输两次
htpasswd -c $PASS robin
# 再加第二个用户(不要 -c 了,会覆盖!)
htpasswd $PASS ops01
htpasswd $PASS ops02手动测试 helper 是否认密码(非常重要!很多人密码文件路径写对了但权限不对,认证永远失败):
echo "robin 你的密码" | $HELPER $PASS
# 成功会输出 OK,失败 ERR第 2 步:配置 squid.conf
visible_hostname proxy-public-01
# 公网监听(开防火墙 3128 只允许你自己的 IP 段,更稳)
http_port 0.0.0.0:3128
# ========== 认证 ==========
auth_param basic program /usr/lib/squid/basic_ncsa_auth /etc/squid/htpasswd
auth_param basic children 8 startup=2 idle=1
auth_param basic credentialsttl 2 hours
auth_param basic casesensitive off
acl login_users proxy_auth REQUIRED
# ========== 端口安全 ==========
acl Safe_ports port 80 443 8080 8443
acl SSL_ports port 443 8443
acl CONNECT method CONNECT
http_access deny !Safe_ports
http_access deny CONNECT !SSL_ports
# ========== 放行 ==========
http_access allow localhost
http_access allow login_users
http_access deny all
# ========== 杂项 ==========
cache_mem 1024 MB
cache_dir aufs /var/spool/squid 10000 16 256
dns_nameservers 223.5.5.5 8.8.8.8
coredump_dir /var/spool/squid
refresh_pattern . 0 20% 4320第 3 步:客户端测试
# 不带密码 → 407(正常,表明认证生效)
curl -I -x http://你的公网IP:3128 https://ifconfig.me
# 输出应该有:HTTP/1.1 407 Proxy Authentication Required
# 带用户名密码 → 成功
curl -U robin:你的密码 -x http://你的公网IP:3128 -s https://ifconfig.me
# 返回出口 IP 就 OK🛡️ 安全提醒:NCSA 的 basic auth 是明文传输用户名密码的,Squid 和客户端之间没有 TLS,中间有人抓包就能看到。如果必须公网长期用,要么 front TLS(让 Nginx/Caddy 前面加 443 证书包一层),要么认证只在你自己的 VPN 里用,或者换成 Digest auth / NTLM。
八、场景三:访问控制黑名单(屏蔽域名/关键词/网段)
日常运营里最常用的”运营规则”类配置,全部是 acl + http_access。
7.1 把黑名单抽成独立文件,不用每次改大 conf
推荐做法: 独立文件 + acl ... "/path/to/list",然后 reload 生效。
# 域名黑名单(一行一个)
cat > /etc/squid/blacklist.domain.txt <<'EOF'
.taobao.com
.tmall.com
.tiktok.com
.ixigua.com
.kuaishou.com
EOF
# URL 关键词黑名单(只要 URL 出现就拦)
cat > /etc/squid/blacklist.keywords.txt <<'EOF'
game
casino
bet
poker
EOF
# 客户端 IP 黑名单(被封的机器)
cat > /etc/squid/blacklist.clients.txt <<'EOF'
10.0.12.88/32
192.168.3.14/32
EOF7.2 squid.conf 引入
acl black_domain dstdomain "/etc/squid/blacklist.domain.txt"
acl black_key url_regex -i "/etc/squid/blacklist.keywords.txt"
acl black_cli src "/etc/squid/blacklist.clients.txt"
# 先 deny
http_access deny black_cli
http_access deny black_domain
http_access deny black_key
# 然后写你的 allow 规则...
http_access allow mynet
http_access deny all之后你要加一个域名,只要:
echo '.weibo.cn' >> /etc/squid/blacklist.domain.txt
squid -k reconfigure # 秒级生效,服务不中断九、运维命令速查(全部命令复制即用)
| 目标 | 命令 |
|---|---|
| 检查配置语法 | squid -k parse |
| 热重载配置(不丢连接) | squid -k reconfigure 或 systemctl reload squid |
| 重启(必要时才用) | systemctl restart squid |
| 初始化缓存目录结构 | squid -z(只在新 cache_dir 后跑一次) |
| 优雅关闭(等连接都结束) | squid -k shutdown |
| 强制杀死 | squid -k interrupt(不推荐) |
| 查看版本/编译特性 | squid -v |
| 实时看请求日志 | tail -f /var/log/squid/access.log |
| 实时看进程日志(启动报错/认证 helper) | tail -f /var/log/squid/cache.log |
| 看服务状态/cgroup 限制 | systemctl status squid -l --no-pager |
| 看 3128 建立连接的客户端 IP | ss -tn state established '( sport = :3128 )' | awk '{print $5}' | cut -d: -f1 | sort | uniq -c |
| 看缓存命中率(用 squidclient) | squidclient mgr:info | grep -A2 'cache' |
| 手动清单个 URL 的缓存 | squidclient -m PURGE http://example.com/file.tgz(一般 405,要加 PURGE method allow) |
访问日志 access.log 字段速拆
典型一行(默认 squid 格式):
1718614627.218 259 10.0.3.55 TCP_MISS/200 1234 GET https://example.com/ - HIER_DIRECT/93.184.216.34 text/html按空格依次:
- 时间戳(Unix 秒.毫秒):
date -d @1718614627反解 - 响应总耗时 ms:
259(包含 DNS + 上游取 + 写回客户端) - 客户端 IP
状态码/HTTP码:TCP_MISS/200、TCP_DENIED/403…- 响应字节数(不含头)
- 请求方法
- URL
- 客户端用户名(没用认证就是
-) HIER_xxx/上游IP:DIRECT=直连,PARENT=走父级代理- 响应 Content-Type
十、常见报错排障(遇到先查表)
❌ 症状 1:客户端全是 403,access.log 里全部 TCP_DENIED/403
可能原因按概率排序:
http_access deny all写在allow前面了 → 把 allow 放前面,deny all 放最后acl mynet src 10.0.0.0/24子网写错了,真实客户端 IP 不在里面- 解法:
tail -f /var/log/squid/access.log看第三列客户端真实 IP,再和 acl src 对比
- 解法:
- 客户端请求的方法/端口不在
Safe_ports/SSL_ports里(比如 8888 端口你没加进去) visible_hostname没设导致某些版本默认拒绝 → 设上- 认证场景:
acl login_users proxy_auth REQUIRED写在 allow 后面 → 顺序不对
排障三板斧:
squid -k parse
tail -f /var/log/squid/access.log
tail -f /var/log/squid/cache.log❌ 症状 2:TCP_MISS/503,全返回 503 Service Unavailable
意味着 Squid 到上游链路有问题:
- Squid 机自己 DNS 不通:
curl -v https://ifconfig.me在 Squid 机本地直接跑,如果也不通就是网络/DNS/防火墙 - 上游 DNS 超时:先
dns_nameservers设成223.5.5.5 8.8.8.8 - SELinux:RHEL/CentOS 上
setenforce 0临时试一下 cache.log里报storeAufsDirOpen...:缓存目录坏了 →squid -z重建- 多 worker 启动时端口冲突:workers 改成默认 1
❌ 症状 3:带认证返回 407 但密码明明对
- 先跑 helper 单测:
echo "user pass" | $HELPER $PASS→ 一定要输出 OK - helper 路径写错:
/usr/lib/squid/...vs/usr/lib64/squid/...,发行版不一样 - htpasswd 文件权限:squid 进程用户(squid/proxy)要能读,
chmod 640 && chown squid:squid /etc/squid/htpasswd auth_param basic program里路径和实际文件不存在,cache.log会有helperOpenServers: Cannot run...
❌ 症状 4:缓存命中率低(HIT 很少都是 MISS)
cache_mem设太小(只有几十 MB)→ 至少1024 MB起maximum_object_size_in_memory太小,热门文件进不了内存- 上游响应带
Cache-Control: no-cache / private→ Squid 只能尊重,改不了 - 客户端请求头带
Pragma: no-cache→ 浏览器 Ctrl+Shift+R 强刷就会带,正常 - URL 每次带随机参数(比如
?t=123456)→ 每次都是新 URL,自然不命中
❌ 症状 5:启动失败 Failed to start Squid caching proxy.
journalctl -u squid -n 50 --no-pager常见错误:
commBind: Cannot bind socket FD ... to 0.0.0.0:3128: (98) Address already in use→ 端口被占用,ss -lntp \| grep 3128找占用者 kill,或改http_port 3129storeAufsDirOpen: (2) No such file or directory→ 忘了squid -zFATAL: auth_param basic program...: (13) Permission denied→ helper 没有执行权限,chmod +x
❌ 症状 6:大量 TCP_TUNNEL/200 但是缓存完全没生效
HTTPS 流量默认都是 CONNECT 隧道,Squid 不会拆开看内容,必然不可能缓存。如果你要缓存 HTTPS 内容,得上 SSL_bump(中间人+自签 CA),客户端要信任你造的根证书。这个坑比较大,除非你真的有省带宽刚需,否则不建议个人环境折腾。
十一、性能调优(1000 并发以内照抄)
10.1 workers:多核利用
Squid 默认单进程,服务器 4 核以上要开 workers:
workers 4
# 绑定到物理核( numa 机器要注意不要跨 numa)
cpu_affinity_map process_numbers=0,1,2,3 cores=0,1,2,3不要开超过物理核数,否则上下文切换反而降性能。
10.2 系统级文件句柄数
Squid 默认 1024,高并发几秒打满:
# systemd 下(持久化)
mkdir -p /etc/systemd/system/squid.service.d
cat > /etc/systemd/system/squid.service.d/limits.conf <<'EOF'
[Service]
LimitNOFILE=65535
LimitNPROC=16384
EOF
systemctl daemon-reload && systemctl restart squid配置文件里也声明下:
max_filedescriptors 6553510.3 内核参数(网关/透明代理必改)
cat >> /etc/sysctl.conf <<'EOF'
net.ipv4.tcp_syncookies=1
net.ipv4.tcp_tw_reuse=1
net.ipv4.tcp_fin_timeout=30
net.ipv4.ip_local_port_range=1024 65535
net.core.rmem_max=16777216
net.core.wmem_max=16777216
net.ipv4.tcp_rmem=4096 87380 16777216
net.ipv4.tcp_wmem=4096 65536 16777216
EOF
sysctl -p10.4 磁盘选型
- 机械盘 → aufs,容量别超单个盘 70%
- SSD → rock 引擎,留 20% 以上 OP(不要写满)
- 日志
/var/log/squid建议挂独立磁盘或开 logrotate 压缩 + 保留 7 天,不然 access.log 几个月几十 GB
结语
Squid 虽然语法古老,但稳定和性能是真的顶:一台 4 核 8G + 512G SSD 的小机器跑 aufs/rock,日常 2~300 并发正向代理 + 20GB 热文件缓存,CPU 不会超过 30%,还能给你完整的访问日志和精细的时间/域名 ACL。
部署记住三句话:
- 改完先
squid -k parse,热重载用 reload,不要动不动 restart http_access是首条命中,默认 deny all 永远写最后一行- 监听公网一定要加认证或 firewall 白名单,裸开 3128 = 等被刷
所有配置都是在 CentOS 8 + Ubuntu 22.04 上实际跑过的模板,抄到 /etc/squid/squid.conf 直接就能用。