Client source address behind reverse proxy showing proxy IP not client

I’ve got a new Vault built and it sits behind an NGINX reverse proxy. I’m trying to source IP address restrict an approle in Vault, but I keep getting errors when trying to authenticate saying that the load balancer’s IP address isn’t in the allowed source address list. For some reason Vault isn’t picking up the Client’s original IP. Any suggestions as to what I’m doing wrong? Thanks.

NGINX:

upstream backend {
  server 192.168.1.100:8200;
}

server {
  listen 80;
  server_name public-dns-name.com;
  return 301 https://public-dns-name.com$request_uri;
}

server {
  listen 443 ssl;
  server_name public-dns-name.com;

  ssl_certificate       /etc/nginx/certs/cert.pem;
  ssl_certificate_key   /etc/nginx/certs/key.pem;
  ssl_session_cache shared:SSL:15m;
  ssl_session_timeout 10m;

  location / {
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_pass           https://backend;
  }
}

VAULT:

ui = true
api_addr = "https://public-dns-name.com"

storage "file" {
  path = "/opt/vault/data"
}

listener "tcp" {
  address       = "192.168.1.100:8200"
  tls_cert_file = "/opt/vault/tls/vault.crt"
  tls_key_file  = "/opt/vault/tls/vault.key"
  tls_client_ca_file = "/opt/vault/tls/CA.crt"
  proxy_protocol_behavior = "use_always"
}

I don’t recall having to do anything special when I used it last (not part of my current day to day) but what modules does your Nginx install have? The AI overlords have led me to believe I might have had a module present…

e.g.

nginx -V                       
nginx version: nginx/1.27.3
built by gcc 12.2.0 (Debian 12.2.0-14) 
built with OpenSSL 3.0.11 19 Sep 2023 (running with OpenSSL 3.0.15 3 Sep 2024)
TLS SNI support enabled
configure arguments: 

--prefix=/etc/nginx 
--sbin-path=/usr/sbin/nginx 
--modules-path=/usr/lib/nginx/modules 
--conf-path=/etc/nginx/nginx.conf 
--error-log-path=/var/log/nginx/error.log 
--http-log-path=/var/log/nginx/access.log 
--pid-path=/var/run/nginx.pid 
--lock-path=/var/run/nginx.lock 
--http-client-body-temp-path=/var/cache/nginx/client_temp 
--http-proxy-temp-path=/var/cache/nginx/proxy_temp 
--http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp 
--http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp 
--http-scgi-temp-path=/var/cache/nginx/scgi_temp 
--user=nginx --group=nginx 
--with-compat 
--with-file-aio 
-with-threads 
--with-http_addition_module 
--with-http_auth_request_module 
--with-http_dav_module 
--with-http_flv_module 
--with-http_gunzip_module 
--with-http_gzip_static_module 
--with-http_mp4_module 
--with-http_random_index_module 
--with-http_realip_module 
...snip...

is --with-http_realip_module present?

I updated my NGINX version to match yours and yes it does have the realip directive, but I still only see the IP address of the NGINX proxy in my vault access logs. I can get it to work with SSL passthrough, but that’s obviously not what I’m trying to do. Any other suggestions?

Ahh - maybe this? Looks like that is not present in the example Vault listener stanza.

1 Like

Yep, that was it! Thank you very much, I don’t think I would have found that nugget.

1 Like

Today was a good day - you helped me learn something new!

highfive