real-ip
描述#
real-ip 插件允许 APISIX 通过 HTTP 请求头或 HTTP 查询字符串中传递的 IP 地址设置客户端的真实 IP。当 APISIX 位于反向代理之后时,此功能尤其有用,因为在这种情况下,代理可能会被视为请求发起客户端。
该插件在功能上类似于 NGINX 的 ngx_http_realip_module,但提供了更多的灵活性。
属性#
| 名称 | 类型 | 是否必需 | 默认值 | 有效值 | 描述 |
|---|---|---|---|---|---|
| source | string | 是 | 内置变量,例如 http_x_forwarded_for 或 arg_realip。变量值应为一个有效的 IP 地址,表示客户端的真实 IP 地址,可选地包含端口。 | ||
| trusted_addresses | array[string] | 否 | IPv4 或 IPv6 地址数组 (接受 CIDR 表示法) | 已知会发送正确替代地址的可信地址。此配置设置 set_real_ip_from 指令。 | |
| recursive | boolean | 否 | false | 如果为 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
- ADC
- Ingress Controller
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
}
}
}'
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
- Gateway API
- APISIX CRD
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
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
- ADC
- Ingress Controller
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
}
}
}'
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
- Gateway API
- APISIX CRD
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
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
- ADC
- Ingress Controller
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
}
}
}'
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
- Gateway API
- APISIX CRD
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
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