1.. _pkinit: 2 3PKINIT configuration 4==================== 5 6PKINIT is a preauthentication mechanism for Kerberos 5 which uses 7X.509 certificates to authenticate the KDC to clients and vice versa. 8PKINIT can also be used to enable anonymity support, allowing clients 9to communicate securely with the KDC or with application servers 10without authenticating as a particular client principal. 11 12 13Creating certificates 14--------------------- 15 16PKINIT requires an X.509 certificate for the KDC and one for each 17client principal which will authenticate using PKINIT. For anonymous 18PKINIT, a KDC certificate is required, but client certificates are 19not. A commercially issued server certificate can be used for the KDC 20certificate, but generally cannot be used for client certificates. 21 22The instruction in this section describe how to establish a 23certificate authority and create standard PKINIT certificates. Skip 24this section if you are using a commercially issued server certificate 25as the KDC certificate for anonymous PKINIT, or if you are configuring 26a client to use an Active Directory KDC. 27 28 29Generating a certificate authority certificate 30~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 31 32You can establish a new certificate authority (CA) for use with a 33PKINIT deployment with the commands:: 34 35 openssl genrsa -out cakey.pem 2048 36 openssl req -key cakey.pem -new -x509 -out cacert.pem -days 3650 37 38The second command will ask for the values of several certificate 39fields. These fields can be set to any values. You can adjust the 40expiration time of the CA certificate by changing the number after 41``-days``. Since the CA certificate must be deployed to client 42machines each time it changes, it should normally have an expiration 43time far in the future; however, expiration times after 2037 may cause 44interoperability issues in rare circumstances. 45 46The result of these commands will be two files, cakey.pem and 47cacert.pem. cakey.pem will contain a 2048-bit RSA private key, which 48must be carefully protected. cacert.pem will contain the CA 49certificate, which must be placed in the filesystems of the KDC and 50each client host. cakey.pem will be required to create KDC and client 51certificates. 52 53 54Generating a KDC certificate 55~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 56 57A KDC certificate for use with PKINIT is required to have some unusual 58fields, which makes generating them with OpenSSL somewhat complicated. 59First, you will need a file containing the following:: 60 61 [kdc_cert] 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 69 70 [kdc_princ_name] 71 realm=EXP:0,GeneralString:${ENV::REALM} 72 principal_name=EXP:1,SEQUENCE:kdc_principal_seq 73 74 [kdc_principal_seq] 75 name_type=EXP:0,INTEGER:2 76 name_string=EXP:1,SEQUENCE:kdc_principals 77 78 [kdc_principals] 79 princ1=GeneralString:krbtgt 80 princ2=GeneralString:${ENV::REALM} 81 82If the above contents are placed in extensions.kdc, you can generate 83and sign a KDC certificate with the following commands:: 84 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 90 rm kdc.req 91 92The second command will ask for the values of certificate fields, 93which can be set to any values. In the third command, substitute your 94KDC's realm name for YOUR_REALMNAME. You can adjust the certificate's 95expiration date by changing the number after ``-days``. Remember to 96create a new KDC certificate before the old one expires. 97 98The result of this operation will be in two files, kdckey.pem and 99kdc.pem. Both files must be placed in the KDC's filesystem. 100kdckey.pem, which contains the KDC's private key, must be carefully 101protected. 102 103If you examine the KDC certificate with ``openssl x509 -in kdc.pem 104-text -noout``, OpenSSL will not know how to display the KDC principal 105name in the Subject Alternative Name extension, so it will appear as 106``othername:<unsupported>``. This is normal and does not mean 107anything is wrong with the KDC certificate. 108 109 110Generating client certificates 111~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 112 113PKINIT client certificates also must have some unusual certificate 114fields. To generate a client certificate with OpenSSL for a 115single-component principal name, you will need an extensions file 116(different from the KDC extensions file above) containing:: 117 118 [client_cert] 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 126 127 [princ_name] 128 realm=EXP:0,GeneralString:${ENV::REALM} 129 principal_name=EXP:1,SEQUENCE:principal_seq 130 131 [principal_seq] 132 name_type=EXP:0,INTEGER:1 133 name_string=EXP:1,SEQUENCE:principals 134 135 [principals] 136 princ1=GeneralString:${ENV::CLIENT} 137 138If the above contents are placed in extensions.client, you can 139generate and sign a client certificate with the following commands:: 140 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 147 rm client.req 148 149Normally, the first two commands should be run on the client host, and 150the resulting client.req file transferred to the certificate authority 151host for the third command. As in the previous steps, the second 152command will ask for the values of certificate fields, which can be 153set to any values. In the third command, substitute your realm's name 154for YOUR_REALMNAME and the client's principal name (without realm) for 155YOUR_PRINCNAME. You can adjust the certificate's expiration date by 156changing the number after ``-days``. 157 158The result of this operation will be two files, clientkey.pem and 159client.pem. Both files must be present on the client's host; 160clientkey.pem, which contains the client's private key, must be 161protected from access by others. 162 163As in the KDC certificate, OpenSSL will display the client principal 164name as ``othername:<unsupported>`` in the Subject Alternative Name 165extension of a PKINIT client certificate. 166 167If 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 171certificate for ``host\/example.com@REALM`` which would not match the 172multi-component principal name.) For a two-component principal, the 173section should read:: 174 175 [principals] 176 princ1=GeneralString:${ENV::CLIENT1} 177 princ2=GeneralString:${ENV::CLIENT2} 178 179The environment variables ``CLIENT1`` and ``CLIENT2`` must then be set 180to the first and second components when running ``openssl x509``. 181 182 183Configuring the KDC 184------------------- 185 186The KDC must have filesystem access to the KDC certificate (kdc.pem) 187and the KDC private key (kdckey.pem). Configure the following 188relation in the KDC's :ref:`kdc.conf(5)` file, either in the 189:ref:`kdcdefaults` section or in a :ref:`kdc_realms` subsection (with 190appropriate pathnames):: 191 192 pkinit_identity = FILE:/var/lib/krb5kdc/kdc.pem,/var/lib/krb5kdc/kdckey.pem 193 194If any clients will authenticate using regular (as opposed to 195anonymous) PKINIT, the KDC must also have filesystem access to the CA 196certificate (cacert.pem), and the following configuration (with the 197appropriate pathname):: 198 199 pkinit_anchors = FILE:/var/lib/krb5kdc/cacert.pem 200 201Because of the larger size of requests and responses using PKINIT, you 202may also need to allow TCP access to the KDC:: 203 204 kdc_tcp_listen = 88 205 206Restart the :ref:`krb5kdc(8)` daemon to pick up the configuration 207changes. 208 209The principal entry for each PKINIT-using client must be configured to 210require preauthentication. Ensure this with the command:: 211 212 kadmin -q 'modprinc +requires_preauth YOUR_PRINCNAME' 213 214Starting with release 1.12, it is possible to remove the long-term 215keys of a principal entry, which can save some space in the database 216and help to clarify some PKINIT-related error conditions by not asking 217for a password:: 218 219 kadmin -q 'purgekeys -all YOUR_PRINCNAME' 220 221These principal options can also be specified at principal creation 222time as follows:: 223 224 kadmin -q 'add_principal +requires_preauth -nokey YOUR_PRINCNAME' 225 226By default, the KDC requires PKINIT client certificates to have the 227standard Extended Key Usage and Subject Alternative Name attributes 228for PKINIT. Starting in release 1.16, it is possible to authorize 229client certificates based on the subject or other criteria instead of 230the standard PKINIT Subject Alternative Name, by setting the 231**pkinit_cert_match** string attribute on each client principal entry. 232For example:: 233 234 kadmin set_string user@REALM pkinit_cert_match "<SUBJECT>CN=user@REALM$" 235 236The **pkinit_cert_match** string attribute follows the syntax used by 237the :ref:`krb5.conf(5)` **pkinit_cert_match** relation. To allow the 238use of non-PKINIT client certificates, it will also be necessary to 239disable key usage checking using the **pkinit_eku_checking** relation; 240for example:: 241 242 [kdcdefaults] 243 pkinit_eku_checking = none 244 245 246 247Configuring the clients 248----------------------- 249 250Client hosts must be configured to trust the issuing authority for the 251KDC certificate. For a newly established certificate authority, the 252client host must have filesystem access to the CA certificate 253(cacert.pem) and the following relation in :ref:`krb5.conf(5)` in the 254appropriate :ref:`realms` subsection (with appropriate pathnames):: 255 256 pkinit_anchors = FILE:/etc/krb5/cacert.pem 257 258If the KDC certificate is a commercially issued server certificate, 259the issuing certificate is most likely included in a system directory. 260You can specify it by filename as above, or specify the whole 261directory like so:: 262 263 pkinit_anchors = DIR:/etc/ssl/certs 264 265A commercially issued server certificate will usually not have the 266standard PKINIT principal name or Extended Key Usage extensions, so 267the following additional configuration is required:: 268 269 pkinit_eku_checking = kpServerAuth 270 pkinit_kdc_hostname = hostname.of.kdc.certificate 271 272Multiple **pkinit_kdc_hostname** relations can be configured to 273recognize multiple KDC certificates. If the KDC is an Active 274Directory domain controller, setting **pkinit_kdc_hostname** is 275necessary, but it should not be necessary to set 276**pkinit_eku_checking**. 277 278To perform regular (as opposed to anonymous) PKINIT authentication, a 279client host must have filesystem access to a client certificate 280(client.pem), and the corresponding private key (clientkey.pem). 281Configure the following relations in the client host's 282:ref:`krb5.conf(5)` file in the appropriate :ref:`realms` subsection 283(with appropriate pathnames):: 284 285 pkinit_identities = FILE:/etc/krb5/client.pem,/etc/krb5/clientkey.pem 286 287If the KDC and client are properly configured, it should now be 288possible to run ``kinit username`` without entering a password. 289 290 291.. _anonymous_pkinit: 292 293Anonymous PKINIT 294---------------- 295 296Anonymity support in Kerberos allows a client to obtain a ticket 297without authenticating as any particular principal. Such a ticket can 298be used as a FAST armor ticket, or to securely communicate with an 299application server anonymously. 300 301To configure anonymity support, you must generate or otherwise procure 302a KDC certificate and configure the KDC host, but you do not need to 303generate any client certificates. On the KDC, you must set the 304**pkinit_identity** variable to provide the KDC certificate, but do 305not need to set the **pkinit_anchors** variable or store the issuing 306certificate if you won't have any client certificates to verify. On 307client hosts, you must set the **pkinit_anchors** variable (and 308possibly **pkinit_kdc_hostname** and **pkinit_eku_checking**) in order 309to trust the issuing authority for the KDC certificate, but do not 310need to set the **pkinit_identities** variable. 311 312Anonymity support is not enabled by default. To enable it, you must 313create the principal ``WELLKNOWN/ANONYMOUS`` using the command:: 314 315 kadmin -q 'addprinc -randkey WELLKNOWN/ANONYMOUS' 316 317Some Kerberos deployments include application servers which lack 318proper access control, and grant some level of access to any user who 319can authenticate. In such an environment, enabling anonymity support 320on the KDC would present a security issue. If you need to enable 321anonymity support for TGTs (for use as FAST armor tickets) without 322enabling anonymous authentication to application servers, you can set 323the variable **restrict_anonymous_to_tgt** to ``true`` in the 324appropriate :ref:`kdc_realms` subsection of the KDC's 325:ref:`kdc.conf(5)` file. 326 327To obtain anonymous credentials on a client, run ``kinit -n``, or 328``kinit -n @REALMNAME`` to specify a realm. The resulting tickets 329will have the client name ``WELLKNOWN/ANONYMOUS@WELLKNOWN:ANONYMOUS``. 330 331 332Freshness tokens 333---------------- 334 335Freshness tokens can ensure that the client has recently had access to 336its certificate private key. If freshness tokens are not required by 337the KDC, a client program with temporary possession of the private key 338can compose requests for future timestamps and use them later. 339 340In release 1.17 and later, freshness tokens are supported by the 341client and are sent by the KDC when the client indicates support for 342them. Because not all clients support freshness tokens yet, they are 343not required by default. To check if freshness tokens are supported 344by a realm's clients, look in the KDC logs for the lines:: 345 346 PKINIT: freshness token received from <client principal> 347 PKINIT: no freshness token received from <client principal> 348 349To require freshness tokens for all clients in a realm (except for 350clients 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 353test that this option is in effect, run ``kinit -X disable_freshness`` 354and verify that authentication is unsuccessful. 355