v0.8.4-rc1 doesn't work for IPv6 client IPs
jonmz opened this issue · 8 comments
We're using mod_rpaf behind a Pound proxy. When updating from 0.8.2 to 0.8.4-rc1 we observed that requests from IPv6 client IPs weren't treated by mod_rpaf while IPv4 clients are still treated correctly.
Pound is running on our host "kaus.uberspace.de", listening to "::" (all IPv4 and IPv6 addresses), both on ports 80 and 443. It is configured to use 185.26.156.16 port 81 as its backend which is an Apache running with mod_rpaf. This is the mod_rpaf configuration on that host:
RPAF_Enable On
RPAF_ProxyIPs 185.26.156.16
RPAF_Header X-Forwarded-For
RPAF_SetHostName On
RPAF_SetHTTPS On
RPAF_SetPort On
At https://phpinfo.kaus.uberspace.de/ a phpinfo() page is set up to show environment variables. Calling the URL by IPv4 (from 185.26.156.4 as the client) everything works as expected; the X-Forwarded-For address is correctly put into REMOTE_ADDR, SERVER_PORT is correctly set to port 443, and so on:
$ curl -4 -s https://phpinfo.kaus.uberspace.de/ | grep -E "(REMOTE_ADDR|FORWARDED|PORT)"
<tr><td class="e">_SERVER["REMOTE_PORT"]</td><td class="v">39429</td></tr>
<tr><td class="e">_SERVER["REMOTE_ADDR"]</td><td class="v">185.26.156.4</td></tr>
<tr><td class="e">_SERVER["SERVER_PORT"]</td><td class="v">443</td></tr>
<tr><td class="e">_SERVER["HTTP_X_FORWARDED_FOR"]</td><td class="v">185.26.156.4</td></tr>
<tr><td class="e">_SERVER["HTTP_X_FORWARDED_PORT"]</td><td class="v">443</td></tr>
<tr><td class="e">_SERVER["HTTP_X_FORWARDED_HTTPS"]</td><td class="v">on</td></tr>
With an IPv6 client (2a00:d0c0:200::4 in this case) however there's an unexpected result: You can still see the IP address of the Pound proxy (185.26.156.16) as REMOTE_ADDR, but as this is the configured RPAF_ProxyIPs mod_rpaf should have transferred the X-Forwarded-For-IP into REMOTE_ADDR. Additionally you can see that SERVER_PORT is still set to port 80, while the rest of the output clearly shows that HTTPS port 443 was in use:
$ curl -6 -s https://phpinfo.kaus.uberspace.de/ | grep -E "(REMOTE_ADDR|FORWARDED|PORT)"
<tr><td class="e">_SERVER["REMOTE_PORT"]</td><td class="v">39470</td></tr>
<tr><td class="e">_SERVER["REMOTE_ADDR"]</td><td class="v">185.26.156.16</td></tr>
<tr><td class="e">_SERVER["SERVER_PORT"]</td><td class="v">80</td></tr>
<tr><td class="e">_SERVER["HTTP_X_FORWARDED_FOR"]</td><td class="v">2a00:d0c0:200::4</td></tr>
<tr><td class="e">_SERVER["HTTP_X_FORWARDED_PORT"]</td><td class="v">443</td></tr>
<tr><td class="e">_SERVER["HTTP_X_FORWARDED_HTTPS"]</td><td class="v">on</td></tr>
I don't have a clue why that happens because the connection between Pound and Apache is always based on IPv4, independent on the connection from the browser client to Pound which might be either IPv4 or IPv6, so mod_rpaf always gets its connection by IPv4 from 185.26.156.16.
Downgrading mod_rpaf to v0.8.2 without touching the configuration is currently a functional workaround, but I'm pretty sure the new behaviour isn't intended.
You are indeed correct, this behaviour is not intended, I will see if I can find the cause.
Edit: Intial look I would suspect it is caused on L266 where rpaf_looks_like_ip
is called, this function doesn't seem to take into account the hex characters (a-f) possible in a IPv6 address.
I can confirm that this fixes the issue. Thanks for fixing this in such a short manner.
curl -6 -s https://phpinfo.kaus.uberspace.de/ | grep -E "(REMOTE_ADDR|FORWARDED|PORT)"
<tr><td class="e">_SERVER["REMOTE_PORT"]</td><td class="v">39514</td></tr>
<tr><td class="e">_SERVER["REMOTE_ADDR"]</td><td class="v">2001:1a50:11:0:5f:8f:ac93:1</td></tr>
<tr><td class="e">_SERVER["SERVER_PORT"]</td><td class="v">443</td></tr>
<tr><td class="e">_SERVER["HTTP_X_FORWARDED_FOR"]</td><td class="v">2001:1a50:11:0:5f:8f:ac93:1</td></tr>
<tr><td class="e">_SERVER["HTTP_X_FORWARDED_PORT"]</td><td class="v">443</td></tr>
<tr><td class="e">_SERVER["HTTP_X_FORWARDED_HTTPS"]</td><td class="v">on</td></tr>
You're welcome.
Still does not work on IPs like "::ffff:148.204.107.28" (nginx uses that format)
Confirmed, this is because it is IPv4 in IPv6 format and can be fixed by adding the '.' to the IPv6 set here: 9e9b483#diff-a6a1beee0c0acdac86777926e2baed82R72
I will update this when I am back at my development environment.
What's the current state with this issue? I'm having the same issue with IPv4 addresses in IPv6 format.
Awesome, thanks!