Multi-homed FreeIPA server investigation
Once in a while people come and ask for FreeIPA servers to work in multi-homed environments. A multi-homed environment in this context is a deployment where the same server is accessible through multiple network interfaces which connect together networks which are not routable to each other. This is typical for administrative and operational networks but there are other types of environments which employ disconnected networks for their operations. FreeIPA server right now has a single host name that resolves to the same IP address in all networks and if one cannot reach the server through that IP address, access to IPA server would not be possible. This typically assumes use of unicast networking as well.
A solution many people look for is to be able to access IPA servers by their
interface-specific addresses. Since all secure communication over HTTPS and other
protocols (LDAP, Kerberos, etc.) uses name-based resolution in the first place,
use of different host names is implied. For example, if FreeIPA is deployed at
DNS domain example.test
, it would be using Kerberos realm EXAMPLE.TEST
and
then the original IPA server would be deployed at a host named
ipa.example.test
(the server host name is not that important here, rather the
fact that is is an individual host name). Let’s look at possible communications
with this server in a non-multihomed environment first.
Single-homed environment
An IPA client uses HTTPS to communicate with IPA management API, SSSD on the
IPA client would use LDAP(S) and Kerberos protocols. In both HTTPS and LDAP(S)
cases TLS negotiation would force checking server TLS certificate correctness.
A hostname of the host we connect to (ipa.example.test
) would have to be
present as a dNS SAN record in the TLS certificate presented by the IPA server.
In Kerberos protocol case a different mechanism is used. Yet, Kerberos KDC must
know the name of the service principal that a client is asking a service ticket
for. If the client wants to acquire a service ticket to
ldap/ipa.example.test@EXAMPLE.TEST
, this service principal must exist in the
Kerberos database that KDC is looking up at.
Multi-homed environment
There are multiple ways of exposing a single hostname in multi-homed
environment but they generally involve use of DNS views specific to the
individual networking. In such cases DNS serves visible to clients in one
network would resolve ipa.example.test
to an IP address in that specific
network. FreeIPA DNS integration does not support DNS views; this means any of
DNS manipulations would have to be done externally to FreeIPA. This is, of
course possible, but it really is not then different from a single-homed
environment from FreeIPA perspective.
Thus, we would have to have not a single ipa.example.test
hostname but for
each independent network’s address present on the IPA server a different host
name must be present. Let’s assume these are ipa1.example.test
and
ipa2.example.test
. Had we not done this split and simply added multiple
addresses for the same ipa.example.test
name, clients might resolve the name
to an IP address which they could not reach through their own networking routing.
Requirements
Immediately we get a set of requirements here:
-
TLS certificates issued by IPA CA for HTTPS and LDAP(S) use on IPA server must include dNS SAN records for each hostname represented by the multi-homed server.
-
Kerberos principals for at least LDAP (
ldap/
), HTTP (HTTP/
), and the system (host/
) service principals must have aliases for all multi-homed hostnames.
The latter requirement means that if ipa1.example.test
is the primary name,
then ldap/ipa1.example.test
should have an alias of ldap/ipa2.example.test
,
HTTP/ipa1.example.test
should have an alias of HTTP/ipa2.example.test
, and
host/ipa1.example.test
should have an alias of host/ipa2.example.test
.
The same would apply to any other service hosted on IPA server: SMB (cifs/..
)
or DNS services would need those aliases as well. However, this is not enough.
Implementation considerations
Hostname aliases
FreeIPA does additional checks when issuing certificiates prior to passing the
request to the Dogtag CA that is integrated into FreeIPA. For hosts and
services on those hosts we also check whether a requestor is granted to issue
these certificates. In FreeIPA terms, a host ipa1.example.test
would be
allowed to issue certificates with dNS SAN record of ipa2.example.test
if a
host object of ipa1.example.test
manages the host object ipa2.example.test
in FreeIPA.
Here lies our first problem. A host object in FreeIPA represents the host
principal in Kerberos, host/ipa1.example.test
. If we created two host
objects, ipa1.example.test
and ipa2.example.test
, then they cannot be
aliases to each other on Kerberos level because they’d be two completely
different objects from FreeIPA perspective.
Perhaps, we can avoid creating two different host objects? DNS records for hosts are different from the host objects themselves, we only need to have different IP addresses for the hostnames represented by these host entries, not the host entries themselves. May be we could mark one hostname an alias of the other host object?
On Kerberos level FreeIPA does have Kebreros principal name aliasing already.
However, it does not exist for hosts as this task has never appeared in past. We
would need to add a way to add multiple names to the host object. One way to
achieve that is to rely on the fact that fqdn
LDAP attribute is multi-valued.
Unfortunately, it is also enforced to be a primary key in IPA API – while the
underlying LDAP attribute is a multi-valued one, IPA API will enforce its single
value:
$ ipa host-mod ipa1.example.test --addattr fqdn=ipa2.example.test
ipa: ERROR: fqdn: Only one value allowed.
This happens because in IPA API any parameter which could be a multi-valued one
should explicitly set multivalue=True
in its definition. We probably would
need to change the multi-valued state for fqdn
parameter:
...
Str('fqdn', hostname_validator,
cli_name='hostname',
label=_('Host name'),
primary_key=True,
normalizer=normalize_hostname,
>>>>>> multivalue=True,
),
...
and review countless places where its single value is assumed through the code,
like in the resolve_fqdn()
helper below. LDAP does not guarantee a particular
order of returned values for the multi-valued attributes. From LDAP protocol
point of view they all equal, there is no particular order.
def resolve_fqdn(name):
hostentry = api.Command['host_show'](name)['result']
return hostentry['fqdn'][0]
An alternative would be to introduce a separate attribute purely for the hostname alias management. We don’t need to use it anywhere else at Kerberos level because there we use Kerberos-specific attributes to handle Kerberos principal names and aliases.
LDAP Access Controls
A big part of the FreeIPA access control mechanism relies on 389-ds LDAP server
access control interface. Permissions and roles in FreeIPA effectively define a
set of ACIs for 389-ds to check access rights. IPA servers verified to be
present in certain resource groups (like cn=masters,cn=ipa,cn=etc,$BASEDN
).
For host aliases this means they should be present in the same groups to be able
to operate as their own entities when checking permissions. This is important
for internal logic in IPA LDAP plugins and in KDC driver. For the cases when
authentication would be done via GSSAPI a resulting Kerberos principal will be
normalized to he primary name of the system anyway.
Certificate issuance
Issuing a certificate is a whole separate topic which still awaits its write up. An abridged version of it can be found in my freeipa-users@ mailing list response from May 2022. I need to turn that into a proper document one day.
From the perspective of aliases, we would need to teach the certificate request processing code to look at the host and service aliases when validating SAN records.
Installer integration
There are two approaches to setting up this multi-homed environment. We can provide all information upfront or we can add a tool that adds individual aliases after deployment. This would mean to (re-)generate certificates, create host aliases and services, create configuration snippets and other details which are required to handle multiple host names for the same host from different networks.
The after-deployment case would cause re-issuance of certificates. For external
CA providers it could be handled with existing tool that allows to replace
existing TLS certificates with externally provided ones. We need to create a
checker to verify that all required dNS SAN names were added and are available.
In general, troubleshooting this environment would be non-trivial so a special
module for ipa-healthcheck
definitely would help.
Final thoughts
Multi-homed environments are hard to automate as many assumptions aren’t
actually known to us. They are partly implicit to system and network
administrator’s work and cannot be derived merely from the system state. It
means administrators would need to aid IPA installers with an information. At
this point, it is unclear how to structure this information and which of it
going to be useful enough. In contemporary Linux environments you might have
DNS resolution depend on a specific network interface thanks to
systemd-resolved
or VPN connection properties. We might not have that
information for introspection in advance. While automatically issuing
certificates with required names to cover multi-homed setup is not going to be
easy, writing down requirements for external CAs and verifying those
certificates before applying them at the second stage of external CA enrollment
would further complicate things.
All these problems could be solved, of course. Prioritization of this work against other, more urging tasks, is what we need to figure first…
COMMENTS
You can use your Mastodon or other ActivityPub account to comment on this article by replying to the associated post.