⚠️ 提示:本站 AI 助手使用博主个人 API Token,没事别特么瞎用。
网络 · · 约 41 分钟阅读

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/EnvoyNginx、Caddy、HAProxy
透明代理(内网客户端不用任何配置,网关自动劫持 HTTP(S) 流量)✅ 支持 TPROXY + iptablesV2Ray/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 规则拦了 → 403
  • TCP_TUNNEL:HTTPS 通过 CONNECT 方法穿隧道(Squid 只转发,看不到内容)

1.3 ACL + http_access:首条命中原则(最重要)

Squid 里的”允许/拒绝访问”分两步:

  1. 先写一堆 acl 名字 类型 值,把”谁""访问什么""什么时候”分类
  2. 再写一堆 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-tools

2.3 RHEL 8+ / Rocky / AlmaLinux(dnf)

dnf install -y epel-release
dnf install -y squid httpd-tools

2.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/null

2.5 安装后你会得到的目录

路径用途
/etc/squid/squid.conf主配置文件(最重要,下面全是围绕它)
/etc/squid/conf.d/拆分配置,最后被主文件 include 进来
/var/log/squid/access.log每次请求一行日志,排障必备
/var/log/squid/cache.logSquid 进程自身日志(启动报错、认证 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=web1

4.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 MB

4.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目标服务器 IPacl 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
methodHTTP 方法acl safe_methods method GET POST HEAD
protoHTTP/HTTPS/FTPacl HTTPS proto HTTPS
time时间acl work_hours time MTWHF 9:00-18:00
myipSquid 自身监听的网卡 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 all

4.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
EOF

7.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 建立连接的客户端 IPss -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

按空格依次:

  1. 时间戳(Unix 秒.毫秒):date -d @1718614627 反解
  2. 响应总耗时 ms:259(包含 DNS + 上游取 + 写回客户端)
  3. 客户端 IP
  4. 状态码/HTTP码:TCP_MISS/200、TCP_DENIED/403…
  5. 响应字节数(不含头)
  6. 请求方法
  7. URL
  8. 客户端用户名(没用认证就是 -)
  9. HIER_xxx/上游IP:DIRECT=直连,PARENT=走父级代理
  10. 响应 Content-Type

十、常见报错排障(遇到先查表)

❌ 症状 1:客户端全是 403,access.log 里全部 TCP_DENIED/403

可能原因按概率排序:

  1. http_access deny all 写在 allow 前面了 → 把 allow 放前面,deny all 放最后
  2. acl mynet src 10.0.0.0/24 子网写错了,真实客户端 IP 不在里面
    • 解法:tail -f /var/log/squid/access.log 看第三列客户端真实 IP,再和 acl src 对比
  3. 客户端请求的方法/端口不在 Safe_ports / SSL_ports 里(比如 8888 端口你没加进去)
  4. visible_hostname 没设导致某些版本默认拒绝 → 设上
  5. 认证场景: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 到上游链路有问题:

  1. Squid 机自己 DNS 不通:curl -v https://ifconfig.me 在 Squid 机本地直接跑,如果也不通就是网络/DNS/防火墙
  2. 上游 DNS 超时:先 dns_nameservers 设成 223.5.5.5 8.8.8.8
  3. SELinux:RHEL/CentOS 上 setenforce 0 临时试一下
  4. cache.log 里报 storeAufsDirOpen...:缓存目录坏了 → squid -z 重建
  5. 多 worker 启动时端口冲突:workers 改成默认 1

❌ 症状 3:带认证返回 407 但密码明明对

  1. 先跑 helper 单测:echo "user pass" | $HELPER $PASS → 一定要输出 OK
  2. helper 路径写错:/usr/lib/squid/... vs /usr/lib64/squid/...,发行版不一样
  3. htpasswd 文件权限:squid 进程用户(squid/proxy)要能读,chmod 640 && chown squid:squid /etc/squid/htpasswd
  4. auth_param basic program 里路径和实际文件不存在,cache.log 会有 helperOpenServers: Cannot run...

❌ 症状 4:缓存命中率低(HIT 很少都是 MISS)

  1. cache_mem 设太小(只有几十 MB)→ 至少 1024 MB 起
  2. maximum_object_size_in_memory 太小,热门文件进不了内存
  3. 上游响应带 Cache-Control: no-cache / private → Squid 只能尊重,改不了
  4. 客户端请求头带 Pragma: no-cache → 浏览器 Ctrl+Shift+R 强刷就会带,正常
  5. 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 3129
  • storeAufsDirOpen: (2) No such file or directory → 忘了 squid -z
  • FATAL: 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 65535

10.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 -p

10.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。

部署记住三句话:

  1. 改完先 squid -k parse,热重载用 reload,不要动不动 restart
  2. http_access 是首条命中,默认 deny all 永远写最后一行
  3. 监听公网一定要加认证或 firewall 白名单,裸开 3128 = 等被刷

所有配置都是在 CentOS 8 + Ubuntu 22.04 上实际跑过的模板,抄到 /etc/squid/squid.conf 直接就能用。

问问 AI