6 PKINIT is a preauthentication mechanism for Kerberos 5 which uses
7 X.509 certificates to authenticate the KDC to clients and vice versa.
8 PKINIT can also be used to enable anonymity support, allowing clients
9 to communicate securely with the KDC or with application servers
10 without authenticating as a particular client principal.
16 PKINIT requires an X.509 certificate for the KDC and one for each
17 client principal which will authenticate using PKINIT. For anonymous
18 PKINIT, a KDC certificate is required, but client certificates are
19 not. A commercially issued server certificate can be used for the KDC
20 certificate, but generally cannot be used for client certificates.
22 The instruction in this section describe how to establish a
23 certificate authority and create standard PKINIT certificates. Skip
24 this section if you are using a commercially issued server certificate
25 as the KDC certificate for anonymous PKINIT, or if you are configuring
26 a client to use an Active Directory KDC.
29 Generating a certificate authority certificate
30 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
32 You can establish a new certificate authority (CA) for use with a
33 PKINIT deployment with the commands::
35 openssl genrsa -out cakey.pem 2048
36 openssl req -key cakey.pem -new -x509 -out cacert.pem -days 3650
38 The second command will ask for the values of several certificate
39 fields. These fields can be set to any values. You can adjust the
40 expiration time of the CA certificate by changing the number after
41 ``-days``. Since the CA certificate must be deployed to client
42 machines each time it changes, it should normally have an expiration
43 time far in the future; however, expiration times after 2037 may cause
44 interoperability issues in rare circumstances.
46 The result of these commands will be two files, cakey.pem and
47 cacert.pem. cakey.pem will contain a 2048-bit RSA private key, which
48 must be carefully protected. cacert.pem will contain the CA
49 certificate, which must be placed in the filesystems of the KDC and
50 each client host. cakey.pem will be required to create KDC and client
54 Generating a KDC certificate
55 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
57 A KDC certificate for use with PKINIT is required to have some unusual
58 fields, which makes generating them with OpenSSL somewhat complicated.
59 First, you will need a file containing the following::
62 basicConstraints=CA:FALSE
63 keyUsage=nonRepudiation,digitalSignature,keyEncipherment,keyAgreement
64 extendedKeyUsage=1.3.6.1.5.2.3.5
65 subjectKeyIdentifier=hash
66 authorityKeyIdentifier=keyid,issuer
67 issuerAltName=issuer:copy
68 subjectAltName=otherName:1.3.6.1.5.2.2;SEQUENCE:kdc_princ_name
71 realm=EXP:0,GeneralString:${ENV::REALM}
72 principal_name=EXP:1,SEQUENCE:kdc_principal_seq
75 name_type=EXP:0,INTEGER:2
76 name_string=EXP:1,SEQUENCE:kdc_principals
79 princ1=GeneralString:krbtgt
80 princ2=GeneralString:${ENV::REALM}
82 If the above contents are placed in extensions.kdc, you can generate
83 and sign a KDC certificate with the following commands::
85 openssl genrsa -out kdckey.pem 2048
86 openssl req -new -out kdc.req -key kdckey.pem
87 env REALM=YOUR_REALMNAME openssl x509 -req -in kdc.req \
88 -CAkey cakey.pem -CA cacert.pem -out kdc.pem -days 365 \
89 -extfile extensions.kdc -extensions kdc_cert -CAcreateserial
92 The second command will ask for the values of certificate fields,
93 which can be set to any values. In the third command, substitute your
94 KDC's realm name for YOUR_REALMNAME. You can adjust the certificate's
95 expiration date by changing the number after ``-days``. Remember to
96 create a new KDC certificate before the old one expires.
98 The result of this operation will be in two files, kdckey.pem and
99 kdc.pem. Both files must be placed in the KDC's filesystem.
100 kdckey.pem, which contains the KDC's private key, must be carefully
103 If you examine the KDC certificate with ``openssl x509 -in kdc.pem
104 -text -noout``, OpenSSL will not know how to display the KDC principal
105 name in the Subject Alternative Name extension, so it will appear as
106 ``othername:<unsupported>``. This is normal and does not mean
107 anything is wrong with the KDC certificate.
110 Generating client certificates
111 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
113 PKINIT client certificates also must have some unusual certificate
114 fields. To generate a client certificate with OpenSSL for a
115 single-component principal name, you will need an extensions file
116 (different from the KDC extensions file above) containing::
119 basicConstraints=CA:FALSE
120 keyUsage=digitalSignature,keyEncipherment,keyAgreement
121 extendedKeyUsage=1.3.6.1.5.2.3.4
122 subjectKeyIdentifier=hash
123 authorityKeyIdentifier=keyid,issuer
124 issuerAltName=issuer:copy
125 subjectAltName=otherName:1.3.6.1.5.2.2;SEQUENCE:princ_name
128 realm=EXP:0,GeneralString:${ENV::REALM}
129 principal_name=EXP:1,SEQUENCE:principal_seq
132 name_type=EXP:0,INTEGER:1
133 name_string=EXP:1,SEQUENCE:principals
136 princ1=GeneralString:${ENV::CLIENT}
138 If the above contents are placed in extensions.client, you can
139 generate and sign a client certificate with the following commands::
141 openssl genrsa -out clientkey.pem 2048
142 openssl req -new -key clientkey.pem -out client.req
143 env REALM=YOUR_REALMNAME CLIENT=YOUR_PRINCNAME openssl x509 \
144 -CAkey cakey.pem -CA cacert.pem -req -in client.req \
145 -extensions client_cert -extfile extensions.client \
146 -days 365 -out client.pem
149 Normally, the first two commands should be run on the client host, and
150 the resulting client.req file transferred to the certificate authority
151 host for the third command. As in the previous steps, the second
152 command will ask for the values of certificate fields, which can be
153 set to any values. In the third command, substitute your realm's name
154 for YOUR_REALMNAME and the client's principal name (without realm) for
155 YOUR_PRINCNAME. You can adjust the certificate's expiration date by
156 changing the number after ``-days``.
158 The result of this operation will be two files, clientkey.pem and
159 client.pem. Both files must be present on the client's host;
160 clientkey.pem, which contains the client's private key, must be
161 protected from access by others.
163 As in the KDC certificate, OpenSSL will display the client principal
164 name as ``othername:<unsupported>`` in the Subject Alternative Name
165 extension of a PKINIT client certificate.
167 If the client principal name contains more than one component
168 (e.g. ``host/example.com@REALM``), the ``[principals]`` section of
169 ``extensions.client`` must be altered to contain multiple entries.
170 (Simply setting ``CLIENT`` to ``host/example.com`` would generate a
171 certificate for ``host\/example.com@REALM`` which would not match the
172 multi-component principal name.) For a two-component principal, the
173 section should read::
176 princ1=GeneralString:${ENV::CLIENT1}
177 princ2=GeneralString:${ENV::CLIENT2}
179 The environment variables ``CLIENT1`` and ``CLIENT2`` must then be set
180 to the first and second components when running ``openssl x509``.
186 The KDC must have filesystem access to the KDC certificate (kdc.pem)
187 and the KDC private key (kdckey.pem). Configure the following
188 relation in the KDC's :ref:`kdc.conf(5)` file, either in the
189 :ref:`kdcdefaults` section or in a :ref:`kdc_realms` subsection (with
190 appropriate pathnames)::
192 pkinit_identity = FILE:/var/lib/krb5kdc/kdc.pem,/var/lib/krb5kdc/kdckey.pem
194 If any clients will authenticate using regular (as opposed to
195 anonymous) PKINIT, the KDC must also have filesystem access to the CA
196 certificate (cacert.pem), and the following configuration (with the
197 appropriate pathname)::
199 pkinit_anchors = FILE:/var/lib/krb5kdc/cacert.pem
201 Because of the larger size of requests and responses using PKINIT, you
202 may also need to allow TCP access to the KDC::
206 Restart the :ref:`krb5kdc(8)` daemon to pick up the configuration
209 The principal entry for each PKINIT-using client must be configured to
210 require preauthentication. Ensure this with the command::
212 kadmin -q 'modprinc +requires_preauth YOUR_PRINCNAME'
214 Starting with release 1.12, it is possible to remove the long-term
215 keys of a principal entry, which can save some space in the database
216 and help to clarify some PKINIT-related error conditions by not asking
219 kadmin -q 'purgekeys -all YOUR_PRINCNAME'
221 These principal options can also be specified at principal creation
224 kadmin -q 'add_principal +requires_preauth -nokey YOUR_PRINCNAME'
226 By default, the KDC requires PKINIT client certificates to have the
227 standard Extended Key Usage and Subject Alternative Name attributes
228 for PKINIT. Starting in release 1.16, it is possible to authorize
229 client certificates based on the subject or other criteria instead of
230 the standard PKINIT Subject Alternative Name, by setting the
231 **pkinit_cert_match** string attribute on each client principal entry.
234 kadmin set_string user@REALM pkinit_cert_match "<SUBJECT>CN=user@REALM$"
236 The **pkinit_cert_match** string attribute follows the syntax used by
237 the :ref:`krb5.conf(5)` **pkinit_cert_match** relation. To allow the
238 use of non-PKINIT client certificates, it will also be necessary to
239 disable key usage checking using the **pkinit_eku_checking** relation;
243 pkinit_eku_checking = none
247 Configuring the clients
248 -----------------------
250 Client hosts must be configured to trust the issuing authority for the
251 KDC certificate. For a newly established certificate authority, the
252 client host must have filesystem access to the CA certificate
253 (cacert.pem) and the following relation in :ref:`krb5.conf(5)` in the
254 appropriate :ref:`realms` subsection (with appropriate pathnames)::
256 pkinit_anchors = FILE:/etc/krb5/cacert.pem
258 If the KDC certificate is a commercially issued server certificate,
259 the issuing certificate is most likely included in a system directory.
260 You can specify it by filename as above, or specify the whole
263 pkinit_anchors = DIR:/etc/ssl/certs
265 A commercially issued server certificate will usually not have the
266 standard PKINIT principal name or Extended Key Usage extensions, so
267 the following additional configuration is required::
269 pkinit_eku_checking = kpServerAuth
270 pkinit_kdc_hostname = hostname.of.kdc.certificate
272 Multiple **pkinit_kdc_hostname** relations can be configured to
273 recognize multiple KDC certificates. If the KDC is an Active
274 Directory domain controller, setting **pkinit_kdc_hostname** is
275 necessary, but it should not be necessary to set
276 **pkinit_eku_checking**.
278 To perform regular (as opposed to anonymous) PKINIT authentication, a
279 client host must have filesystem access to a client certificate
280 (client.pem), and the corresponding private key (clientkey.pem).
281 Configure the following relations in the client host's
282 :ref:`krb5.conf(5)` file in the appropriate :ref:`realms` subsection
283 (with appropriate pathnames)::
285 pkinit_identities = FILE:/etc/krb5/client.pem,/etc/krb5/clientkey.pem
287 If the KDC and client are properly configured, it should now be
288 possible to run ``kinit username`` without entering a password.
291 .. _anonymous_pkinit:
296 Anonymity support in Kerberos allows a client to obtain a ticket
297 without authenticating as any particular principal. Such a ticket can
298 be used as a FAST armor ticket, or to securely communicate with an
299 application server anonymously.
301 To configure anonymity support, you must generate or otherwise procure
302 a KDC certificate and configure the KDC host, but you do not need to
303 generate any client certificates. On the KDC, you must set the
304 **pkinit_identity** variable to provide the KDC certificate, but do
305 not need to set the **pkinit_anchors** variable or store the issuing
306 certificate if you won't have any client certificates to verify. On
307 client hosts, you must set the **pkinit_anchors** variable (and
308 possibly **pkinit_kdc_hostname** and **pkinit_eku_checking**) in order
309 to trust the issuing authority for the KDC certificate, but do not
310 need to set the **pkinit_identities** variable.
312 Anonymity support is not enabled by default. To enable it, you must
313 create the principal ``WELLKNOWN/ANONYMOUS`` using the command::
315 kadmin -q 'addprinc -randkey WELLKNOWN/ANONYMOUS'
317 Some Kerberos deployments include application servers which lack
318 proper access control, and grant some level of access to any user who
319 can authenticate. In such an environment, enabling anonymity support
320 on the KDC would present a security issue. If you need to enable
321 anonymity support for TGTs (for use as FAST armor tickets) without
322 enabling anonymous authentication to application servers, you can set
323 the variable **restrict_anonymous_to_tgt** to ``true`` in the
324 appropriate :ref:`kdc_realms` subsection of the KDC's
325 :ref:`kdc.conf(5)` file.
327 To obtain anonymous credentials on a client, run ``kinit -n``, or
328 ``kinit -n @REALMNAME`` to specify a realm. The resulting tickets
329 will have the client name ``WELLKNOWN/ANONYMOUS@WELLKNOWN:ANONYMOUS``.
335 Freshness tokens can ensure that the client has recently had access to
336 its certificate private key. If freshness tokens are not required by
337 the KDC, a client program with temporary possession of the private key
338 can compose requests for future timestamps and use them later.
340 In release 1.17 and later, freshness tokens are supported by the
341 client and are sent by the KDC when the client indicates support for
342 them. Because not all clients support freshness tokens yet, they are
343 not required by default. To check if freshness tokens are supported
344 by a realm's clients, look in the KDC logs for the lines::
346 PKINIT: freshness token received from <client principal>
347 PKINIT: no freshness token received from <client principal>
349 To require freshness tokens for all clients in a realm (except for
350 clients authenticating anonymously), set the
351 **pkinit_require_freshness** variable to ``true`` in the appropriate
352 :ref:`kdc_realms` subsection of the KDC's :ref:`kdc.conf(5)` file. To
353 test that this option is in effect, run ``kinit -X disable_freshness``
354 and verify that authentication is unsuccessful.