Certificate management with FreeIPA and Dogtag
Show Your ID
Both internal and external services rely on encrypted communication with SSL and TLS. For external services, administrators use officially signed certificates, although Let's Encrypt is absolutely fine in many scenarios. In contrast, internal services predominantly rely on self-signed certificates, which always cause a stir with web browsers on the local area network (LAN) by generating messages such as The server's certificate is unknown .
Administrators would prefer to see a nice lock icon displayed in the browser for a trusted TLS connection – for their intranet applications, too – instead of requiring users to create an individual exception in the browser for every internal application. This also means that stricter security policies can be applied for browsers on the corporate network, preventing users from opening untrusted connections at all or from creating exceptions. Admins also want other internal services to use trusted certificates and SSL for communication.
All you need is your own certificate authority (CA) on your intranet to manage and sign certificates for the connected services. Internal computers then only need to trust that this internal root CA for all keys signed by it are identified as valid.
Dogtag [1], the open source certificate system, offers a simple approach to managing an internal CA, and it integrates seamlessly with the FreeIPA [2] user directory. FreeIPA is to Linux what Active Directory (AD) is to the Windows world. It uses the same technology with a Lightweight Directory Access Protocol (LDAP) back end and Kerberos authentication. AD and an Identity, Policy, and Audit (IPA) system can trust each other with cross-domain trusts, allowing administrators of heterogeneous networks to run a connected directory for Windows and Linux machines.
In this article, I review the basic features of FreeIPA and focus on Dogtag. Every administrator of an environment with multiple Linux servers will probably run an IPA directory for central user, host, and service management anyway, just as admins run AD on Windows networks.
Installing the FreeIPA Server
To set up the IPA server, you will want to use a Linux distribution such as Enterprise Linux distribution version 8 (EL8), Rocky, or AlmaLinux. The Minimal installation type is quite sufficient. The setup does not need special repositories such as Extra Packages for Enterprise Linux (EPEL) because all of the required packages can be found in the AppStream repository of every EL8 distribution. The IPA server must have a static IP address. Its Domain Name System (DNS) name must be configured correctly, and DNS resolution on the LAN must be correct (forward and reverse lookup). The time zone configuration must be appropriate, and the server must use Chrony to sync the time with timeservers on the web.
The FreeIPA server is registered as a module named idm
(identity management) in the AppStream repository. The versions you will find are simply the server and the client; the dandified Yum (dnf
) command lets you enable the server module and set up the required packages:
dnf module enable idm:DL1 dnf distro-sync dnf module install idm:DL1/server
The installation is an interactive process with the
ipa-server-install
command. Alternatively, you can pass all the required parameters into the command at the command line. At this point, you need to decide whether the IPA server itself will assume the role of DNS server, which is common practice with AD. In this example, however, I assume that a DNS installation is already in place on your network.
To make it easier for IPA clients and servers to communicate, you need to add a few entries to the existing DNS server that point to the IPA installation. In this example, the server is named ipa.mykier.ip
and it manages the mykier.ip
realm. Running dnsmasq
reveals the matching entries in the DNS server (Listing 1).
Listing 1
dnsmasq Output
srv-host =_kerberos._udp.mykier.ip,ipa.mykier.ip,88 srv-host =_kerberos._tcp.mykier.ip,ipa.mykier.ip,88 srv-host =_kerberos-master._tcp.mykier.ip,ipa.mykier.ip,88 srv-host =_kerberos-master._udp.mykier.ip,ipa.mykier.ip,88 srv-host =_kpasswd._tcp.mykier.ip,ipa.mykier.ip,88 srv-host =_kpasswd._udp.mykier.ip,ipa.mykier.ip,88 srv-host =_ldap._tcp.mykier.ip,ipa.mykier.ip,389
A Berkeley Internet Name Domain (BIND) 9 DNS server needs the same entries, but in a different format:
_kerberos._udp.mykier.ip. 86400 IN SRV 0 100 88 ipa.mykier.ip. [...]
The important thing here is that both AD and IPA require the same service (SRV) records for Kerberos in DNS. If you are already using AD on the LAN, do not reassign the entries; otherwise, AD will no longer work. FreeIPA can manage without a DNS configuration. However, you then always need to include the reference to the realm and the IPA server in all operations on the clients.
To enable the clients to communicate with the IPA server, you also need to open the required firewall ports on the IPA machine:
firewall-cmd --add-service={http,https,dns,ntp,freeipa-ldap,freeipa-ldaps} --permanent firewall-cmd --reload
You can now access the web user interface (UI) on the FreeIPA server at https://ipa.mykier.ip. When you get there, you will see the users and hosts in your domain along with any certificates issued (Figure 1). For further tests with the directory, you can now create users and groups. With the use of suitable rule sets (e.g., Sudo rules), you can allow individual users or groups to work as root users on selected hosts.
To add an existing Linux server to the directory, you first need to install the IPA client on the server. As for the IPA server, you will find the packages you need in the AppStream repository:
dnf install @idm:client
Once you have configured the IPA entries on your DNS server, a simple command is all it takes to register the server in the domain:
ipa-client-install --mkhomedir
The installer relies on DNS to discover all the information it needs about the domain. The --mkhomedir
option tells the client to create the required home directories dynamically for the domain users on the local system. In practice, however, administrators are more likely to create an automount rule on the FreeIPA server that mounts the home directories from a central NFS server at user login time. In this way, domain users will always have access to their files, regardless from which PC within the domain they log in.
Without DNS records, users need to pass in the IPA server and domain information to the command:
ipa-client-install --mkhomedir --server=ipa.mykier.ip --domain=mykier.ip --realm=MYKIER.IP
In both cases, the client setup then asks for a domain admin user account name and password to log the current machine into the directory service.
If you use Kickstart to install EL8 servers or clients, this step can be automated. If you are setting up Fedora Linux or EL8 Linux with a graphical UI (GUI) from a Live operating system disc, you can handle the domain joining step directly in the Gnome configuration after completing the basic installation. When Gnome prompts the user to create a new user, the Enterprise Login button pops up, which then guides you interactively through the IPA client setup.
Automating the IPA Client Rollout
When you set up a FreeIPA directory on an existing LAN, you obviously don't want to have to register manually all existing or new machines with the directory. The process can be automated in a relatively simple way. First, create the appropriate host entries in the directory service, which you can do on a computer that has the IPA client and is authorized with admin rights to the directory:
ipa host-add hostname.fqdn --password=<one-time-password>
The assigned password expires after the computer's first attempt to join the domain.
On existing Linux hosts, install the IPA client Ansible or some other automation tool. Then, on the respective client, by remote execution (or an Ansible role), register with the domain:
ipa-client-install --hostname=client.mykier.ip --domain=mykier.ip --mkhomedir -w <one-time-password> --realm=MYKIER.IP --server=ipa.mykier.ip
You only need the details (e.g., domain
, server
, and realm
) if you do not have appropriate DNS records for the IPA server. By the same principle, you can automatically add systems installed by Kickstart to the directory. First define the computer, including the one-time password in the directory. In the Kickstart file, add the following options:
%packages [...] ipa-client
and toward the end:
%post [...] /usr/sbin/ipa-client-install <parameters as above>
The system then joins the domain at the end of the automated installation process.
In the web UI of your IPA server, the newly registered server is now displayed in Identity | Hosts
. With Policy | Sudo | Sudo rules
you could now, for example, allow one of your directory users to run the sudo
command on the new server and perform actions as root. The ruleset also supports granular breakdown if you only want to let users run specific commands or command groups as Sudo without gaining full root access to the system (Figure 2).
Generating Certificates for Services
Once the new server has joined the domain, you can create certificates for services on this machine and have them signed by the root CA on the Free IPA server (Figure 3). In this example, I run a web server with Nginx on a freshly set up AlmaLinux 8 server that I registered in the domain as dhcp224 . I want to give this server an official certificate for the HTTPS protocol:
dnf install nginx
Now create a suitable directory for the certificate
mkdir -p /etc/nginx/cert
EL8 systems run SELinux by default. The directory needs the correct context for the certificates; otherwise, the IPA client cannot store certificates there:
semanage fcontext -a -t cert_t "/etc/nginx/cert(/.*)?" restorecon -v /etc/nginx/cert
In the next step, log in to the directory with an admin account (kinit admin
). Now go to the certificate directory, register the service, and request the appropriate certificate. For this case study, assume that the realm for your domain is MYKIER.IP
:
cd /etc/nginx/cert fqdn=$(hostname -f) ipa service-add HTTP/$fqdn ipa-getcert request -f $fqdn.crt -k $fqdn.key -r -K HTTP/$fqdn@MYKIER.IP -N $fqdn
To avoid typing the complete fully qualified domain name (FQDN) of the server multiple times, you can define it as a shell variable named $fqdn
. The
ipa service-add
command registers the desired service for the server against the directory. A number of services are predefined (e.g., HTTP ), but you can create your own services at any time (e.g., REDIS/redis.mykier.ip ).
The command
ipa-getcert request
creates the request and also immediately intercepts the response from the Dogtag service on the IPA server. Like many other services, Nginx wants the certificate in privacy-enhanced mail (PEM) format in two files for the certificate and the key. If the server is named www.mykier.ip
, you will receive a www.mykier.ip.crt
file and a www.mykier.ip.key
file in the response. The long detour by a local Network Security Services (NSS) database is no longer needed thanks to Certmonger. When a certificate is approaching its expiration date, you can renew it with the -r
(renew) option.
For the Nginx server to access the files, it of course needs the appropriate permissions:
chown -R nginx. /etc/nginx/cert/*
In the default /etc/nginx/nginx.conf
configuration file, simply enable the commented out # Settings for a TLS enabled server
section and add the reference to your certificate:
ssl_certificate "/etc/nginx/cert/www.mykier.ip.crt"; ssl_certificate_key "/etc/nginx/cert/www.mykier.ip.key";
After restarting the service, your web server now also responds to HTTPS requests with the IPA-signed certificate. You can then use the same principle to create other services (e.g., IMAP, SMTP, or even MQTT) and generate suitable certificates.
Buy this article as PDF
(incl. VAT)