Sergey B Kirpichev <skirpic...@gmail.com> 2014-01-20 00:43:
tags 734798 +moreinfo
thanks

I can't reproduce the problem for apache2-mpm-worker nor for
apache2-mpm-prefork.  See below.

On Thu, Jan 09, 2014 at 10:48:20PM +0100, Vincent CARON wrote:
this is a follow up of bug #697644. I could reproduce the problem today on
two up-to-date Wheezys, and here are the instructions to encounter the bug.

Setup a single default Apache vhost, which we thus may reach with any name.
Eg:

<VirtualHost *:80>
ServerName rpaf-bug

DocumentRoot /var/www
CustomLog /var/log/apache2/access.log combined

<Location />
Order deny,allow
Deny from all
Allow from 1.2.3.4
</Location>
</VirtualHost>

... where 1.2.3.4 is an IP address of your host. Then on this same host,
try :

$ curl http://localhost/
(denied with Apache default 403 page)
$ curl http://1.2.3.4/
(granted, serves /var/www/default/index.html happily)

So everything's fine till there. Then install libapache2-mod-rpaf and keep
its default config (which trusts 127.0.0.1), and try :

$ curl -H 'X-Forwarded-For: 1.2.3.4' http://localhost/
(denied with Apache default 403 page)
$ tail /var/log/apache2/access.log
...
1.2.3.4 - - [09/Jan/2014:22:15:53 +0100] "GET / HTTP/1.1" 403 461 "-" 
"curl/7.26.0"

... where obviously mod_rpaf works fine (seeing the log) but auth is wrongfully 
denied.
CGIs also get 1.2.3.4 in REMOTE_ADDR. I made several tests, and it's clear that 
Apache
authz against the real client IP (127.0.0.1 above), and not the one in 
X-Forwarded-For.

I still can't reproduce this:

$ sed 's/\#.*$//;s/[[:space:]]\+/ /g;/^ *$/d' 
/etc/apache2/mods-enabled/rpaf.conf
<IfModule rpaf_module>
RPAFenable On
RPAFsethostname On
RPAFproxy_ips 127.0.0.1 ::1
</IfModule>
$ cat /etc/apache2/sites-enabled/000-default
<VirtualHost *:60080>
...
<Location /files>
Order deny,allow
Deny from all
Allow from 1.2.3.4
</Location>
...
</VirtualHost>

$ HEAD -d http://localhost:60080/files
403 Forbidden
$ HEAD -d -H 'X-Forwarded-For: 1.2.3.4' http://localhost:60080/files
200 OK

Perhaps try the wget command I gave earlier to force it over IPv6 instead. Then vary the X-Forwarded-For with either IPv4 or IPv6 addresses.

$ tail -2 /var/log/apache2/access.log
127.0.0.1 - - [20/Jan/2014:00:20:39 +0400] "HEAD /files HTTP/1.1" 403 - "-" 
"lwp-request/6.03 libwww-perl/6.04"
1.2.3.4 - - [20/Jan/2014:00:20:53 +0400] "HEAD /files HTTP/1.1" 200 - "-" 
"lwp-request/6.03 libwww-perl/6.04"

Without the patch the log's reported client address is correct in my case, but the return status is not. That's because the logs use the string form of the client address (remote_addr) whereas mod_authz_host uses the binary format (remote_ip).

FYI, I think the patch described in [1], fixes this issue as well.

Which one? 030_ipv6.patch?

Yes, that's the main one of importance to this ticket. The others were build fixups (as the comments in series tried to explain).

But you are using ipv4, isn't?

No, I'm using both IPv4 and IPv6 on the proxy, but the communications between proxy and backend are IPv6 only.

If you look at the original code directly above the patch, for the binary format (the part that's checked by things like mod_authz_host) it's only overwriting the request's address when treated as an IPv4 address, so when the X-Forwarded-For address is IPv6 the result is incomplete, incorrect, a buffer overflow, or some other sorts of badness.

Additionally, since our backend addresses are IPv6 only, the socket family (AF_INET6) won't match even if the X-Forwareded-For client is IPv4 (AF_INET).

Mind you, I'm not saying a blind memcpy() is necessarily the right answer, but that's what Debian was doing before, and it does fix the problem.

Thanks,
Brian

Attachment: signature.asc
Description: Digital signature

Reply via email to