Hello,
I'm having some issues with getting X-Forwarded-For set consistently for upstream proxy requests. The server runs Nginx/OpenResty in front of Apache, and has domains hosted behind Cloudflare as well as direct. The ones behind Cloudflare show the correct X-Forwarded-For header being set, using (snippet):
http {
server {
location ~ .* {
proxy_set_header X-Forwarded-For $http_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
}
}
However, when I receive a direct request, which does not include X-Forwarded-For, $http_x_forwarded_for, $proxy_add_x_forwarded_for, $http_x_real_ip are empty, and I'm unable to set the header to $remote_addr (shows correct IP). If I try adding this in the server {} block:
if ($http_x_forwarded_for = '') {
set $http_x_forwarded_for $remote_addr;
}
I get:
nginx: [emerg] the duplicate "http_x_forwarded_for" variable in /usr/local/openresty/nginx/conf/nginx.conf:131
nginx: configuration file /usr/local/openresty/nginx/conf/nginx.conf test failed
The above works to set $http_x_real_ip, but then I end up with direct connections passing Apache the client IP through X-Real-IP, and proxied connections (from Cloudflare) set X-Forwarded-For.
The log format I'm using to verify both $http_x_forwarded_for and $http_x_real_ip is:
log_format json_combined escape=json
'{'
'"id":"$zid",'
'"upstream_cache_status":"$upstream_cache_status",'
'"remote_addr":"$remote_addr",'
'"remote_user":"$remote_user",'
'"stime":"$msec",'
'"timestamp":"$time_local",'
'"host":"$host",'
'"server_addr":"$server_addr",'
'"server_port":"$proxy_port",'
'"request":"$request",'
'"status": "$status",'
'"body_bytes_sent":"$body_bytes_sent",'
'"http_referer":"$http_referer",'
'"http_user_agent":"$http_user_agent",'
'"http_x_forwarded_for":"$http_x_forwarded_for",'
'"http_x_real_ip":"$http_x_real_ip",'
'"request_type":"$request_type",'
'"upstream_addr":"$upstream_addr",'
'"upstream_status":"$upstream_status",'
'"upstream_connect_time":"$upstream_connect_time",'
'"upstream_header_time":"$upstream_header_time",'
'"upstream_response_time":"$upstream_response_time",'
'"country":"$country_code",'
'"request_time":"$request_time"'
'}';
How can I consistently pass the backend service an X-Forwarded-For header, with the client IP, regardless of it being a direct request or proxied through Cloudflare/some other CDN?
Thanks!
--Andrei