侧边栏壁纸
博主头像
青菜-halo2 博主等级

行动起来,活在当下

  • 累计撰写 74 篇文章
  • 累计创建 6 个标签
  • 累计收到 7 条评论

目 录CONTENT

文章目录

解决 Kubernetes nginx-ingress 无法获取真实客户端 IP 的问题

Administrator
2025-10-31 / 0 评论 / 0 点赞 / 49 阅读 / 0 字

在实际生产环境中,我们经常需要准确记录客户端的真实 IP 地址用于安全审计、访问分析等目的。本文将详细介绍如何通过配置 nginx-ingress 来获取并记录客户端的真实 IP。

问题背景

在 Kubernetes 集群中使用 nginx-ingress 作为入口控制器时,经常会发现访问日志中的客户端 IP 并不是真实的用户 IP,而是负载均衡器或中间代理的 IP。这是因为请求在到达应用之前,可能经过了多级代理:

客户端 → 云服务商负载均衡器 → nginx-ingress Pod → 业务应用 Pod

在这个过程中,如果没有正确配置,nginx-ingress 只能看到前一跳(负载均衡器)的 IP 地址。

解决方案

通过在 nginx-ingress 的 ConfigMap 中添加以下配置,可以解决这个问题:

apiVersion: v1
kind: ConfigMap
metadata:
  name: ingress-nginx-controller
  namespace: ingress-nginx
data:
  use-forwarded-headers: "true"
  compute-full-forwarded-for: "true"
  forwarded-for-header: "X-Forwarded-For"
  use-proxy-protocol: "false"  # 如果 LB 支持 PROXY 协议,可以设为 true
  enable-real-ip: "true"
  real-ip-header: "X-Forwarded-For"
  real-ip-recursive: "true"

配置详解

核心配置项说明

  1. use-forwarded-headers: "true"

    • 启用对 X-Forwarded-* 头部的处理

    • 这告诉 nginx 信任并使用上游代理设置的转发头部

  2. compute-full-forwarded-for: "true"

    • 完整计算 X-Forwarded-For 头部

    • 确保所有的代理 IP 都被正确记录在链条中

  3. forwarded-for-header: "X-Forwarded-For"

    • 指定用于转发 IP 的头部字段

    • 通常使用标准的 X-Forwarded-For

  4. enable-real-ip: "true"

    • 启用真实 IP 模块

    • 这是解析客户端真实 IP 的核心功能

  5. real-ip-header: "X-Forwarded-For"

    • 指定包含真实 IP 的头部字段

    • forwarded-for-header 保持一致

  6. real-ip-recursive: "true"

    • 启用递归查找真实 IP

    • 当存在多个代理时,会从右向左查找第一个不受信任的 IP

  7. use-proxy-protocol: "false"

    • 是否启用 PROXY 协议

    • 如果您的负载均衡器支持 PROXY 协议(如 AWS ELB、HAProxy),可以设置为 "true"

配置的安全考虑

这些配置通常不会影响现有的功能,因为:

  • 向后兼容:这些配置主要是增强功能,不会破坏现有行为

  • 渐进式增强:只是在现有日志基础上添加了更多信息

  • 标准协议:使用的都是标准的 HTTP 头部和 nginx 指令

操作步骤

1. 编辑 ConfigMap

kubectl edit configmap ingress-nginx-controller -n ingress-nginx

2. 添加配置项

data 部分添加上述配置:

data:
  use-forwarded-headers: "true"
  compute-full-forwarded-for: "true"
  forwarded-for-header: "X-Forwarded-For"
  use-proxy-protocol: "false"
  enable-real-ip: "true"
  real-ip-header: "X-Forwarded-For"
  real-ip-recursive: "true"

3. 重启 nginx-ingress Pod

配置更新后,需要重启 nginx-ingress 控制器以使配置生效:

kubectl rollout restart deployment/ingress-nginx-controller -n ingress-nginx

或者删除 Pod 让 Deployment 自动重建:

kubectl delete pod -l app.kubernetes.io/name=ingress-nginx -n ingress-nginx

验证配置

方法一:检查 nginx 配置

# 进入 nginx-ingress pod
kubectl exec -it <ingress-pod-name> -n ingress-nginx -- cat /etc/nginx/nginx.conf
​
# 检查 real_ip 相关配置
kubectl exec -it <ingress-pod-name> -n ingress-nginx -- grep -i real_ip /etc/nginx/nginx.conf

方法二:创建测试服务

创建一个简单的 echo 服务来验证接收到的头部信息:

apiVersion: v1
kind: Service
metadata:
  name: echo-headers
spec:
  ports:
  - port: 80
    targetPort: 8080
  selector:
    app: echo-headers
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: echo-headers
spec:
  replicas: 1
  selector:
    matchLabels:
      app: echo-headers
  template:
    metadata:
      labels:
        app: echo-headers
    spec:
      containers:
      - name: echo-headers
        image: mendhak/http-https-echo:latest
        ports:
        - containerPort: 8080

访问该服务,检查返回的头部信息中的 x-forwarded-for 字段。

方法三:检查日志格式

确保日志格式包含真实 IP 信息:

# 可以同时配置自定义日志格式
data:
  # ... 其他配置
  log-format-upstream: '{"time": "$time_iso8601", "remote_addr": "$remote_addr", "real_ip": "$realip_remote_addr", "x_forwarded_for": "$http_x_forwarded_for", "status": "$status", "host": "$host", "path": "$uri"}'

云服务商特殊配置

AWS ELB

如果使用 AWS ELB,需要额外配置:

# Service 配置
apiVersion: v1
kind: Service
metadata:
  name: ingress-nginx-controller
  namespace: ingress-nginx
  annotations:
    service.beta.kubernetes.io/aws-load-balancer-proxy-protocol: "*"
spec:
  type: LoadBalancer
  externalTrafficPolicy: Local  # 重要配置
  # ... 其他配置

同时在 ConfigMap 中启用 proxy protocol:

data:
  use-proxy-protocol: "true"
  # ... 其他配置

其他云服务商

对于 GCP、Azure 等其他云服务商,确保正确设置 externalTrafficPolicy: Local

spec:
  externalTrafficPolicy: Local

注意事项

  1. 性能影响externalTrafficPolicy: Local 可能会影响负载均衡,但这是保留真实 IP 的必要配置

  2. 安全考虑:确保只信任必要的代理,避免 IP 欺骗

  3. 测试验证:在生产环境应用前,务必在测试环境充分验证

  4. 监控告警:配置变更后,密切关注相关监控指标

总结

通过正确的 nginx-ingress 配置,我们可以可靠地获取客户端的真实 IP 地址。关键配置包括启用转发头部处理、设置真实 IP 解析参数,以及正确配置 Service 的 externalTrafficPolicy

如果您在实施过程中遇到任何问题,欢迎在评论区留言讨论!

0

评论区