🤔 Introducing APISIX AI Gateway – Built for LLMs and AI workloads. Learn More

real-ip

描述

real-ip 插件允许 APISIX 通过 HTTP 请求头或 HTTP 查询字符串中传递的 IP 地址设置客户端的真实 IP。当 APISIX 位于反向代理之后时,此功能尤其有用,因为在这种情况下,代理可能会被视为请求发起客户端。

该插件在功能上类似于 NGINX 的 ngx_http_realip_module,但提供了更多的灵活性。

属性

名称类型是否必需默认值有效值描述
sourcestring内置变量,例如 http_x_forwarded_forarg_realip。变量值应为一个有效的 IP 地址,表示客户端的真实 IP 地址,可选地包含端口。
trusted_addressesarray[string]IPv4 或 IPv6 地址数组 (接受 CIDR 表示法)已知会发送正确替代地址的可信地址。此配置设置 set_real_ip_from 指令。
recursivebooleanfalse如果为 false,则将匹配可信地址之一的原始客户端地址替换为配置的 source 中发送的最后一个地址。
如果为 true,则将匹配可信地址之一的原始客户端地址替换为配置的 source 中发送的最后一个非可信地址。

NOTE

只有发送自 apisix.trusted_addresses 配置 (支持 IP 和 CIDR) 地址的 X-Forwarded-* 头才会被信任,并传递给插件或上游。如果未配置 apisix.trusted_addresses 或 ip 不在配置地址范围内的,X-Forwarded-* 头将全部被可信值覆盖。

NOTE

如果 source 属性中设置的地址丢失或者无效,该插件将不会更改客户端地址。

示例

以下示例展示了如何在不同场景中配置 real-ip

NOTE

你可以这样从 config.yaml 中获取 admin_key 并存入环境变量:

admin_key=$(yq '.deployment.admin.admin_key[0].key' conf/config.yaml | sed 's/"//g')

从 URI 参数获取真实客户端地址

以下示例演示了如何使用 URI 参数更新客户端 IP 地址。

创建如下路由:

admin-api

curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
  -H "X-API-KEY: ${admin_key}" \
  -d '{
    "id": "real-ip-route",
    "uri": "/get",
    "plugins": {
      "real-ip": {
        "source": "arg_realip",
        "trusted_addresses": ["127.0.0.0/24"]
      },
      "response-rewrite": {
        "headers": {
          "remote_addr": "$remote_addr",
          "remote_port": "$remote_port"
        }
      }
    },
    "upstream": {
      "type": "roundrobin",
      "nodes": {
        "httpbin.org:80": 1
      }
    }
  }'

adc

adc.yaml
services:
  - name: httpbin
    routes:
      - name: real-ip-route
        uris:
          - /get
        plugins:
          real-ip:
            source: arg_realip
            trusted_addresses:
              - 127.0.0.0/24
          response-rewrite:
            headers:
              remote_addr: $remote_addr
              remote_port: $remote_port
    upstream:
      type: roundrobin
      nodes:
        - host: httpbin.org
          port: 80
          weight: 1

同步配置到网关:

adc sync -f adc.yaml

aic

gateway-api

real-ip-ic.yaml
apiVersion: v1
kind: Service
metadata:
  namespace: aic
  name: httpbin-external-domain
spec:
  type: ExternalName
  externalName: httpbin.org
---
apiVersion: apisix.apache.org/v1alpha1
kind: PluginConfig
metadata:
  namespace: aic
  name: real-ip-plugin-config
spec:
  plugins:
    - name: real-ip
      config:
        source: arg_realip
        trusted_addresses:
          - 127.0.0.0/24
    - name: response-rewrite
      config:
        headers:
          remote_addr: $remote_addr
          remote_port: $remote_port
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  namespace: aic
  name: real-ip-route
spec:
  parentRefs:
    - name: apisix
  rules:
    - matches:
        - path:
            type: Exact
            value: /get
      filters:
        - type: ExtensionRef
          extensionRef:
            group: apisix.apache.org
            kind: PluginConfig
            name: real-ip-plugin-config
      backendRefs:
        - name: httpbin-external-domain
          port: 80

apisix-crd

real-ip-ic.yaml
apiVersion: apisix.apache.org/v2
kind: ApisixUpstream
metadata:
  namespace: aic
  name: httpbin-external-domain
spec:
  ingressClassName: apisix
  externalNodes:
  - type: Domain
    name: httpbin.org
---
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
  namespace: aic
  name: real-ip-route
spec:
  ingressClassName: apisix
  http:
    - name: real-ip-route
      match:
        paths:
          - /get
      upstreams:
        - name: httpbin-external-domain
      plugins:
        - name: real-ip
          config:
            source: arg_realip
            trusted_addresses:
              - 127.0.0.0/24
        - name: response-rewrite
          config:
            headers:
              remote_addr: $remote_addr
              remote_port: $remote_port

应用配置:

kubectl apply -f real-ip-ic.yaml

向路由发送带有 URL 参数中的真实 IP 和端口的请求:

curl -i "http://127.0.0.1:9080/get?realip=1.2.3.4:9080"

你应看到响应包含以下头:

remote_addr: 1.2.3.4
remote_port: 9080

从请求头获取真实客户端地址

以下示例展示了当 APISIX 位于反向代理 (例如负载均衡器) 之后时,如何设置真实客户端 IP,此时代理在 X-Forwarded-For 请求头中暴露了真实客户端 IP。

创建如下路由:

admin-api

curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
  -H "X-API-KEY: ${admin_key}" \
  -d '{
    "id": "real-ip-route",
    "uri": "/get",
    "plugins": {
      "real-ip": {
        "source": "http_x_forwarded_for",
        "trusted_addresses": ["127.0.0.0/24"]
      },
      "response-rewrite": {
        "headers": {
          "remote_addr": "$remote_addr"
        }
      }
    },
    "upstream": {
      "type": "roundrobin",
      "nodes": {
        "httpbin.org:80": 1
      }
    }
  }'

adc

adc.yaml
services:
  - name: httpbin
    routes:
      - name: real-ip-route
        uris:
          - /get
        plugins:
          real-ip:
            source: http_x_forwarded_for
            trusted_addresses:
              - 127.0.0.0/24
          response-rewrite:
            headers:
              remote_addr: $remote_addr
    upstream:
      type: roundrobin
      nodes:
        - host: httpbin.org
          port: 80
          weight: 1

同步配置到网关:

adc sync -f adc.yaml

aic

gateway-api

real-ip-ic.yaml
apiVersion: v1
kind: Service
metadata:
  namespace: aic
  name: httpbin-external-domain
spec:
  type: ExternalName
  externalName: httpbin.org
---
apiVersion: apisix.apache.org/v1alpha1
kind: PluginConfig
metadata:
  namespace: aic
  name: real-ip-plugin-config
spec:
  plugins:
    - name: real-ip
      config:
        source: http_x_forwarded_for
        trusted_addresses:
          - 127.0.0.0/24
    - name: response-rewrite
      config:
        headers:
          remote_addr: $remote_addr
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  namespace: aic
  name: real-ip-route
spec:
  parentRefs:
    - name: apisix
  rules:
    - matches:
        - path:
            type: Exact
            value: /get
      filters:
        - type: ExtensionRef
          extensionRef:
            group: apisix.apache.org
            kind: PluginConfig
            name: real-ip-plugin-config
      backendRefs:
        - name: httpbin-external-domain
          port: 80

apisix-crd

real-ip-ic.yaml
apiVersion: apisix.apache.org/v2
kind: ApisixUpstream
metadata:
  namespace: aic
  name: httpbin-external-domain
spec:
  ingressClassName: apisix
  externalNodes:
  - type: Domain
    name: httpbin.org
---
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
  namespace: aic
  name: real-ip-route
spec:
  ingressClassName: apisix
  http:
    - name: real-ip-route
      match:
        paths:
          - /get
      upstreams:
        - name: httpbin-external-domain
      plugins:
        - name: real-ip
          config:
            source: http_x_forwarded_for
            trusted_addresses:
              - 127.0.0.0/24
        - name: response-rewrite
          config:
            headers:
              remote_addr: $remote_addr

应用配置:

kubectl apply -f real-ip-ic.yaml

向路由发送请求:

curl -i "http://127.0.0.1:9080/get" \
  -H "X-Forwarded-For: 10.26.3.19"

你应看到响应包含以下头:

remote_addr: 10.26.3.19

IP 地址应对应于请求发起客户端的 IP 地址。

在多个代理之后获取真实客户端地址

以下示例展示了当 APISIX 位于多个代理之后时,如何获取真实客户端 IP,此时 X-Forwarded-For 请求头包含了一系列代理 IP 地址。

创建如下路由:

admin-api

curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
  -H "X-API-KEY: ${admin_key}" \
  -d '{
  "id": "real-ip-route",
  "uri": "/get",
  "plugins": {
    "real-ip": {
      "source": "http_x_forwarded_for",
      "recursive": true,
      "trusted_addresses": ["192.128.0.0/16", "127.0.0.1/32"]
    },
    "response-rewrite": {
      "headers": {
        "remote_addr": "$remote_addr"
      }
    }
  },
  "upstream": {
    "type": "roundrobin",
    "nodes": {
      "httpbin.org:80": 1
    }
  }
}'

adc

adc.yaml
services:
  - name: httpbin
    routes:
      - name: real-ip-route
        uris:
          - /get
        plugins:
          real-ip:
            source: http_x_forwarded_for
            recursive: true
            trusted_addresses:
              - 192.128.0.0/16
              - 127.0.0.1/32
          response-rewrite:
            headers:
              remote_addr: $remote_addr
    upstream:
      type: roundrobin
      nodes:
        - host: httpbin.org
          port: 80
          weight: 1

同步配置到网关:

adc sync -f adc.yaml

aic

gateway-api

real-ip-ic.yaml
apiVersion: v1
kind: Service
metadata:
  namespace: aic
  name: httpbin-external-domain
spec:
  type: ExternalName
  externalName: httpbin.org
---
apiVersion: apisix.apache.org/v1alpha1
kind: PluginConfig
metadata:
  namespace: aic
  name: real-ip-plugin-config
spec:
  plugins:
    - name: real-ip
      config:
        source: http_x_forwarded_for
        recursive: true
        trusted_addresses:
          - 192.128.0.0/16
          - 127.0.0.1/32
    - name: response-rewrite
      config:
        headers:
          remote_addr: $remote_addr
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  namespace: aic
  name: real-ip-route
spec:
  parentRefs:
    - name: apisix
  rules:
    - matches:
        - path:
            type: Exact
            value: /get
      filters:
        - type: ExtensionRef
          extensionRef:
            group: apisix.apache.org
            kind: PluginConfig
            name: real-ip-plugin-config
      backendRefs:
        - name: httpbin-external-domain
          port: 80

apisix-crd

real-ip-ic.yaml
apiVersion: apisix.apache.org/v2
kind: ApisixUpstream
metadata:
  namespace: aic
  name: httpbin-external-domain
spec:
  ingressClassName: apisix
  externalNodes:
  - type: Domain
    name: httpbin.org
---
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
  namespace: aic
  name: real-ip-route
spec:
  ingressClassName: apisix
  http:
    - name: real-ip-route
      match:
        paths:
          - /get
      upstreams:
        - name: httpbin-external-domain
      plugins:
        - name: real-ip
          config:
            source: http_x_forwarded_for
            recursive: true
            trusted_addresses:
              - 192.128.0.0/16
              - 127.0.0.1/32
        - name: response-rewrite
          config:
            headers:
              remote_addr: $remote_addr

应用配置:

kubectl apply -f real-ip-ic.yaml

向路由发送请求:

curl -i "http://127.0.0.1:9080/get" \
  -H "X-Forwarded-For: 127.0.0.2, 192.128.1.1, 127.0.0.1"

你应看到响应包含以下头:

remote_addr: 127.0.0.2