Nginx real_ip_recursive with matomo; what to do from multiple sources

Hi. I will try to detail this as easy as possible, maybe this will help more people in the future :

Current setup :

We have an on-premise matomo instance in our corporate environment. It tracks several websites. It resides on a server as a docker container, with another docker container containing an nginx reverse proxy to access matomo (mostly to handle tls).

Current issue :

Some tracked websites are accessed from the internal network (other teams, from, some are accessed by our users from VPN (from, some are accessed from the outside world (load balancers IPs are in Docker containers talk through network (reverse proxy).

We usually either get :
client -> vpn -> reverse proxy -> matomo
client -> internal -> reverse proxy -> matomo
client -> outsideworld -> reverse proxy -> matomo

Currently, Matomo shows these IPs as source in the UI and not the clients IPs. We would like to log the real clients IPs.

Current config :

Regarding proxy configurations (faq/how-to-install/faq_98/) we are using the following in the config.ini.php file :

; Uncomment line below if you use a standard proxy
proxy_client_headers[] = HTTP_X_FORWARDED_FOR
proxy_host_headers[] = HTTP_X_FORWARDED_HOST

and nginx.conf :

#Matomo nginx config
#made by Quardah Sept 11th 2020
#inspired by :

server {

    listen 443 ssl;
    access_log /var/log/nginx/matomo.access.log;
    error_log /var/log/nginx/matomo.error.log;
    ssl_certificate /etc/nginx/conf.d/matomo.internal.corp.pem;
    ssl_certificate_key /etc/nginx/conf.d/matomo.key;

    add_header Referrer-Policy origin always; # make sure outgoing links don't show the URL to the Matomo instance
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-XSS-Protection "1; mode=block" always;
    client_max_body_size 0;
    real_ip_header X-Forwarded-For;
    real_ip_recursive on;

    location / {
        proxy_read_timeout  900;
        proxy_pass_header   Server;
        proxy_cookie_path   ~*^/.* /;
        proxy_set_header    X-Forwarded-Port  $server_port;
        proxy_set_header    X-Forwarded-Proto $http_x_forwarded_proto;
        proxy_set_header    X-Forwarded-For   $remote_addr;
        proxy_set_header    X-Forwarded-Host  $http_host;
# vim: filetype=nginx

My Understanding :

Using these three documentations :

nginx documentation on core modules (ngx_http_core_module.html)

I figured out the remote_addr string should contain the client_ip, and it’s recursively stacked in X-Forwarded-For header.

But i just can’t figure out how to always point to the client IP.

We could also do with simply displaying all X-Forwarded-For IPs to know what path the tracker takes to report the action. If that’s possible that would also be nice and do the job.

The most important ones are the ones coming from clients from the outside world (we need this info) but all their records have IPs in the

Please let me know what you think, i can also post some more informations if you need.

Thank you for your time.


Me again.

Because of the new user link limitation i will post my two additional links here (trusted sources) for the post to be complete.

Here is the installation faq page in question from official matomo doc :

Here is the nginx documentation on core module :

Thank you and sorry for circumventing the law here :slight_smile: I’m just trying to make sure anyone trying to help me will have the same info i had.

Thank you for your time again.

Hello folks, me again with further findings.

I have tried the following today to no avail :

We changed matomo configuration to use the following :

; Uncomment line below if you use another proxy (that sets Client-IP header)
proxy_client_headers[] = HTTP_CLIENT_IP

And used this is the nginx reverse proxy :

     proxy_set_header    X-Real-IP 	      $remote_addr;

Unfortunately using this method we see as IPs for our clients. Most probably matomo simply doesn’t catch the X-Real-IP header for HTTP_CLIENT_IP

as you probably figured out by now if you have read the thread from the beginning i am not really good with this, this is my first time with both nginx and matomo and my understanding is very basic.

thank you for your time.


I tried to remove the following from the nginx config file for nginx not to set the header over the one coming from the client.

unfortunately it doesn’t change a thing.

i’m hitting a wall and i have no idea what to try next.