Nginx

How to use multiple real IP headers with nginx

by ,


In some very rare cases, you would have traffic flowing to your nginx instance from two different cloud services.
Some users will visit the site from service A, and later other users coming from service B.

The standard header for communicating end visitor IP is X-Forwarded-For. However, you may stumble on a case when the two different services will use different headers, e.g. X-Real-IP and CF-Connecting-IP.

Nginx is very flexible with its map and geo directives. And the real_ip_header directive can be set to a variable.

Let’s put those great features together and not without some duplication, achieve completion for this tricky task.
In the following example solution, some users access the site through Cloudflare and sometimes through DDos Guard service.

The following goes into http section of your nginx.conf:

set_real_ip_from 103.21.244.0/22;
set_real_ip_from 103.22.200.0/22;
set_real_ip_from 103.31.4.0/22;
# .. put all Cloudflare ranges like above

# ddos-guard.net range:
set_real_ip_from 186.2.160.0/24;

# DDoS Guard
geo $use_x_real_ip {
  default 0;
  186.2.160.0/24 1;
}

# Cloudflare
geo $use_x_cf_connecting_ip {
  default 0;
  103.21.244.0/22 1;
  103.22.200.0/22 1;
  103.31.4.0/22 1;
  # all other Cloudflare's ranges ...
}

map "$use_x_real_ip:$use_x_cf_connecting_ip" $real_ip_header {
  default 'X-Forwarded-For';
  "1:0" 'X-Real-Ip';
  "0:1" 'CF-Connecting-IP';
}

real_ip_header $real_ip_header;

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.