diff --git a/docs/en/latest/plugins/real-ip.md b/docs/en/latest/plugins/real-ip.md index 0bd945675e8f..c2ccec63bc24 100644 --- a/docs/en/latest/plugins/real-ip.md +++ b/docs/en/latest/plugins/real-ip.md @@ -5,7 +5,7 @@ keywords: - API Gateway - Plugin - Real IP -description: This document contains information about the Apache APISIX real-ip Plugin. +description: The real-ip plugin allows Apache APISIX to set the client's real IP by the IP address passed in the HTTP header or HTTP query string. --- -## Description - -The `real-ip` Plugin is used to dynamically change the client's IP address and port as seen by APISIX. - -This is more flexible but functions similarly to Nginx's [ngx_http_realip_module](https://nginx.org/en/docs/http/ngx_http_realip_module.html). + + + -:::info IMPORTANT +## Description -This Plugin requires APISIX to run on [APISIX-Runtime](../FAQ.md#how-do-i-build-the-apisix-runtime-environment). +The `real-ip` Plugin allows APISIX to set the client's real IP by the IP address passed in the HTTP header or HTTP query string. This is particularly useful when APISIX is behind a reverse proxy since the proxy could act as the request-originating client otherwise. -::: +The Plugin is functionally similar to NGINX's [ngx_http_realip_module](https://nginx.org/en/docs/http/ngx_http_realip_module.html) but offers more flexibility. ## Attributes -| Name | Type | Required | Valid values | Description | -|-------------------|---------------|----------|-----------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| source | string | True | Any Nginx variable like `arg_realip` or `http_x_forwarded_for`. | Dynamically sets the client's IP address and an optional port, or the client's host name, from APISIX's view. | -| trusted_addresses | array[string] | False | List of IPs or CIDR ranges. | Dynamically sets the `set_real_ip_from` field. | -| recursive | boolean | False | True to enable, false to disable, default is false | If recursive search is disabled, the original client address that matches one of the trusted addresses is replaced by the last address sent in the configured `source`. If recursive search is enabled, the original client address that matches one of the trusted addresses is replaced by the last non-trusted address sent in the configured `source`. | +| Name | Type | Required | Default | Valid values | Description | +|-----------|---------|----------|---------|----------------|---------------| +| source | string | True | | |A built-in [APISIX variable](https://apisix.apache.org/docs/apisix/apisix-variable/) or [NGINX variable](https://nginx.org/en/docs/varindex.html), such as `http_x_forwarded_for` or `arg_realip`. The variable value should be a valid IP address that represents the client's real IP address, with an optional port.| +| trusted_addresses | array[string] | False | | array of IPv4 or IPv6 addresses (CIDR notation acceptable) | Trusted addresses that are known to send correct replacement addresses. This configuration sets the [`set_real_ip_from`](https://nginx.org/en/docs/http/ngx_http_realip_module.html#set_real_ip_from) directive. | +| recursive | boolean | False | False | | If false, replace the original client address that matches one of the trusted addresses by the last address sent in the configured `source`.
If true, replace the original client address that matches one of the trusted addresses by the last non-trusted address sent in the configured `source`. | :::note - If the address specified in `source` is missing or invalid, the Plugin would not change the client address. - ::: -## Enable Plugin +## Examples -The example below enables the `real-ip` Plugin on the specified Route: +The examples below demonstrate how you can configure `real-ip` in different scenarios. :::note + You can fetch the `admin_key` from `config.yaml` and save to an environment variable with the following command: ```bash @@ -66,58 +63,140 @@ admin_key=$(yq '.deployment.admin.admin_key[0].key' conf/config.yaml | sed 's/"/ ::: +### Obtain Real Client Address From URI Parameter + +The following example demonstrates how to update the client IP address with a URI parameter. + +Create a Route as follows. You should configure `source` to obtain value from the URL parameter `realip` using [APISIX variable](https://apisix.apache.org/docs/apisix/apisix-variable/) or [NGINX variable](https://nginx.org/en/docs/varindex.html). Use the `response-rewrite` Plugin to set response headers to verify if the client IP and port were actually updated. + ```shell -curl -i http://127.0.0.1:9180/apisix/admin/routes/1 -H "X-API-KEY: $admin_key" -X PUT -d ' -{ - "uri": "/index.html", +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" - } + "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": { - "127.0.0.1:1980": 1 - } + "type": "roundrobin", + "nodes": { + "httpbin.org:80": 1 + } } -}' + }' ``` -## Example usage - -After you have enabled the Plugin as mentioned above, you can test it as shown below: +Send a request to the Route with real IP and port in the URL parameter: ```shell -curl 'http://127.0.0.1:9080/index.html?realip=1.2.3.4:9080' -I +curl -i "http://127.0.0.1:9080/get?realip=1.2.3.4:9080" ``` -```shell -... +You should see the response includes the following header: + +```text remote-addr: 1.2.3.4 remote-port: 9080 ``` -## Delete Plugin +### Obtain Real Client Address From Header + +The following example shows how to set the real client IP when APISIX is behind a reverse proxy, such as a load balancer when the proxy exposes the real client IP in the [`X-Forwarded-For`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For) header. -To remove the `real-ip` Plugin, you can delete the corresponding JSON configuration from the Plugin configuration. APISIX will automatically reload and you do not have to restart for this to take effect. +Create a Route as follows. You should configure `source` to obtain value from the request header `X-Forwarded-For` using [APISIX variable](https://apisix.apache.org/docs/apisix/apisix-variable/) or [NGINX variable](https://nginx.org/en/docs/varindex.html). Use the `response-rewrite` Plugin to set a response header to verify if the client IP was actually updated. ```shell -curl http://127.0.0.1:9180/apisix/admin/routes/1 -H "X-API-KEY: $admin_key" -X PUT -d ' -{ - "uri": "/index.html", - "upstream": { - "type": "roundrobin", - "nodes": { - "127.0.0.1:1980": 1 +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 + } } + }' +``` + +Send a request to the Route: + +```shell +curl -i "http://127.0.0.1:9080/get" +``` + +You should see a response including the following header: + +```text +remote-addr: 10.26.3.19 +``` + +The IP address should correspond to the IP address of the request-originating client. + +### Obtain Real Client Address Behind Multiple Proxies + +The following example shows how to get the real client IP when APISIX is behind multiple proxies, which causes [`X-Forwarded-For`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For) header to include a list of proxy IP addresses. + +Create a Route as follows. You should configure `source` to obtain value from the request header `X-Forwarded-For` using [APISIX variable](https://apisix.apache.org/docs/apisix/apisix-variable/) or [NGINX variable](https://nginx.org/en/docs/varindex.html). Set `recursive` to `true` so that the original client address that matches one of the trusted addresses is replaced by the last non-trusted address sent in the configured `source`. Then, use the `response-rewrite` Plugin to set a response header to verify if the client IP was actually updated. + +```shell +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.0/24"] + }, + "response-rewrite": { + "headers": { + "remote_addr": "$remote_addr" + } + } + }, + "upstream": { + "type": "roundrobin", + "nodes": { + "httpbin.org:80": 1 + } + } }' ``` + +Send a request to the Route: + +```shell +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" +``` + +You should see a response including the following header: + +```text +remote-addr: 127.0.0.2 +``` diff --git a/docs/zh/latest/plugins/real-ip.md b/docs/zh/latest/plugins/real-ip.md index 1066c507ed86..d3ea92ddfd2f 100644 --- a/docs/zh/latest/plugins/real-ip.md +++ b/docs/zh/latest/plugins/real-ip.md @@ -5,7 +5,7 @@ keywords: - API 网关 - Plugin - Real IP -description: 本文介绍了关于 Apache APISIX `real-ip` 插件的基本信息及使用方法。 +description: real-ip 插件允许 Apache APISIX 通过 HTTP 请求头或 HTTP 查询字符串中传递的 IP 地址设置客户端的真实 IP。 --- -## 描述 - -`real-ip` 插件用于动态改变传递到 Apache APISIX 的客户端的 IP 地址和端口。 - -它的工作方式和 NGINX 中的 `ngx_http_realip_module` 模块一样,并且更加灵活。 + + + -:::info IMPORTANT +## 描述 -该插件要求 APISIX 运行在 [APISIX-Runtime](../FAQ.md#如何构建-apisix-runtime-环境) 上。 +`real-ip` 插件允许 APISIX 通过 HTTP 请求头或 HTTP 查询字符串中传递的 IP 地址设置客户端的真实 IP。当 APISIX 位于反向代理之后时,此功能尤其有用,因为否则代理可能会被视为请求发起客户端。 -::: +该插件在功能上类似于 NGINX 的 [ngx_http_realip_module](https://nginx.org/en/docs/http/ngx_http_realip_module.html),但提供了更多的灵活性。 ## 属性 -| 名称 | 类型 | 必选项 | 有效值 | 描述 | -|-------------------|---------------|--|-------------------------------------------------------------|----------------------------------------------------------------------| -| source | string | 是 | 任何 NGINX 变量,如 `arg_realip` 或 `http_x_forwarded_for` 。 | 动态设置客户端的 IP 地址和端口,或主机名。如果该值不包含端口,则不会更改客户端的端口。 | -| trusted_addresses | array[string] | 否 | IP 或 CIDR 范围列表。 | 动态设置 `set_real_ip_from` 字段。 | -| recursive | boolean | 否 | true 或者 false,默认是 false | 如果禁用递归搜索,则与受信任地址之一匹配的原始客户端地址将替换为配置的`source`中发送的最后一个地址。如果启用递归搜索,则与受信任地址之一匹配的原始客户端地址将替换为配置的`source`中发送的最后一个非受信任地址。 | +| 名称 | 类型 | 是否必需 | 默认值 | 有效值 | 描述 | +|-------------------|---------------|----------|--------|----------------------------|----------------------------------------------------------------------| +| source | string | 是 | | | 内置变量,例如 `http_x_forwarded_for` 或 `arg_realip`。变量值应为一个有效的 IP 地址,表示客户端的真实 IP 地址,可选地包含端口。 | +| trusted_addresses | array[string] | 否 | | IPv4 或 IPv6 地址数组(接受 CIDR 表示法) | 已知会发送正确替代地址的可信地址。此配置设置 [`set_real_ip_from`](https://nginx.org/en/docs/http/ngx_http_realip_module.html#set_real_ip_from) 指令。 | +| recursive | boolean | 否 | false | | 如果为 false,则将匹配可信地址之一的原始客户端地址替换为配置的 `source` 中发送的最后一个地址。
如果为 true,则将匹配可信地址之一的原始客户端地址替换为配置的 `source` 中发送的最后一个非可信地址。 | :::note - 如果 `source` 属性中设置的地址丢失或者无效,该插件将不会更改客户端地址。 - ::: -## 启用插件 +## 示例 -以下示例展示了如何在指定路由中启用 `real-ip` 插件: +以下示例展示了如何在不同场景中配置 `real-ip`。 :::note @@ -67,60 +63,140 @@ admin_key=$(yq '.deployment.admin.admin_key[0].key' conf/config.yaml | sed 's/"/ ::: +### 从 URI 参数获取真实客户端地址 + +以下示例演示了如何使用 URI 参数更新客户端 IP 地址。 + +创建如下路由。您应配置 `source` 以使用 [APISIX 变量](https://apisix.apache.org/docs/apisix/apisix-variable/)或者 [NGINX 变量](https://nginx.org/en/docs/varindex.html)从 URL 参数 `realip` 获取值。使用 `response-rewrite` 插件设置响应头,以验证客户端 IP 和端口是否实际更新。 + ```shell -curl -i http://127.0.0.1:9180/apisix/admin/routes/1 \ --H "X-API-KEY: $admin_key" -X PUT -d ' -{ - "uri": "/index.html", +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" - } + "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": { - "127.0.0.1:1980": 1 - } + "type": "roundrobin", + "nodes": { + "httpbin.org:80": 1 + } } -}' + }' ``` -## 测试插件 - -通过上述命令启用插件后,可以使用如下命令测试插件是否启用成功: +向路由发送带有 URL 参数中的真实 IP 和端口的请求: ```shell -curl 'http://127.0.0.1:9080/index.html?realip=1.2.3.4:9080' -I +curl -i "http://127.0.0.1:9080/get?realip=1.2.3.4:9080" ``` -```shell -... +您应看到响应包含以下头: + +```text remote-addr: 1.2.3.4 remote-port: 9080 ``` -## 删除插件 +### 从请求头获取真实客户端地址 + +以下示例展示了当 APISIX 位于反向代理(例如负载均衡器)之后时,如何设置真实客户端 IP,此时代理在 [`X-Forwarded-For`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For) 请求头中暴露了真实客户端 IP。 -当你需要禁用 `real-ip` 插件时,可以通过以下命令删除相应的 JSON 配置,APISIX 将会自动重新加载相关配置,无需重启服务: +创建如下路由。您应配置 `source` 以使用 [APISIX 变量](https://apisix.apache.org/docs/apisix/apisix-variable/)或者 [NGINX 变量](https://nginx.org/en/docs/varindex.html)从请求头 `X-Forwarded-For` 获取值。使用 response-rewrite 插件设置响应头,以验证客户端 IP 是否实际更新。 ```shell -curl http://127.0.0.1:9180/apisix/admin/routes/1 \ --H "X-API-KEY: $admin_key" -X PUT -d ' -{ - "uri": "/index.html", - "upstream": { - "type": "roundrobin", - "nodes": { - "127.0.0.1:1980": 1 +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 + } + } + }' +``` + +向路由发送请求: + +```shell +curl -i "http://127.0.0.1:9080/get" +``` + +您应看到响应包含以下头: + +```text +remote-addr: 10.26.3.19 +``` + +IP 地址应对应于请求发起客户端的 IP 地址。 + +### 在多个代理之后获取真实客户端地址 + +以下示例展示了当 APISIX 位于多个代理之后时,如何获取真实客户端 IP,此时 [`X-Forwarded-For`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For) 请求头包含了一系列代理 IP 地址。 + +创建如下路由。您应配置 `source` 以使用 [APISIX 变量](https://apisix.apache.org/docs/apisix/apisix-variable/)或者 [NGINX 变量](https://nginx.org/en/docs/varindex.html)从请求头 `X-Forwarded-For` 获取值。将 `recursive` 设置为 `true`,以便将匹配可信地址之一的原始客户端地址替换为配置的 `source` 中发送的最后一个非可信地址。然后,使用 `response-rewrite` 插件设置响应头,以验证客户端 IP 是否实际更新。 + +```shell +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.0/24"] + }, + "response-rewrite": { + "headers": { + "remote_addr": "$remote_addr" + } } + }, + "upstream": { + "type": "roundrobin", + "nodes": { + "httpbin.org:80": 1 + } + } }' ``` + +向路由发送请求: + +```shell +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" +``` + +您应看到响应包含以下头: + +```text +remote-addr: 127.0.0.2 +```