09 - HTTPS 拦截 (SSL Bump)
第九章:HTTPS 拦截 (SSL Bump)
9.1 SSL Bump 概述
SSL Bump(SSL 拦截)是 Squid 实现 HTTPS 流量中间人(Man-in-the-Middle, MitM)解密的技术。它允许代理检查、过滤和缓存加密的 HTTPS 流量。
┌──────────┐ ┌───────────────────┐ ┌──────────────┐
│ 客户端 │────→│ Squid SSL Bump │────→│ 目标服务器 │
│ │←────│ │←────│ │
│ │ │ 1. 拦截 ClientHello│ │ │
│ │ │ 2. 动态生成证书 │ │ │
│ │ │ 3. 解密流量 │ │ │
│ │ │ 4. 检查/过滤 │ │ │
│ │ │ 5. 重新加密 │ │ │
└──────────┘ └───────────────────┘ └──────────────┘
TLS 1.3 SSL Bump TLS 1.3
(动态证书) (解密+检查) (真实证书)
⚠️ 法律与合规警告:SSL Bump 拦截加密流量涉及隐私和法律问题。在企业环境中使用前,务必确认:
- 有明确的公司政策授权
- 员工已被告知(通常在入职协议中)
- 不拦截银行、医疗、政府等敏感网站
- 遵守当地法律法规(如 GDPR)
9.2 SSL Bump 工作模式
9.2.1 Splice 模式(透传)
客户端 ←──TLS──→ Squid(仅转发)←──TLS──→ 服务器
Squid 不解密流量,仅做 TCP 转发。可以记录连接元数据(域名、IP),但不能检查内容。
9.2.2 Bump 模式(解密)
客户端 ←──TLS──→ Squid(解密+重新加密)←──TLS──→ 服务器
Squid 完全解密流量,检查明文内容后重新加密发给客户端。
9.2.3 Peek 模式(窥探)
客户端 ←──TLS──→ Squid(查看 SNI/证书)←──TLS──→ 服务器
Squid 仅查看 ClientHello 中的 SNI 和服务器证书信息,不解密数据。
9.2.4 模式对比
| 模式 | 解密内容 | 可见信息 | 性能影响 | 法律风险 |
|---|---|---|---|---|
| Splice | 否 | IP、端口 | 极低 | 低 |
| Peek | 否 | SNI、证书 | 低 | 低 |
| Bump | 是 | 全部内容 | 中 | 高 |
| Stare | 否 | SNI | 低 | 低 |
9.3 编译支持
SSL Bump 需要 Squid 编译时启用 SSL 支持:
# 检查当前 Squid 是否支持 SSL
squid -v 2>&1 | grep -o "enable-ssl"
# 如果没有输出,需要重新编译
# 源码编译时添加 SSL 选项
./configure \
--prefix=/usr/local/squid \
--enable-ssl \
--with-openssl \
--enable-ssl-crtd \
...
# Ubuntu/Debian 安装支持 SSL 的 Squid
sudo apt install -y squid
# 大多数发行版默认编译了 SSL 支持
squid -v | grep ssl
9.4 生成 CA 证书
9.4.1 创建自签名 CA
#!/bin/bash
# generate_ca.sh — 生成 SSL Bump CA 证书
SSL_DIR="/etc/squid/ssl"
mkdir -p "$SSL_DIR"
cd "$SSL_DIR"
# 生成 CA 私钥
openssl genrsa -out ca.key 4096
# 生成 CA 证书(10年有效期)
openssl req -new -x509 -days 3650 -key ca.key -out ca.crt \
-subj "/C=CN/ST=Beijing/L=Beijing/O=MyCompany/OU=IT/CN=Squid SSL Bump CA"
# 合并为 PEM 格式(Squid 需要)
cat ca.crt ca.key > myCA.pem
# 设置权限
chmod 600 ca.key myCA.pem
chmod 644 ca.crt
chown -R proxy:proxy "$SSL_DIR"
echo "CA certificate generated at: $SSL_DIR/myCA.pem"
echo "CA certificate fingerprint:"
openssl x509 -in ca.crt -noout -fingerprint -sha256
9.4.2 创建 SSL 证书数据库
# 初始化 SSL 证书数据库
# 需要 Squid 6.x 或编译了 --enable-ssl-crtd 的版本
/usr/lib/squid/security_file_certgen -c -s /var/lib/squid/ssl_db -M 20MB
# 设置权限
chown -R proxy:proxy /var/lib/squid/ssl_db
9.4.3 分发 CA 证书到客户端
CA 证书需要导入到所有客户端的信任证书存储中:
Windows(域控推送):
# 通过 GPO 推送 CA 证书
certutil -addstore "Root" "ca.crt"
# 或手动导入
# 双击 ca.crt → 安装证书 → 受信任的根证书颁发机构
macOS:
sudo security add-trusted-cert -d -r trustRoot \
-k /Library/Keychains/System.keychain ca.crt
Linux(Firefox):
# 使用 certutil
certutil -d sql:$HOME/.pki/nssdb -A -t "C,," -n "Squid CA" -i ca.crt
# 或在 Firefox 设置中手动导入
# 设置 → 隐私与安全 → 证书 → 查看证书 → 导入
Linux(系统级):
# Ubuntu/Debian
sudo cp ca.crt /usr/local/share/ca-certificates/squid-ca.crt
sudo update-ca-certificates
# CentOS/RHEL
sudo cp ca.crt /etc/pki/ca-trust/source/anchors/squid-ca.crt
sudo update-ca-trust
9.5 SSL Bump 配置
9.5.1 基础 SSL Bump 配置
# SSL Bump 拦截端口
http_port 3129 ssl-bump \
cert=/etc/squid/ssl/myCA.pem \
generate-host-certificates=on \
dynamic_cert_mem_cache_size=20MB
# SSL Bump 策略
ssl_bump stare all # 先窥探所有连接
ssl_bump bump all # 然后解密所有
# SSL 代理设置
sslproxy_cert_error allow all # 允许后端证书错误(生产环境不建议)
sslproxy_flags DONT_VERIFY_PEER # 不验证后端证书(仅测试用)
9.5.2 分级 SSL Bump 策略
# 配置 SSL Bump 拦截端口
http_port 3129 ssl-bump \
cert=/etc/squid/ssl/myCA.pem \
generate-host-certificates=on \
dynamic_cert_mem_cache_size=20MB
# SSL 证书数据库
sslcrtd_program /usr/lib/squid/security_file_certgen -s /var/lib/squid/ssl_db -M 20MB
sslcrtd_children 5
# ============ SSL Bump ACL ============
# 不解密的域名(银行、医疗、政府等敏感站点)
acl nobump_ssl ssl::server_name_regex -i "/etc/squid/nobump_domains.txt"
# 解密的域名(一般网站)
acl bump_ssl ssl::server_name_regex -i "/etc/squid/bump_domains.txt"
# 不解密的 IP
acl nobump_ip dst "/etc/squid/nobump_ips.txt"
# ============ SSL Bump 规则 ============
# 1. 先窥探(获取 SNI)
ssl_bump peek all
# 2. 白名单域名不解密
ssl_bump splice nobump_ssl
# 3. 白名单 IP 不解密
ssl_bump splice nobump_ip
# 4. 其他流量解密
ssl_bump bump all
nobump_domains.txt(不解密的域名):
# 银行
.bank.example.com
.alipay.com
.wechat.com
.paypal.com
# 医疗
.hospital.example.com
# 政府
.gov.cn
# 其他敏感站点
.google.com # 如果需要保留隐私
9.5.3 基于端口的 SSL Bump
# 仅对 443 端口做 SSL Bump
acl https_port port 443
ssl_bump peek all
ssl_bump bump https_port
ssl_bump splice !https_port
9.6 SSL 证书管理
9.6.1 使用通配符证书
# 使用自己的通配符证书
# 合并证书链
cat wildcard.crt intermediate.crt > combined.pem
cat combined.pem wildcard.key > /etc/squid/ssl/site.pem
# 配置
https_port 443 cert=/etc/squid/ssl/site.pem
9.6.2 证书错误处理
# 策略一:拒绝证书错误(安全,推荐生产环境)
sslproxy_cert_error deny all
# 策略二:允许证书错误(仅测试环境)
# sslproxy_cert_error allow all
# 策略三:根据 ACL 选择性允许
acl trusted_domain ssl::server_name .trusted.com
sslproxy_cert_error allow trusted_domain
sslproxy_cert_error deny all
# 不验证后端证书(仅测试,生产环境不要使用)
# sslproxy_flags DONT_VERIFY_PEER
# 证书错误日志
sslproxy_cert_sign hash all
sslproxy_cert_adapt setCommonName all
9.6.3 证书缓存管理
# 动态证书内存缓存
dynamic_cert_mem_cache_size 20MB
# 证书数据库位置
sslcrtd_program /usr/lib/squid/security_file_certgen \
-s /var/lib/squid/ssl_db -M 20MB
# 证书生成子进程数
sslcrtd_children 10 startup=3 idle=1
9.7 透明 SSL Bump
9.7.1 配置透明 SSL Bump
# 透明 SSL Bump 端口
http_port 3130 intercept ssl-bump \
cert=/etc/squid/ssl/myCA.pem \
generate-host-certificates=on \
dynamic_cert_mem_cache_size=20MB
# SSL Bump 规则
ssl_bump peek all
ssl_bump bump all
# iptables 配置
# 将 HTTPS 流量重定向到 Squid 的 SSL Bump 端口
iptables -t nat -A PREROUTING -s 192.168.1.0/24 \
-p tcp --dport 443 \
-j REDIRECT --to-port 3130
# 排除 Squid 自身流量
iptables -t nat -A OUTPUT -p tcp --dport 443 \
-m owner --uid-owner proxy \
-j RETURN
9.8 TLS 1.3 支持
# Squid 6.x 支持 TLS 1.3
# 配置 TLS 版本
http_port 3129 ssl-bump \
cert=/etc/squid/ssl/myCA.pem \
generate-host-certificates=on \
tls-min-version=1.2
# 配置加密套件
https_port 443 \
cert=/etc/squid/ssl/site.pem \
options=NO_SSLv3,NO_TLSv1,NO_TLSv1_1 \
cipher=ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384 \
tls-min-version=1.2
9.9 SSL Bump 日志分析
# 启用 SSL 相关日志
access_log /var/log/squid/access.log squid
# 自定义日志格式包含 SSL 信息
logformat ssl_log %ts.%03tu %6tr %>a %Ss/%03>Hs %<st %rm %ru %[un %Sh/%<a %ssl::>sni %ssl::>cert_subject %mt
access_log /var/log/squid/ssl_access.log ssl_log
# 查看 SSL Bump 日志
tail -f /var/log/squid/access.log | grep SSL
# 查看拦截的域名
awk '{print $11}' /var/log/squid/ssl_access.log | sort | uniq -c | sort -rn
# 查看证书错误
grep "CERT_ERROR" /var/log/squid/cache.log
9.10 SSL Bump 排除列表
# 推荐排除的网站类别
# 1. 金融类
acl nobump_finance ssl::server_name_regex -i \
"\.bank\." "\.paypal\." "\.alipay\." "\.wechat\."
# 2. 医疗健康
acl nobump_health ssl::server_name_regex -i \
"\.hospital\." "\.medical\." "\.health\."
# 3. 政府网站
acl nobump_gov ssl::server_name .gov .gov.cn .mil
# 4. 个人隐私
acl nobump_personal ssl::server_name_regex -i \
"\.health\." "\.therapy\." "\.lawyer\."
# 5. 证书钉扎的站点(SSL Bump 会破坏证书钉扎)
acl nobump_pinning ssl::server_name_regex -i \
"\.google\." "\.facebook\." "\.twitter\."
# 应用排除
ssl_bump splice nobump_finance
ssl_bump splice nobump_health
ssl_bump splice nobump_gov
ssl_bump splice nobump_personal
ssl_bump splice nobump_pinning
ssl_bump bump all
9.11 完整 SSL Bump 配置示例
# /etc/squid/squid.conf — SSL Bump 生产配置
# ============ 端口 ============
http_port 3128
http_port 3129 ssl-bump \
cert=/etc/squid/ssl/myCA.pem \
generate-host-certificates=on \
dynamic_cert_mem_cache_size=20MB
# ============ SSL ============
sslcrtd_program /usr/lib/squid/security_file_certgen -s /var/lib/squid/ssl_db -M 20MB
sslcrtd_children 10 startup=3 idle=1
# ============ ACL ============
acl localnet src 192.168.0.0/16
acl SSL_ports port 443
acl Safe_ports port 80 443
acl CONNECT method CONNECT
# SSL Bump ACL
acl nobump ssl::server_name_regex -i "/etc/squid/nobump.txt"
acl nopeek ssl::server_name_regex -i "/etc/squid/nopeek.txt"
# 认证
auth_param basic program /usr/lib/squid/basic_ncsa_auth /etc/squid/passwd
auth_param basic children 10
auth_param basic realm Proxy
acl auth proxy_auth REQUIRED
# ============ SSL Bump 规则 ============
ssl_bump peek all
ssl_bump splice nobump
ssl_bump splice nopeek
ssl_bump bump all
# ============ 访问控制 ============
http_access deny !Safe_ports
http_access deny CONNECT !SSL_ports
http_access allow localnet
http_access deny all
# ============ 证书策略 ============
sslproxy_cert_error deny all
sslproxy_cert_sign hash setCommonName all
# ============ 缓存 ============
cache_dir ufs /var/spool/squid 20000 256 4096
cache_mem 2048 MB
# ============ 日志 ============
access_log /var/log/squid/access.log squid
cache_log /var/log/squid/cache.log
# ============ 安全 ============
via off
forwarded_for delete
httpd_suppress_version_string on
visible_hostname proxy.example.com
9.12 本章小结
| 功能 | 关键配置 |
|---|---|
| SSL Bump 端口 | http_port ... ssl-bump |
| CA 证书 | cert=/etc/squid/ssl/myCA.pem |
| 证书数据库 | sslcrtd_program + security_file_certgen |
| Bump 策略 | ssl_bump peek/splice/bump/stare |
| 排除域名 | ssl::server_name ACL |
| 证书错误 | sslproxy_cert_error |
⚠️ 重要提示:SSL Bump 会影响 TLS 证书链验证,某些应用(如证书钉扎的 App)可能无法正常工作。务必在部署前充分测试。