Skip to content

Latest commit

 

History

History
202 lines (163 loc) · 7.42 KB

real-ip.md

File metadata and controls

202 lines (163 loc) · 7.42 KB
title keywords description
real-ip
Apache APISIX
API Gateway
Plugin
Real IP
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 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 but offers more flexibility.

Attributes

Name Type Required Default Valid values Description
source string True A built-in APISIX variable or NGINX variable, 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 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. :::

Examples

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:

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

:::

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 or NGINX variable. Use the response-rewrite Plugin to set response headers to verify if the client IP and port were actually updated.

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
      }
    }
  }'

Send a request to the Route with real IP and port in the URL parameter:

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

You should see the response includes the following header:

remote-addr: 1.2.3.4
remote-port: 9080

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 header.

Create a Route as follows. You should configure source to obtain value from the request header X-Forwarded-For using APISIX variable or NGINX variable. Use the response-rewrite Plugin to set a response header to verify if the client IP was actually updated.

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:

curl -i "http://127.0.0.1:9080/get"

You should see a response including the following header:

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 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 or NGINX variable. 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.

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:

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:

remote-addr: 127.0.0.2