强曰为道
与天地相似,故不违。知周乎万物,而道济天下,故不过。旁行而不流,乐天知命,故不忧.
文档目录

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 + 超时
审计合规完整审计日志 + 保留策略

扩展阅读