Squid 完全指南 / 12 - 安全加固
第十二章:安全加固
12.1 安全威胁概述
Squid 作为网络边缘设备,面临多种安全威胁:
| 威胁类型 | 说明 | 风险等级 |
|---|
| 开放代理 | 未配置 ACL 的代理被滥用 | 严重 |
| DDoS 攻击 | 大量请求导致服务不可用 | 高 |
| 缓存投毒 | 恶意内容被注入缓存 | 高 |
| 中间人攻击 | SSL 证书伪造 | 高 |
| 信息泄露 | 错误页面暴露内部信息 | 中 |
| 暴力破解 | 认证接口被暴力攻击 | 中 |
| 配置泄露 | 管理接口未授权访问 | 中 |
12.2 防止成为开放代理
# ============ 最基本的安全配置 ============
# 端口安全检查
acl Safe_ports port 80 443 21 70 8080 8443
acl SSL_ports port 443 8443
# 拒绝不安全的端口
http_access deny !Safe_ports
http_access deny CONNECT !SSL_ports
# 仅允许本地和授权网络
acl localnet src 192.168.0.0/16
acl localhost src 127.0.0.0/8 ::1
# 访问控制顺序
http_access allow localhost
http_access allow localnet
http_access deny all # 必须有这一行!
# 仅绑定到内网接口(不要监听 0.0.0.0)
http_port 192.168.1.1:3128
# 而非
# http_port 3128
⚠️ 严重警告:没有 http_access deny all 的配置会成为开放代理,任何人都可以通过你的代理访问互联网,可能导致法律问题。
12.3 DDoS 防护
12.3.1 连接限制
# 单 IP 最大连接数
acl max_conn_per_ip maxconn 20
http_access deny max_conn_per_ip
# 单用户最大连接数
acl max_user_conn maxconn 15
# 请求频率限制(通过 note 标记)
# 需要外部 helper 或 iptables 配合
12.3.2 使用 iptables 限流
# 限制每 IP 的新连接速率
iptables -A INPUT -p tcp --dport 3128 \
-m connlimit --connlimit-above 50 \
-j DROP
# 限制每分钟的新连接数
iptables -A INPUT -p tcp --dport 3128 \
-m state --state NEW \
-m recent --set --name squid_conn
iptables -A INPUT -p tcp --dport 3128 \
-m state --state NEW \
-m recent --update --seconds 60 --hitcount 100 --name squid_conn \
-j DROP
# 使用 hashlimit 模块
iptables -A INPUT -p tcp --dport 3128 \
-m hashlimit --hashlimit-above 30/sec \
--hashlimit-burst 50 \
--hashlimit-mode srcip \
--hashlimit-name squid_rate \
-j DROP
12.3.3 Squid 内置限流
# 请求体大小限制
request_body_max_size 10 MB
# 请求头大小限制
request_header_max_size 64 KB
# 响应体大小限制
reply_body_max_size 100 MB allow all
# 持久连接限制
client_persistent_connections on
server_persistent_connections on
pipeline_prefetch on
12.4 缓存安全
12.4.1 防止缓存投毒
# 验证源站证书(反向代理场景)
# 不要使用 sslproxy_flags DONT_VERIFY_PEER
# 不缓存带有 Set-Cookie 的响应
# reply_header_access Set-Cookie deny all
# 严格遵循源站的缓存指令
# 不要使用 override-expire 或 ignore-no-cache
# 限制缓存的 HTTP 方法
acl Safe_methods method GET HEAD
cache deny !Safe_methods
12.4.2 缓存内容隔离
# 使用 cache_peer_access 隔离不同域名的缓存
cache_peer web1.local parent 80 0 no-query originserver name=site1
cache_peer web2.local parent 80 0 no-query originserver name=site2
acl site1_req dstdomain .site1.com
acl site2_req dstdomain .site2.com
cache_peer_access site1 allow site1_req
cache_peer_access site2 allow site2_req
12.5 SSL/TLS 安全
12.5.1 严格 TLS 配置
# 仅允许 TLS 1.2 和 TLS 1.3
https_port 443 \
cert=/etc/squid/ssl/site.pem \
options=NO_SSLv2,NO_SSLv3,NO_TLSv1,NO_TLSv1_1 \
cipher=ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305 \
tls-min-version=1.2
# SSL 会话缓存(防止重放攻击)
ssl_session_cache shared:SSL:50MB
ssl_session_timeout 4 hours
# 定期更新证书
# 使用 Let's Encrypt 自动续期
12.5.2 HSTS 配置
# 添加 HSTS 响应头
reply_header_add Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" all
# 仅对 HTTPS 请求添加
acl is_https proto HTTPS
reply_header_add Strict-Transport-Security "max-age=31536000" is_https
12.6 信息泄露防护
12.6.1 隐藏版本信息
# 隐藏 Squid 版本
httpd_suppress_version_string on
# 隐藏 Via 头
via off
# 隐藏 X-Forwarded-For
forwarded_for delete
# 隐藏 Server 和 X-Powered-By
reply_header_access Server deny all
reply_header_access X-Powered-By deny all
# 自定义错误页面(不暴露系统信息)
error_directory /usr/share/squid/errors/zh-cn
12.6.2 自定义错误页面
# 使用自定义错误页面
error_directory /etc/squid/errors/custom
<!-- /etc/squid/errors/custom/ERR_ACCESS_DENIED -->
<!DOCTYPE html>
<html>
<head><title>访问被拒绝</title></head>
<body>
<h1>访问被拒绝</h1>
<p>您没有权限访问此资源。</p>
<p>如需帮助,请联系管理员。</p>
</body>
</html>
12.7 认证安全
12.7.1 防暴力破解
# 使用 credentialsttl 避免频繁认证
auth_param basic credentialsttl 2 hours
# 认证 IP 缓存时间
authenticate_ip_ttl 10 seconds
# Helper 超时
helper_startup_timeout 30 seconds
# 使用 fail2ban 防暴力破解
# /etc/fail2ban/filter.d/squid-auth.conf
[Definition]
failregex = WARNING!.*denied.*<HOST>
ignoreregex =
# /etc/fail2ban/jail.d/squid.conf
[squid-auth]
enabled = true
filter = squid-auth
logpath = /var/log/squid/access.log
maxretry = 5
bantime = 3600
findtime = 600
12.7.2 密码策略
# 使用 Bcrypt 加密密码(更安全)
htpasswd -B /etc/squid/passwd username
# 定期更新密码
# 通过脚本检查密码文件年龄
#!/bin/bash
PASSWD_FILE="/etc/squid/passwd"
MAX_AGE=90 # 天
if [ $(( ($(date +%s) - $(stat -c %Y "$PASSWD_FILE")) / 86400 )) -gt $MAX_AGE ]; then
echo "WARNING: Squid password file is older than $MAX_AGE days"
fi
12.8 网络安全
12.8.1 防火墙规则
# 仅允许授权网络访问 Squid
iptables -A INPUT -s 192.168.1.0/24 -p tcp --dport 3128 -j ACCEPT
iptables -A INPUT -s 10.0.0.0/24 -p tcp --dport 3128 -j ACCEPT
iptables -A INPUT -p tcp --dport 3128 -j DROP
# 禁止从外部访问 Squid 管理端口
iptables -A INPUT ! -s 127.0.0.1 -p tcp --dport 3128 -j DROP
12.8.2 网络隔离
# 监听内网接口
http_port 192.168.1.1:3128
# 不要监听公网接口
# http_port 0.0.0.0:3128 # 危险!
12.9 审计与合规
12.9.1 审计日志配置
# 详细审计日志
logformat audit %ts.%03tu %>a %[un %rm %03>Hs %<st %ru %>ha{User-Agent} %ssl::>sni
access_log /var/log/squid/audit.log audit
# 不记录到审计日志的流量
acl healthcheck url_regex /health
access_log /var/log/squid/audit.log audit !healthcheck
12.9.2 合规要求
| 合规标准 | 要求 | Squid 配置 |
|---|
| 等保 2.0 | 访问日志留存 180 天 | logrotate + 归档 |
| GDPR | 不记录个人数据 | 日志脱敏 |
| PCI DSS | 加密传输、访问控制 | TLS + ACL |
| HIPAA | 审计日志、访问控制 | 完整审计日志 |
# 日志保留 180 天
# /etc/logrotate.d/squid
/var/log/squid/*.log {
daily
rotate 180
compress
delaycompress
missingok
notifempty
}
12.10 安全加固检查清单
# 1. 检查是否为开放代理
curl -x http://your-proxy:3128 http://httpbin.org/ip
# 如果返回了结果,需要检查 ACL
# 2. 检查版本信息是否泄露
curl -x http://your-proxy:3128 -I http://example.com
# 检查响应头中是否包含 Via、Server 等信息
# 3. 检查配置语法
sudo squid -k parse
# 4. 检查文件权限
ls -la /etc/squid/squid.conf
ls -la /etc/squid/ssl/
ls -la /var/log/squid/
# 5. 检查网络绑定
ss -tlnp | grep squid
# 6. 检查防火墙规则
iptables -L -n | grep 3128
# 7. 检查认证是否启用
grep -i "auth_param" /etc/squid/squid.conf
# 8. 检查 SSL 配置
squid -v | grep -i ssl
12.11 安全事件响应
#!/bin/bash
# squid-security-check.sh — 安全检查脚本
echo "=== Squid Security Check ==="
echo "Date: $(date)"
echo ""
# 1. 检查进程
echo "1. Squid process:"
ps aux | grep squid | grep -v grep
# 2. 检查监听端口
echo "2. Listening ports:"
ss -tlnp | grep squid
# 3. 检查拒绝的请求
echo "3. Recent denied requests:"
grep "TCP_DENIED" /var/log/squid/access.log | tail -10
# 4. 检查认证失败
echo "4. Authentication failures:"
grep "407" /var/log/squid/access.log | tail -10
# 5. 检查错误
echo "5. Recent errors:"
tail -20 /var/log/squid/cache.log | grep -i "error\|warning"
# 6. 检查连接数
echo "6. Current connections:"
ss -s | head -5
# 7. 检查文件描述符
echo "7. File descriptors:"
SQUID_PID=$(pgrep squid)
if [ -n "$SQUID_PID" ]; then
echo "Used: $(ls /proc/$SQUID_PID/fd | wc -l)"
echo "Limit: $(cat /proc/$SQUID_PID/limits | grep 'Max open files' | awk '{print $4}')"
fi
12.12 本章小结
| 安全措施 | 关键配置/方法 |
|---|
| 防开放代理 | http_access deny all + 绑定内网 IP |
| DDoS 防护 | maxconn + iptables 限流 |
| 缓存安全 | 验证源站 + 限制缓存方法 |
| SSL 安全 | TLS 1.2+ + 强密码套件 |
| 信息隐藏 | via off + httpd_suppress_version_string |
| 认证防护 | fail2ban + Bcrypt + 超时 |
| 审计合规 | 完整审计日志 + 保留策略 |
扩展阅读