In part 1 I discussed how to configure NSS and OpenSSL. In part 2, I discussed how to configure pam_pkcs11 and how to test a smartcard against the NSS database we set up. In this part, I’ll discuss how to add pam_krb5 into the mix to automatically get a Kerberos ticket from an Active Directory domain using PKINIT.
Notice that this post will discuss a package that is yet to be officially released by Red Hat. Whenever this is officially released, it may have different configuration options, or different functionality. I’ll update this post at that time.
Configure the krb5.conf
Add the following information into the [libdefaults] section:
default_realm = EXAMPLE.COM
This tells the Kerberos client that by default, it will use the EXAMPLE.COM realm unless otherwise specified. If you are in an environment where another Kerberos realm is supposed to be your default, you can skip the [libdefaults] section. Later, I’ll show you how pam_krb5 can work without this configuration setting.
Add the following information into the [realms] section:
EXAMPLE.COM = {
kdc = kdc1.example.com
kdc = kdc2.example.com
admin_server = kdc1.example.com
default_domain = example.com
}
This tells the Kerberos client about the EXAMPLE.COM domain; specifically: what the servers are, and the default domain.
Add the following into the [domain_realm] section:
.example.com = EXAMPLE.COM
This maps the DNS domain name to the Kerberos domain name; if you have service records for your Active Directory domain, this may not be necessary.
Add the following into the [appdefaults] section:
allow_pkinit = yes
pkinit = {
client_ca_certificate_pool = /etc/pki/tls/certs
EXAMPLE.COM = {
trusted_guid = f7:11:44:70:97:a8:40:d8:bb:a1:b8:7f:4e:a2:ed:fe 51:6d:28:dd:57:af:4d:b5:90:09:00:a1:c0:39:48:a2
is_hw = yes
pkinit_cert_match = &&<EKU>msScLogin,<KU>digitalSignature
}
}
This is where the magic happens. First we tell the Kerberos client to allow pkinit (which is for pre-authentication, aka token login). Next we make a section for pkinit, tell it where the PEM (ascii) encoded CA certs are, and make a section for our domain. In the domain section, we tell the Kerberos client which servers to trust, that the token is a hardware token, and the criteria needed for a valid login certificate from the smartcard.
The pkinit_cert_match field has the following documentation in the version of pkinit-nss that I am discussing:
pkinit_cert_match – Alternate combinations of client certificate
characteristics which would cause it to be deemed
sufficient for use. Rules are specified as combinations
of fields and specifications in the form
[&&]<FIELD1>spec1[,<FIELD2>spec2[,...]] [...]
<FIELD1>spec1[,<FIELD2>spec2[,...]] [...]
[||]<FIELD1>spec1[,<FIELD2>spec2[,...]] [...]
Recognized fields and the types of specifications to be
used include
<SUBJECT> Regular expression.
<ISSUER> Regular expression.
<SAN> Regular expression.
<EKU> List of zero or more values, possibly
including “pkinit”, “msScLogin”,
“clientAuth”, and “emailProtection”.
<KU> List of zero or more values, possibly
including “digitalSignature” and
“keyEncipherment”.
There is no default.
pkinit-nss needs to match exactly one certificate off of your smartcard; you can use these criteria to specify which certificate will be used. Notice that in the above configuration I chose a certificate that was allowed for Microsoft Smart Card Login, and was a digital signature type of certificate.
Notice that the guids are collected via the pkinit-show-cert-guid command, and that they are space delimited.
Collecting server guids
- Get the server’s public certificate
- openssl s_client -connect kdc1.example.com:636
- Find the section that starts with “BEGIN CERTIFICATE” and ends with “END CERTIFICATE”; copy everything including the begin and end sections, and paste it into a file
- Use pkinit-show-cert-guid on the file to get the guid
- pkinit-show-cert-guid <file>
- Repeat for every Active Directory server
Configure PAM
The following is an example /etc/pam.d/system-auth file:
auth required pam_env.so auth [success=2 default=ignore] pam_succeed_if.so service notin login:gdm:xdm:kdm:xscreensaver:gnome-screensaver:kscreensaver quiet use_uid auth [success=ok authinfo_unavail=2 ignore=2 default=die] pam_pkcs11.so auth [default=ignore] pam_krb5.so no_subsequent_prompt no_initial_prompt auth sufficient pam_permit.so auth sufficient pam_unix.so likeauth auth required pam_deny.so account required pam_unix.so broken_shadow account sufficient pam_localuser.so account sufficient pam_krb5.so account required pam_permit.so password optional pam_pkcs11.so password requisite pam_cracklib.so retry=3 dcredit=-1 ucredit=-1 ocredit=-1 lcredit=-1 minlen=10 password sufficient pam_unix.so md5 shadow try_first_pass use_authtok remember=5 password required pam_deny.so session optional pam_keyinit.so revoke session optional pam_krb5.so session required pam_limits.so session [success=1 default=ignore] pam_succeed_if.so service in crond quiet use_uid session required pam_unix.so
It is important to understand what is happening in the auth stack here. Read the following three lines carefully:
auth [success=ok authinfo_unavail=2 ignore=2 default=die] pam_pkcs11.so auth [default=ignore] pam_krb5.so no_subsequent_prompt no_initial_prompt auth sufficient pam_permit.so
The first line says if pam_pkcs11 succeeds, continue on; if a card isn’t available, or we can’t map the card identity to a user, skip the next two lines; if the user puts his pin in incorrectly, exit with a failure. The second line says don’t prompt for a pin, don’t prompt for a password if the pin fails, and ignore the return value of pam_krb5. The third line says no matter what, return success.
This configuration ensures a few things:
- Ensures if the user types her pin in incorrectly, it won’t cause two incorrect pins against the card
- Ensures that the system will only try to get a Kerberos ticket if the user is using a card
- Ensures that the user can log into the system with a card even if they can’t get a Kerberos ticket
- If you wish to require valid Kerberos authentication, pam_krb5 should be marked as “required”, the pam_success line should be removed, and the pam_pkcs11 module line’s arguments should be changed to “authinfo_unavail=1 ignore=1″
Notice that if you are trying to completely eliminate passwords, that this PAM configuration won’t fully do it. This configuration still allows password authentication to the local system. You should tweak this configuration as necessary. Remember, however, that you likely don’t wish to lock root out of the system – so be careful!
As I mentioned earlier, if your default Kerberos domain cannot be your Active Directory domain, you can specify it explicitly in the PAM configuration; to do this, your auth line for pam_krb5 would change to the following:
auth [default=done] pam_krb5.so realm=EXAMPLE.COM no_subsequent_prompt no_initial_prompt
Conclusion
This series should be a good starting ground for getting your PKI environment set up on your RHEL systems. In the future I will discuss more ways to eliminate passwords by using Smart Card authentication.
If you have any questions, please be sure to leave a comment!
Update (04/24/2009): I updated the krb5.conf configuration.
pkinit_cert_match = &&msScLogin,digitalSignature
should have read as:
pkinit_cert_match = &&<EKU>msScLogin,<KU>digitalSignature
Update (05/12/2009): The PAM configuration was slightly incorrect. The way it was previously written would deny users access if pam_krb failed.
Update (05/26/2009): The openssl s_client command was slightly incorrect; I changed “connect” to “-connect”.
Related posts:
- Seamless Smartcard login with pam_pkcs11, and pam_krb5 against an Active Directory Domain using Red Hat Enterprise Linux 5 (Part 2)
- Seamless Smartcard login with pam_pkcs11, and pam_krb5 against an Active Directory Domain using Red Hat Enterprise Linux 5 (Part 1)
- Using NSS with OpenSSH for Smart Card Login
- SSL replication and CA trusts in Sun Directory Server 6.x








