Hotdry.
ai-systems

基于Squid代理的Kubernetes出口流量控制架构:TLS拦截与细粒度策略工程实践

设计基于Squid透明代理的Kubernetes出口流量控制架构,涵盖TLS拦截配置、FQDN级访问控制、连接池优化与高可用部署的完整工程参数。

在云原生环境中,Kubernetes 集群的出口流量控制是安全架构的关键环节。传统的网络层防火墙虽然能基于 IP 和端口进行过滤,但无法应对现代应用对 FQDN(完全限定域名)级别的细粒度访问控制需求。Squid 作为成熟的代理服务器,通过透明代理模式结合 TLS 拦截能力,为 Kubernetes 出口流量提供了应用层的精细控制方案。

架构设计:透明代理模式与 iptables 重定向

Squid 在 Kubernetes 环境中的部署通常采用两种模式:DaemonSet 模式或独立 VM 网关模式。DaemonSet 模式将 Squid 代理部署到每个节点,实现节点级别的流量控制;独立 VM 网关模式则通过云服务商的路由配置,将所有集群出口流量集中到专门的 Squid 代理实例。

透明代理的核心在于 iptables 规则的重定向配置。以下是一组典型的 iptables 规则,将 HTTP(80)和 HTTPS(443)流量重定向到 Squid 的监听端口:

# HTTP流量重定向到3129端口
iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 3129
iptables -t nat -A POSTROUTING -j MASQUERADE
iptables -t mangle -A PREROUTING -p tcp --dport 3129 -j DROP

# HTTPS流量重定向到3130端口  
iptables -t nat -A PREROUTING -p tcp --dport 443 -j REDIRECT --to-port 3130
iptables -t nat -A POSTROUTING -j MASQUERADE
iptables -t mangle -A PREROUTING -p tcp --dport 3130 -j DROP

在 Kubernetes DaemonSet 部署中,这些 iptables 规则可以通过 init 容器或特权容器在节点启动时自动配置。关键参数包括:

  • can_ip_forward = true:允许代理实例转发非匹配源 / 目的 IP 的数据包
  • 负载均衡器 IP 白名单:避免负载均衡器自身的健康检查流量被重定向

TLS 拦截工程实践:CA 证书管理与 ssl-bump 配置

对于 HTTPS 流量的深度检查,Squid 提供了 ssl-bump 功能,能够拦截并解密 TLS 连接进行内容检查。这一功能需要精心配置,涉及 CA 证书管理、动态证书生成和多个拦截阶段。

证书基础设施配置

首先需要创建自签名的根 CA 证书,并将其导入到所有需要信任代理的客户端(包括 Kubernetes 节点和容器运行时):

# 生成根CA私钥和证书
openssl genrsa -out ca-key.pem 4096
openssl req -new -x509 -days 3650 -key ca-key.pem -out ca-cert.pem

# 创建DER格式证书供客户端导入
openssl x509 -in ca-cert.pem -outform DER -out ca-cert.der

Squid ssl-bump 配置参数

Squid 的 https_port 配置需要启用 intercept 和 ssl-bump 模式:

# Squid 4.x配置示例
http_port 3129 intercept
https_port 3130 intercept ssl-bump \
  tls-cert=/etc/squid/certs/ca-cert.pem \
  tls-key=/etc/squid/certs/ca-key.pem \
  tls-default-ca=on \
  generate-host-certificates=on \
  dynamic_cert_mem_cache_size=4MB

关键配置参数说明:

  • generate-host-certificates=on:启用动态主机证书生成
  • dynamic_cert_mem_cache_size=4MB:动态证书内存缓存大小,根据流量规模调整
  • tls-default-ca=on:使用配置的 CA 作为默认证书颁发机构

SSL 证书数据库助手

Squid 需要专门的助手程序来管理动态生成的 TLS 证书:

# Squid 4.x配置
sslcrtd_program /usr/local/squid/libexec/security_file_certgen \
  -s /var/lib/ssl_db -M 4MB

证书数据库目录需要预先初始化:

/usr/local/squid/libexec/security_file_certgen -c -s /var/lib/ssl_db

多阶段拦截策略

ssl-bump 采用三阶段拦截策略,每个阶段可以执行不同的操作:

# 定义拦截阶段ACL
acl step1 at_step SslBump1
acl step2 at_step SslBump2  
acl step3 at_step SslBump3

# 阶段1:peek - 窥探ClientHello获取SNI
ssl_bump peek step1

# 阶段2:stare - 建立TLS连接但不终止
ssl_bump stare step2

# 阶段3:bump - 完全拦截并解密(对非白名单域名)
ssl_bump bump step3

对于白名单中的可信域名,可以使用splice模式直接透传,避免不必要的解密开销:

acl trusted_domains ssl::server_name "/etc/squid/trusted-domains.txt"
ssl_bump splice trusted_domains

细粒度策略:基于 FQDN 的 ACL 白名单与连接池优化

FQDN 级访问控制列表

Squid 的核心优势在于其强大的 ACL(访问控制列表)系统,支持基于域名、URL 路径、内容类型等多维度的策略控制:

# 定义白名单文件路径
acl allowed_domains dstdomain "/etc/squid/allowlist.txt"

# 按域名类别分组
acl internal_services dstdomain .internal.company.com
acl cloud_apis dstdomain .api.cloudprovider.com
acl public_cdn dstdomain .cdnjs.cloudflare.com .ajax.googleapis.com

# 时间限制策略
acl business_hours time MTWHF 09:00-18:00

# 组合策略:工作时间允许访问云API
http_access allow business_hours cloud_apis
http_access deny !business_hours cloud_apis

白名单文件格式支持通配符和正则表达式:

# 允许特定域名
api.github.com
*.docker.io

# 正则表达式匹配
.regex ^https?://([a-z0-9]+\.)?example\.com/

连接池优化参数

Squid 的连接池机制能显著提升代理性能,减少 TLS 握手开销。关键优化参数包括:

# 连接池配置
maximum_object_size 256 MB
cache_mem 512 MB
maximum_object_size_in_memory 128 KB

# HTTP连接复用
pipeline_prefetch on
quick_abort_min -1 KB
quick_abort_max -1 KB

# TLS连接保持
tls_outgoing_options cipher=ECDHE-RSA-AES128-GCM-SHA256
tls_outgoing_options options=NO_TLSv1,NO_TLSv1_1

# 连接超时与重试
connect_timeout 30 seconds
read_timeout 60 minutes
request_timeout 60 minutes
persistent_request_timeout 5 minutes

对于高并发场景,需要调整文件描述符限制:

# /etc/security/limits.conf
squid soft nofile 65536
squid hard nofile 131072

部署与监控:Kubernetes DaemonSet 配置

DaemonSet 部署清单

在 Kubernetes 中部署 Squid 代理的 DaemonSet 需要特殊权限配置:

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: squid-egress-proxy
  namespace: kube-system
spec:
  selector:
    matchLabels:
      app: squid-proxy
  template:
    metadata:
      labels:
        app: squid-proxy
    spec:
      hostNetwork: true
      dnsPolicy: ClusterFirstWithHostNet
      tolerations:
      - key: node-role.kubernetes.io/master
        effect: NoSchedule
      - key: node-role.kubernetes.io/control-plane
        effect: NoSchedule
      initContainers:
      - name: configure-iptables
        image: alpine:latest
        securityContext:
          privileged: true
        command:
        - /bin/sh
        - -c
        - |
          # 配置iptables规则
          iptables -t nat -N SQUID_REDIRECT
          iptables -t nat -A SQUID_REDIRECT -p tcp -j REDIRECT --to-port 3129
          iptables -t nat -A PREROUTING -p tcp --dport 80 -j SQUID_REDIRECT
          iptables -t nat -A PREROUTING -p tcp --dport 443 -j SQUID_REDIRECT
      containers:
      - name: squid
        image: squid:4-alpine
        securityContext:
          capabilities:
            add:
            - NET_ADMIN
            - NET_RAW
        ports:
        - containerPort: 3129
          name: http-proxy
          hostPort: 3129
        - containerPort: 3130
          name: https-proxy
          hostPort: 3130
        volumeMounts:
        - name: squid-config
          mountPath: /etc/squid/squid.conf
          subPath: squid.conf
        - name: allowlist
          mountPath: /etc/squid/allowlist.txt
          subPath: allowlist.txt
        - name: certs
          mountPath: /etc/squid/certs
        resources:
          requests:
            memory: "512Mi"
            cpu: "250m"
          limits:
            memory: "1Gi"
            cpu: "500m"
      volumes:
      - name: squid-config
        configMap:
          name: squid-config
      - name: allowlist
        configMap:
          name: squid-allowlist
      - name: certs
        secret:
          secretName: squid-ca-cert

监控指标与告警

Squid 提供了丰富的监控指标,可以通过 Prometheus 进行采集:

# Squid Prometheus exporter配置
squid_exporter_args:
  - --squid.hostname=localhost
  - --squid.port=3128
  - --web.listen-address=:9301
  - --squid.timeout=10s

关键监控指标包括:

  • squid_client_http_requests_total:HTTP 请求总数
  • squid_client_http_requests_duration_seconds:请求延迟分布
  • squid_cache_mem_bytes:内存缓存使用量
  • squid_disk_usage_bytes:磁盘缓存使用量
  • squid_client_http_errors_total:按错误类型分类的请求错误

告警规则示例:

groups:
- name: squid_alerts
  rules:
  - alert: SquidHighErrorRate
    expr: rate(squid_client_http_errors_total[5m]) > 0.1
    for: 5m
    labels:
      severity: warning
    annotations:
      summary: "Squid代理错误率过高"
      description: "Squid代理在过去5分钟内的错误率超过10%"
  
  - alert: SquidHighMemoryUsage
    expr: squid_cache_mem_bytes / squid_cache_mem_limit_bytes > 0.8
    for: 10m
    labels:
      severity: warning
    annotations:
      summary: "Squid内存使用率过高"
      description: "Squid内存缓存使用率超过80%"

工程实践中的挑战与应对策略

TLS 拦截的技术限制

随着 TLS 1.3 和 ECH(Encrypted Client Hello)的普及,传统的 SNI(Server Name Indication)窥探变得困难。应对策略包括:

  1. 降级协商:配置 Squid 优先使用 TLS 1.2,但需权衡安全性与可观测性
  2. 显式代理模式:对于无法拦截的流量,回退到显式代理配置
  3. 基于 IP 的过滤:作为后备方案,维护 IP 与域名的映射关系

性能优化实践

在大规模 Kubernetes 集群中,Squid 代理可能成为性能瓶颈。优化措施包括:

  1. 分层缓存架构:在集群边缘部署父代理,减少重复的 TLS 握手
  2. 连接预热:对高频访问的域名预先建立 TLS 连接
  3. 硬件加速:使用支持 TLS 硬件加速的实例类型

合规性与隐私考量

TLS 流量拦截涉及法律和隐私问题,必须:

  1. 明确告知:在组织政策中明确说明流量监控的范围和目的
  2. 最小化收集:仅拦截必要的业务流量,避免过度监控
  3. 安全存储:CA 私钥必须安全存储,定期轮换
  4. 审计日志:保留完整的访问日志用于安全审计

总结

基于 Squid 代理的 Kubernetes 出口流量控制架构,通过透明代理模式实现了 FQDN 级别的细粒度访问控制。TLS 拦截功能虽然强大,但需要精心配置 CA 证书基础设施,并考虑性能、隐私和法律合规等多方面因素。

在实际工程实践中,建议采用渐进式部署策略:首先在非生产环境验证配置,然后逐步扩大拦截范围。监控系统的建设同样重要,需要实时跟踪代理性能、错误率和安全事件。

随着云原生安全生态的发展,Squid 代理与 Service Mesh、网络策略等技术的结合,将为 Kubernetes 出口流量控制提供更加完善和自动化的解决方案。

资料来源

  1. Xebia 博客《How To Configure Squid As An Egress Gateway》(2024 年 2 月)
  2. Squid 官方 Wiki《ConfigExamples/Intercept/SslBumpExplicit》(2025 年 11 月更新)
查看归档