The ``ipa-client-install`` command now supports PKINIT for client enrollment. Existing X.509 client certificates can be used to authenticate a host. Also restart KRB5 KDC during ``ipa-certupdate`` so KDC picks up new CA certificates for PKINIT. *Requirements* - The KDC must trust the CA chain of the client certificate. - The client must be able to verify the KDC's PKINIT cert. - The host entry must exist. This limitation may be removed in the future. - A certmap rule must match the host certificate and map it to a single host entry. *Example* ``` ipa-client-install \ --pkinit-identity=FILE:/path/to/cert.pem,/path/to/key.pem \ --pkinit-anchor=/path/to/kdc-ca-bundle.pem ``` Fixes: https://pagure.io/freeipa/issue/9271 Fixes: https://pagure.io/freeipa/issue/9269 Signed-off-by: Christian Heimes <cheimes@redhat.com> Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
7.9 KiB
IPA client enrollment with PKINIT
This design document proposes PKINIT as an additional authentication
mechanism for ipa-client-install
, ticket
https://pagure.io/freeipa/issue/9271.
Overview
PKINIT is an authentication mechanism for Kerberos that uses X.509 certificates and private keys to authenticate Kerberos KDC server to client and optionally clients to the server. Mutual authentication is almost the same as mTLS with TLS server and client certificates in HTTPS.
PKINIT can be used instead of user/password or OTP to authorize client enrollment. This enables admins to re-use existing host certificates to automate client installations.
Assumptions
- The client machine has access to a X.509 certificate / key pair that uniquely identifies an account with necessary permissions to enroll the host. The certificate does not have to contain special extensions for PKINIT. It only requires an attribute that can be uniquely mapped to an account, e.g. subject alternative name (SAN) dNSName maps to FQDN of an existing host entry or RFC 822 name maps to an user account with enrollment privileges.
- A certmap rule exists matches the certificate, and maps the unique identifier to a single account like an existing host entry or user with enrollment privileges.
- The certificate is signed by a CA chain which is known to and trusted
by the Kerberos KDC server. This can be accomplished by installing the
root CA and intermediate CAs as additional CA certificates to IPA
with
ipa-cacert-manage install
on one IPA server, then runningipa-certupdate
on every IPA servers. - The CA chain of the certificate and the CA chain of the Kerberos KDC
server certificate are available on the host. On an IPA server, the file
/var/lib/ipa-client/pki/kdc-ca-bundle.pem
typically contains all necessary CAs.
How the certificates and CAs are generated and distributed and how host entries are created is out of scope for this document. The certificates and key can be provided as files or by a PKCS#11 provider like OpenSC from a smart card or p11-kit proxy from a remote PKCS#11 source.
Host self-enrollment
Host self-enrollment allows a host to enroll itself using a host-specific certificate. The approach use the fact that a host account has the necessary permissions to self-manage its host entry. A host entry must be pre-created by a privileged account and a certmap rule must map a unique identifier to a host entry.
For example a certmap rule like
$ ipa certmaprule-add pkinit-host \
--matchrule '<ISSUER>CN=Certificate Authority,O=IPA.EXAMPLE' \
--maprule='(fqdn={subject_dns_name})'
allows an host with hostname host.ipa.example
and a certificate with
properties like
Issuer: O = HMSIDM.TEST, CN = Certificate Authority
Subject: O = HMSIDM.TEST, CN = host.ipa.example
X509v3 extensions:
X509v3 Subject Alternative Name:
DNS:host.ipa.example
to enroll itself with a command like
$ ipa-client-install \
--pkinit-identity=FILE:/path/to/cert.pem,/path/to/key.pem \
--pkinit-anchor=FILE:/path/to/kdc-ca-bundle.pem \
...
A privileged account only has to pre-created its host entry with
$ ipa host-add host.ipa.example
first.
Privileged user account
A user account with e.g. Host Administrators
privilege can be used to
create and enroll new hosts.
Example certmap rule:
$ ipa certmaprule-add pkinit-user \
--matchrule '<ISSUER>CN=Certificate Authority,O=IPA.EXAMPLE' \
--maprule='(&(mail={subject_rfc822_name})(objectclass=inetorgperson))'
In this case you have to pass the principal name of the user account to
ipa-client-install
:
$ ipa-client-install \
--pkinit-identity=FILE:/path/to/cert.pem,/path/to/key.pem \
--pkinit-anchor=FILE:/path/to/kdc-ca-bundle.pem \
-p enrollmentuser
...
New options for ipa-client-install
The ipa-client-install
command is extended with two new options:
--pkinit-identity=IDENTITY
specifies the PKINIT identity information. The
option is mutually exclusive with --keytab
and --password
option.
See man krb5.conf(5)
for more information. Possible values are
FILE:/path/to/cert.pem,/path/to/key.pem
orFILE:/path/to/combined.pem
for certificate and private key in PEM format.PKCS12:/path/to/file.p12
for PKCS#12 file with a certificate and private key.PKCS11:...
to use a PKCS#11 providerDIR:/path/to/directory
with*.crt
and*.key
files.
--pkinit-anchor=FILEDIR
to load trust anchors (root and intermediate CA
certs) for KDC server and host identity. FILE is either an absolute path to
a PEM bundle (for example FILE:/etc/pki/tls/cert.pem
) or to an OpenSSL hash
directory (for example DIR:/etc/ssl/certs/
). The option can be used multiple
times to load trust anchors from several locations.
By default ipa-client-install
attempts to authenticate with the host
principal host/hostname@REALM
. Use -p
option to authenticate as a
different account.
Example:
$ ipa-client-install \
--pkinit-identity=FILE:/path/to/cert.pem,/path/to/key.pem \
--pkinit-anchor=FILE:/path/to/kdc-ca-bundle.pem \
...
Testing
The ipa certmap-match
command does not support hosts, yet. To test a
rule and certificate, you can run kinit:
$ kinit \
-X X509_user_identity=FILE:/path/to/cert.pem,/path/to/key.pem \
-X X509_anchors=FILE:/path/to/kdc-ca-bundle.pem \
host/host.ipa.example
Set the environment variable KRB5_CONFIG=/dev/stderr
for additional debug
information. On IPA servers the log file /var/log/krb5kdc.log
contains
information about cert authentication and filters:
Initializing IPA certauth plugin.
Doing certauth authorize for [host/host.ipa.example@IPA.EXAMPLE]
Got cert filter [(fqdn=host.ipa.example)]
PKINIT: freshness token received from host/host.ipa.example@IPA.EXAMPLE
The KDC caches certmap rules for 5 minutes. To test a new or modified certmap
rule immediately, the KDC must be restarted with the command
systemctl restart krb5kdc.service
.
cert map rules
See SSSD: Certificate mapping and matching rules and man sss-certmap(5).
certmap matching rule
certmap matching rules use RFC 4514 string representation of subject and issuer distinguished names (DN) in LDAP order with NSS-style attribute type names. RFC 4514 is the successor to RFC 2253. LDAP order is reverse to X.509 order of relative distinguised names, so common name (CN) typically comes before organization and country.
- Matching rules are regular expressions. Characters
^.[$()|*+?{\\
must be quoted, e.g..
becomes\.
. - Characters
=#+,;<=>\
have special meaning in in RDN attribute values and may be escaped. A,
becomes\,
, which is then quoted again as\\,
. - Some fields use different attribute type names than OpenSSL, e.g.
emailAddress
attributes is justE
.
To match a cert with issuer DN
O = "ACME, Inc.", CN = host.acme.example, emailAddress = info@acme.example
,
use the matching rule
<I>^E=info@acme.example,CN=host.acme.example,O=ACME\\, Inc\.$
.
certmap mapping rules
certmap mapping rules are used to associate a certificate with an account.
Mapping rules are LDAP queries with templating, e.g.
(fqdn={subject_dns_name})
uses the dNSName value from the certificate
subject alternative name extension.
- Combine the filter with
(!(krbprincipalkey=*))
to prevent further PKINIT authenticate after the host has been enrolled:(&(fqdn={subject_dns_name})(!(krbprincipalkey=*)))
- Use
(!(memberof=cn=ipaservers,cn=hostgroups,cn=accounts,.*))
to prevent PKINIT as an IPA server host or(memberof=pkinit-hosts,cn=hostgroups,cn=accounts,.*)
to limit PKINIT to hosts in a custompkinit-hosts
host group.