Piwik Proxy Hide URL behind reverse proxy not reporting actual user IP

I’m using a CDN service that acts as a reverse proxy. It provides 2 http headers: X-Real-Forwarded-For and X-Forwarded-For. According to the server access log, the CDN server ip appears in the cip parameter. I’m not sure how proxy_client_headers[] in the config.inc.php works. Is there an officially supported way to make Piwik hide url proxy log the actual user IP? Or can I use js/ proxy?

Thanks for message. This is a known bug / feature request: When running piwik proxy php to hide footprint, IP address is not set correctly when the website being tracked is behind proxy · Issue #2900 · matomo-org/matomo · GitHub

please comment on this comment to make your voice heard!

You’re welcome, matt. I should have searched the forum and trac before opening the topic…
I’ve googled a bit about proxy_client_headers[], but can’t find detailed documentation. Can I put both X-Real-Forwarded-For and X-Forwarded-For headers in the config? Then what would happen if neither headers are present in the request?

that’s the bug, that this ticket is about to fix.

The problem lies at this line: https://github.com/piwik/piwik/blob/master/misc/proxy-hide-piwik-url/piwik.php#L64

replace @$_SERVER[‘REMOTE_ADDR’]
with the right value, eg.

$_SERVER[‘X-Real-Forwarded-For’]

Thanks for pointing that out. I’ll grep proxy_client_headers in the code to find out how it works.
By the way, @$_SERVER[‘HTTP_X_REAL_FORWARDED_FOR’] worked for me.

i think the way it should work for piwik.php proxy is: try all known _SERVER keys, that could contain IPs, and get the first one from it.

Well, that’s sort of what I’m doing right now. My CDN provider provided a modified ip detection function for phpwind in their support forum: 知道云安全都提供哪些客户支持方式 – 知道创宇云安全 – 帮助与文档 .

I simplified it as follow:


$User_IP = $_SERVER['REMOTE_ADDR'];
if (isset($_SERVER['HTTP_X_REAL_FORWARDED_FOR']) && preg_match('/^([0-9]{1,3}\.){3}[0-9]{1,3}$/', $_SERVER['HTTP_X_REAL_FORWARDED_FOR'])) {
        $User_IP = $_SERVER['HTTP_X_REAL_FORWARDED_FOR'];
}
elseif (isset($_SERVER['HTTP_X_FORWARDED_FOR']) && preg_match('/^([0-9]{1,3}\.){3}[0-9]{1,3}$/', $_SERVER['HTTP_X_FORWARDED_FOR'])) {
        $User_IP = $_SERVER['HTTP_X_FORWARDED_FOR'];
}
elseif (isset($_SERVER['HTTP_CLIENT_IP']) && preg_match('/^([0-9]{1,3}\.){3}[0-9]{1,3}$/', $_SERVER['HTTP_CLIENT_IP'])) {
        $User_IP = $_SERVER['HTTP_CLIENT_IP'];
}

And added the above code to piwik.php, so @$_SERVER[] becomes $User_IP. It works… I didn’t mention it earlier because I wasn’t sure about the code’s license.

Thank you, I fixed it in git Fixes #2900 Now reading 'HTTP_X_FORWARDED_FOR', 'HTTP_CLIENT_IP', 'H… · matomo-org/matomo@300d3c2 · GitHub