Perlbal Reproxy and HTTP Auth
I use Perlbal in one of the systems to reproxy requests to an internal URL. Reproxying to URL is a powerful feature that works like this.
- An HTTP request comes to Perlbal.
- Perlbal reverse-proxies it to one of its backend servers.
- Backend server does some work (in my case, does extensive verification of URL) but instead of returning entire response (status, headers, body), it returns X-REPROXY-URL header which includes a list of URLs.
- Seamlessly to end user, perlbal attempts to fetch content from one of these URLs, and returns that new content to the user.
The other day I found out that Perlbal can’t reproxy to URLs that require HTTP basic authentication. Here is a part of Perlbal that parses X-REPROXY-URL header and you can clearly see from regex, it treats URLs as (host, port, path) tuples (this is from ClientProxy.pm).
# construct reproxy_uri list if (defined $urls) { my @uris = split /\s+/, $urls; $self->{currently_reproxying} = undef; $self->{reproxy_uris} = []; foreach my $uri (@uris) { next unless $uri =~ m!^http://(.+?)(?::(\d+))?(/.*)?$!; push @{$self->{reproxy_uris}}, [ $1, $2 || 80, $3 || '/' ]; } }
And my backend Apaches do require http auth. What to do?
RTFM to the rescue! Apache provides a very cool feature - Satisfy (all|any) command. Essentially, it means that for a Directory or Location I can specify both http auth and IP based access control, and using Satisfy Any I can allow access if at least one of these conditions are met (default is Satisfy All).
Here is what it looks like in http config:
<Location /foo> # http auth AuthType basic AuthName "protected" AuthUserFile /etc/apache2/users Require valid-user order allow,deny # this is subnet where perlbal is running # backends see perlbal's reproxy requests from this subnet allow from 192.168.4 127.0.0.1 satisfy any </Location>
Alternatively, I would need to create a fake URI outside of http auth location and rewrite it with mod_rewrite, or possibly use a symlink - way less transparent.
Categories: software-engineering |