FreeIPA behind HTTP load balancer
2017-02-16
Table of Contents
Abstract
The FreeIPA servers can be run with multiple replicas set up. Administrators and users can use Web user interface of any replica they can reach over the network by specifying hostname of the particular replica in the URL but sometimes it might be useful to provide single URL to the users and let the software fail over between replicas. We will look at the steps that achieve the load balancing setup.
Front-end proxy
In article about
FreeIPA
behind HTTP proxy with different hostname, we've shown
basic proxy configuration plus a couple of additional tweaks to
session cookie and referer header handling, making the WebUI
of the FreeIPA server ipa.int.example.com
accessible
on front-end HTTP proxy machine with hostname webipa.example.com
,
different from the real server name.
The resulting configuration we've arrived at could be done fully on the front-end machine:
<VirtualHost _default_:443> # ... # add the following directives SSLProxyEngine on ProxyPass / https://ipa.int.example.com/ ProxyPassReverse / https://ipa.int.example.com/ ProxyPassReverseCookieDomain ipa.int.example.com webipa.example.com RequestHeader edit Referer ^https://webipa\.example\.com/ https://ipa.int.example.com/ </VirtualHost>
Proxy balancer
Let's now assume that instead of one FreeIPA server
ipa.int.example.com
, we have two servers in multi-master
replication setup, for example ipa1.int.example.com
and ipa2.int.example.com
. On the front-end proxy machine,
we can configure Apache module mod_proxy_balancer
which
extends the mod_proxy
with load balancing capabilities.
We first define the pseudo-URL balancer://ipa-replicas
with two balanced members:
<Proxy balancer://ipa-replicas> BalancerMember https://ipa1.int.example.com/ BalancerMember https://ipa2.int.example.com/ </Proxy>and change the
ProxyPass
and ProxyPassReverse
to point to this pseudo-URL, effectively invoking
mod_proxy_balancer
:
ProxyPass / balancer://ipa-replicas/ ProxyPassReverse / balancer://ipa-replicas/
We also need to extend the ProxyPassReverseCookieDomain
setting to handle cookies coming from either back-end machine:
ProxyPassReverseCookieDomain ipa1.int.example.com webipa.example.com ProxyPassReverseCookieDomain ipa2.int.example.com webipa.example.com
Determining referer value
All these configuration changes were done in the Apache HTTP Server
configuration on the HTTP front-end machine, for example in
/etc/httpd/conf.d/ssl.conf
. The last one
that we need to do is taking care of the referer HTTP request header
which the FreeIPA WebUI logic expects to match its own hostname,
and here we hit
a problem — each FreeIPA server replica will want to see
its own hostname in that request header but we cannot put
multiple RequestHeader edit
directives to the front-end
proxy machine. Attempting something like
RequestHeader edit Referer ^https://webipa\.example\.com/ https://ipa1.int.example.com/ RequestHeader edit Referer ^https://webipa\.example\.com/ https://ipa2.int.example.com/would cause the request header value to be rewritten from
https://webipa.example.com/...
to
https://ipa1.int.example.com/...
no matter whether the balancer
picked ipa1.int.example.com
or ipa2.int.example.com
.
At the same time, we do not seem to have a way to determine the
worker which will be selected by mod_proxy_balancer
to use that hostname as the replacement argument of
RequestHeader edit
.
The solution is to move this last configuration piece to the
individual FreeIPA servers. There, we know what hostname to use,
so we will do exactly the one change to the request header value
needed. On ipa1.int.example.com
replica, for example
into /etc/httpd/conf.d/ipa-rewrite.conf
,
we add
RequestHeader edit Referer ^https://webipa\.example\.com/ https://ipa1.int.example.com/while on
ipa2.int.example.com
machine, we use
RequestHeader edit Referer ^https://webipa\.example\.com/ https://ipa2.int.example.com/
Conclusion
After restarting Apache HTTP Server service on all three machines,
we can access the FreeIPA server WebUI on the URL
https://ipa.example.com/
and the access will work
even if one of the replicas will be down — the HTTP request
will be routed to the other back-end replica machine.