@bazzadp opened this Issue on September 3rd 2020

Could we add to the documentation how X-Forwarded-For type headers are transformed for when you want to set them up in config.ini.php when using proxy_client_headers?

Namely that the following transforms take place for the HTTP Header name:

  • Header names are uppercased
  • Header names are prefixes with HTTP_
  • Dashes are converted to underscores

So if your server is sending X-Forwarded-For (like mod_proxy does for Apache for example) then this should be entered in the config as HTTP_X_FORWARDED_FOR.

Additionally it is possible to have multiple proxy_client_headers and they should be added to the config in order of preference. For example:

proxy_client_headers[] = HTTP_WAF_FORWARDED_FOR
proxy_client_headers[] = HTTP_LB_FORWARDED_FOR
proxy_client_headers[] = HTTP_X_FORWARDED_FOR

Means first try the HTTP_WAF_FORWARDED_FOR header and if that doesn’t exist, then try the HTTP_LB_FORWARDED_FOR and if neither exists then finally try HTTP_X_FORWARDED_FOR.

Within these, it is possible to have multiple IPs. The IPs are are used in reverse order and you can use proxy_ips config to exclude known IPs.

So if you have the following headers:

X-Forwarded-For: 123.456.78.9, 192.168.10.20
X-LB-Forwarded-For: 123.456.78.9

And the following set up in config.ini.php:

[General]
; Uncomment line below if you use a standard proxy
proxy_client_headers[] = HTTP_X_FORWARDED_FOR
proxy_client_headers[] = HTTP_LB_FORWARDED_FOR
proxy_ips[] = 192.168.*.*/16
proxy_ips[] = 10.40.*.*/16

Then it would first look at HTTP_X_FORWARDED_FOR and start at the right-most IP (192.168.10.20), which would be discarded as matches the proxy_ips[]. Next it would move left and find 123.456.78.9 which is what would be selected as the real ip.

It’s also possible to debug this to list all these details in the Matomo log file.

Some or all of this may be obvious to regular PHP developers (or regular Matomo administrators) but just spent quite a bit of time getting this setup on my server and I feel the documentation could be improved here to prevent future people making the same mistakes I initially did.

@tsteur commented on September 4th 2020 Member

Thanks for all this @bazzadp very appreciated

@bazzadp commented on September 4th 2020

Thank you for this great product 😀

Is this page in GitHub? If so I’m happy to open a PR with the above info if you agree with what I’ve said and can point me at where this?

@Findus23 commented on September 4th 2020 Member

Hi @bazzadp,

The FAQs are not on GitHub, but if you can send us your improvements, we can replace the text.

@mattab commented on September 24th 2020 Member

@bazzadp here is the text of the current FAQ in markdown, if you're able to suggest some improvements, we'd love to publish them in the page, that would be very appreciated

This FAQ details the few different use cases and configurations when using a proxy in Matomo.

### If Matomo is behind a reverse proxy 

If you install Matomo, connecting through a reverse proxy (https-to-http), the following line should be automatically added to your config/config.ini.php file during the Matomo installation:

    [General]
    assume_secure_protocol = 1

If you install Matomo from **behind the reverse proxy** (where Matomo can't detect https will be used), you should set the above manually. Also, depending on your proxy server, the Visitor IP is set in a different HTTP Header which should also be automatically detected on install and added to your config/config.ini.php:

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

    ; Uncomment line below if you use CloudFlare
    ;proxy_client_headers[] = HTTP_CF_CONNECTING_IP

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

If Matomo was unable to detect your proxy configuration, you may add these lines manually in your Matomo config.ini.php file (remove the leading ";" character to enable the setting). 

Notes: 

* If your server runs IIS reverse proxy, `HTTP_X_FORWARDED_HOST` needs to be added manually to "Allowed Server Variables" and added to the inbound rewrite rule and set to {HTTP_HOST} so that it passes through the original HTTP_HOST value provided by the client to Matomo. [Learn more](https://docs.microsoft.com/en-us/iis/extensions/url-rewrite-module/modifying-http-response-headers).

* If you use Apache 2.4 or Apache 2.5, there is an alternative solution, you could use `mod_remoteip` to override the client IP with the IP as provided by a proxy or load balancer. Then you won't need to specify these Piwik config settings.

### If Piwik is behind a reverse proxy and installed in a sub-path

If you're using Piwik **behind a reverse proxy with a different path** such as `rewrite ^/piwik/(.*)$ /$1 break;` (in `nginx.conf` when Piwik is installed in the `/piwik` path), you would need to:

1) configure your web server to provide a header `HTTP_X_FORWARDED_URI`. For example on NGINX, when Piwik is installed in `/piwik` path, you would set `proxy_set_header X-Forwarded-Uri /piwik;` in your `nginx.conf`.
2) configure Piwik to read this HTTP_X_FORWARDED_URI to construct correct URLs. In Piwik config/config.ini.php in the `[General]` section add:

     [General]
     ; Use the header HTTP_X_FORWARDED_URI to construct the current script name
     proxy_uri_header = 1

### Matomo is behind an outgoing proxy 

If your server is configured **behind an outgoing proxy**, check out this FAQ: [outgoing Proxy easy setup in Piwik][1]. 

### You might also be interested in...
* [Proxy all requests to Matomo Tracker on all websites through a local proxy on each site (to hide the central Matomo instance URL)](https://matomo.org/faq/how-to/faq_132/)
* [How do I force Matomo login to use SSL (https)?][2].

 [1]: https://matomo.org/faq/troubleshooting/#faq_121
 [2]: https://matomo.org/faq/how-to/#faq_91
@bazzadp commented on September 24th 2020

Thanks that makes it easier!

What about this:

This FAQ details the few different use cases and configurations when using a proxy in Matomo.

### If Matomo is behind a reverse proxy 

If you install Matomo, connecting through a reverse proxy (https-to-http), the following line should be automatically added to your config/config.ini.php file during the Matomo installation:

    [General]
    assume_secure_protocol = 1

If you install Matomo from **behind the reverse proxy** (where Matomo can't detect https will be used), you should set the above manually. Also, depending on your proxy server, the Visitor IP is set in a different HTTP Header which should also be automatically detected on install and added to your config/config.ini.php:

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

    ; Uncomment line below if you use CloudFlare
    ;proxy_client_headers[] = HTTP_CF_CONNECTING_IP

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

If Matomo was unable to detect your proxy configuration, you may add these lines manually in your Matomo config.ini.php file (remove the leading ";" character to enable the setting).

Be aware that PHP applies some transforms to headers: uppercases them, prefixes `HTTP_` and converts dashes to underscores. So if your reverse proxy is sending `X-Forwarded-For`, it should be entered in the config as `HTTP_X_FORWARDED_FOR`.

It is also possible to check multiple `proxy_client_headers`, which will be checked in order until a header value is found. For example, with the config below:

    proxy_client_headers[] = HTTP_WAF_FORWARDED_FOR
    proxy_client_headers[] = HTTP_LB_FORWARDED_FOR
    proxy_client_headers[] = HTTP_X_FORWARDED_FOR

This means first try the HTTP_WAF_FORWARDED_FOR header and if that doesn’t exist, then try the HTTP_LB_FORWARDED_FOR and if neither exists then finally try HTTP_X_FORWARDED_FOR. The `array[]` syntax is shorthand in PHP for `array_push` so adds to the existing array.

You can exclude internal IPs (e.g. LoadBalancer IPs) from being used from these headers using the `proxy_ips[]` config to exclude certain ranges of IP addresses. For example the following config will ignore commonly used internal IP address ranges:

    proxy_ips[] = 192.168.*.*/16
    proxy_ips[] = 10.40.*.*/16

It is also possible to [debug this](https://matomo.org/faq/how-to/faq_20991/) to list the exact details in the Matomo log file.

Notes: 

* If your server runs IIS reverse proxy, `HTTP_X_FORWARDED_HOST` needs to be added manually to "Allowed Server Variables" and added to the inbound rewrite rule and set to {HTTP_HOST} so that it passes through the original HTTP_HOST value provided by the client to Matomo. [Learn more](https://docs.microsoft.com/en-us/iis/extensions/url-rewrite-module/modifying-http-response-headers).

* If you use Apache 2.4 or Apache 2.5, there is an alternative solution, you could use `mod_remoteip` to override the client IP with the IP as provided by a proxy or load balancer. Then you won't need to specify these Piwik config settings.

### If Piwik is behind a reverse proxy and installed in a sub-path

If you're using Piwik **behind a reverse proxy with a different path** such as `rewrite ^/piwik/(.*)$ /$1 break;` (in `nginx.conf` when Piwik is installed in the `/piwik` path), you would need to:

1) configure your web server to provide a header `HTTP_X_FORWARDED_URI`. For example on NGINX, when Piwik is installed in `/piwik` path, you would set `proxy_set_header X-Forwarded-Uri /piwik;` in your `nginx.conf`.
2) configure Piwik to read this HTTP_X_FORWARDED_URI to construct correct URLs. In Piwik config/config.ini.php in the `[General]` section add:

     [General]
     ; Use the header HTTP_X_FORWARDED_URI to construct the current script name
     proxy_uri_header = 1

### Matomo is behind an outgoing proxy 

If your server is configured **behind an outgoing proxy**, check out this FAQ: [outgoing Proxy easy setup in Piwik][1]. 

### You might also be interested in...
* [Proxy all requests to Matomo Tracker on all websites through a local proxy on each site (to hide the central Matomo instance URL)](https://matomo.org/faq/how-to/faq_132/)
* [How do I force Matomo login to use SSL (https)?][2].

 [1]: https://matomo.org/faq/troubleshooting/#faq_121
 [2]: https://matomo.org/faq/how-to/#faq_91
@mattab commented on November 4th 2020 Member

Thank you very much @bazzadp for your suggestion :muscle:
we've updated the FAQ at https://matomo.org/faq/how-to-install/faq_98/
I suppose it is closed but let me know if something is still not as expected.

This Issue was closed on November 4th 2020
Powered by GitHub Issue Mirror