adelton

FreeIPA behind HTTP load balancer

Jan Pazdziora

2017-02-16


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.