Skip to main content

real-ip

Takes the client address from a header or variable behind a proxy.

Category GeneralAdd it to Route, Service, Consumer, Consumer group, Global rule, Plugin configEngine plugin real-ipPriority 23000

What it does​

Behind a load balancer every request comes from the load balancer's address, so the gateway cannot tell the clients apart. real-ip reads each client's own address from the header the load balancer writes it into, X-Forwarded-For for example. That address becomes the client address the plugins of the route see. limit-count then counts each client on its own, and your backend receives the address in X-Real-IP.

It believes the header only from the addresses listed under Trusted addresses, your load balancer's. A request from anywhere else keeps its own address. Left empty, it believes every client, and one that reaches a gateway node without passing the load balancer can claim any address.

When to use it​

  • Gateway nodes behind a load balancer or proxy, where every request arrives from the load balancer's address.
  • A limit per client with limit-count behind a load balancer, counted by each client's own address rather than the load balancer's.
  • A backend that logs or checks the caller's address and reads it from X-Real-IP.
  • A load balancer that sends the address in a header of its own, X-Real-IP for example, named under Source.

Guides​

Pages that walk through a job with real-ip, step by step.

Set it up​

Read each client's address from X-Forwarded-For, believed from your load balancer only​

real-ip believes the header only from the addresses under Trusted addresses: list every address your load balancer connects to the gateway from.

Set Source to http_x_forwarded_for and fill Trusted addresses as in the JSON below.

The console's Add plugin panel, filled with this example.
real-ip · as the console saves it
{
"source": "http_x_forwarded_for",
"trusted_addresses": [
"10.0.0.21",
"10.0.0.22"
]
}

What you will see​

  • Your backend receives the client's address in X-Real-IP: a request your load balancer forwards with 203.0.113.7 last in X-Forwarded-For arrives with X-Real-IP: 203.0.113.7.
  • Only the last address counts: an address the client wrote into the header itself, 198.51.100.66 in X-Forwarded-For: 198.51.100.66, 203.0.113.7, is not used.
  • The header reaches your backend as it came, with the client's address added once more at the end, X-Forwarded-For: 198.51.100.66, 203.0.113.7, 203.0.113.7: the first address is one a client can write, the last is the one the load balancer saw.
  • A limit-count on the same route that counts by client address counts each client under its own address. Once 203.0.113.7 has used its count it is answered 429, while another client behind the same load balancer still passes.
  • With Recursive off the last address is taken even when it is another proxy's: a request whose header ends in 192.0.2.10 arrives with X-Real-IP: 192.0.2.10.
  • The route is matched before real-ip runs. A route whose Client addresses leave 203.0.113.7 out still takes its request, because the request arrives from the load balancer, and the backend still receives X-Real-IP: 203.0.113.7.
  • ip-restriction on the same route acts after real-ip: a client inside its allow list passes, and one outside it is answered 403.

More scenarios​

Read the address from X-Real-IP when your load balancer sends that header

Source http_x_real_ip reads the X-Real-IP header.

Set Source to http_x_real_ip and fill Trusted addresses as in the JSON below.

real-ip · as the console saves it
{
"source": "http_x_real_ip",
"trusted_addresses": [
"10.0.0.21",
"10.0.0.22"
]
}

What you will see​

  • A request your load balancer forwards with X-Real-IP: 203.0.113.7 is taken as coming from 203.0.113.7, and your backend receives X-Real-IP: 203.0.113.7.
Skip a proxy in front of your load balancer with Recursive

List the proxy's addresses in Trusted addresses beside the load balancer's.

Set Source to http_x_forwarded_for, fill Trusted addresses as in the JSON below and turn on Recursive.

real-ip · as the console saves it
{
"source": "http_x_forwarded_for",
"trusted_addresses": [
"10.0.0.21",
"10.0.0.22",
"192.0.2.0/24"
],
"recursive": true
}

What you will see​

  • With Recursive on, a request that arrives as X-Forwarded-For: 203.0.113.7, 192.0.2.10, where 192.0.2.10 is a proxy inside a range listed in Trusted addresses, reaches your backend with X-Real-IP: 203.0.113.7, the client in front of that proxy.
Without Trusted addresses, any client can name its own address

Shown as a warning: set Trusted addresses to your load balancer's addresses, as the first example does.

Set Source to http_x_forwarded_for.

real-ip · as the console saves it
{
"source": "http_x_forwarded_for"
}

What you will see​

  • A client that reaches the gateway directly and writes 198.51.100.66 into X-Forwarded-For itself is taken for it: your backend receives X-Real-IP: 198.51.100.66.
  • With limit-count counting by client address, such a client is never refused: each request that names a new address starts a count of its own and is answered 200.

Things to know​

  • Trusted addresses — Left empty, the header is believed from every client. One that reaches a gateway node directly can write any address into X-Forwarded-For. Under limit-count counting by client address, each new address starts a fresh count, so it is never refused.
  • The route itself is matched before its plugins run. Its Client addresses and a client-address condition under Conditions still see the load balancer's address, so they cannot let clients in by their own address. ip-restriction on the same route acts after real-ip and can.
  • Trusted addresses — A request from an address that is not listed keeps its own address, whatever header it sends.
  • Trusted addresses — Every address inside a listed range is believed, so a range trusts every machine in it.
  • AdviceList only the addresses your load balancer connects from, not the whole network it sits in.
  • Source — With http_x_forwarded_for the last address of the header is taken, the one your load balancer added; an address a client wrote in front of it is not used.
  • Recursive — Off, the last address of the header is taken even when it belongs to another proxy, 192.0.2.10 for example.
  • Recursive — On, the addresses listed under Trusted addresses are skipped from the end of the header and the address in front of them is taken: list a proxy that stands in front of your load balancer there as well.
  • Your backend also receives X-Forwarded-For as it came, with the client's address added once more at the end, so its first address is whatever the client wrote there.
  • AdviceIn your backend, read the client's address from X-Real-IP, or from the last address of X-Forwarded-For, never from the first.

Settings​

The fields as the console shows them, section by section.

SourcesourcestringRequired

The request variable the client address is read from, such as http_x_forwarded_for for a header or arg_realip for a query parameter.

at least 1 character · example http_x_forwarded_for
Trusted addressestrusted_addressesarray of strings

Addresses whose forwarded value is believed, such as your load balancers’ 10.0.0.21; left empty, the value every client sends is believed. A request from anywhere else keeps its own address.

at least 1 item
Recursiverecursivebooleandefault false

Walks the chain of forwarded addresses from the end, skipping the trusted ones, to find the first address that is not trusted.

Every plugin also has Enabled, Priority, Filter, Error response and Pre-function: see Plugin execution settings.

G8 dev · Apache APISIX® 3.19.0
Apache, Apache APISIX and APISIX are trademarks of The Apache Software Foundation.
Facts
Category
General
Add it to
Route, Service, Consumer, Consumer group, Global rule, Plugin config
Engine plugin
real-ip
Priority
23000