Seamless Smartcard login with pam_pkcs11, and pam_krb5 against an Active Directory Domain using Red Hat Enterprise Linux 5 (Part 3)

LDAP, pki

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

  1. Get the server’s public certificate
    1. openssl s_client -connect kdc1.example.com:636
    2. 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
  2. Use pkinit-show-cert-guid on the file to get the guid
    • pkinit-show-cert-guid <file>
  3. 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:

  1. Ensures if the user types her pin in incorrectly, it won’t cause two incorrect pins against the card
  2. Ensures that the system will only try to get a Kerberos ticket if the user is using a card
  3. 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:

  1. Seamless Smartcard login with pam_pkcs11, and pam_krb5 against an Active Directory Domain using Red Hat Enterprise Linux 5 (Part 2)
  2. Seamless Smartcard login with pam_pkcs11, and pam_krb5 against an Active Directory Domain using Red Hat Enterprise Linux 5 (Part 1)
  3. Using NSS with OpenSSH for Smart Card Login
  4. SSL replication and CA trusts in Sun Directory Server 6.x
28 Comments

28 Responses to “Seamless Smartcard login with pam_pkcs11, and pam_krb5 against an Active Directory Domain using Red Hat Enterprise Linux 5 (Part 3)”

  1. Katriel says:

    It should be noted that RHEL5 supports only coolkey, which in turn supports a limited set of smartcards/tokens.
    If doing this on Fedora, and using pkinit-nss (Fedora originally comes with pkinit-openssl), you should use “modutil -add” to allow nss to use opensc cards/tokens.
    Compiling opensc on RHEL5 and adding the module with modutil should work as well, while widening the range of supported cards (through pcsc).
    Also, since MS kdc certs usually don’t include the needed EKU for a KDC cert (1.3.6.1.5.2.3.5), you should use “pkinit_eku_checking = kpServerAuth” and pkinit_kdc_hostname = ” for checking for the “Server Authentication” EKU and matching the server DNS name for the “Subject Alternative Name”.

    • Ryan Lane says:

      I wasn’t aware of the issue with the MS KDC cert (I work in an environment where the EKU is included). Thanks for the info!

      Also, I’d like to mention that in RHEL 5.3 a new version of pkinit-nss was released that adds the functionality mentioned in this post.

  2. Jonas says:

    Hi,
    When running “pkinit-show-cert-guid ” I get: Segmentation fault. I have used pkinit-nss-0.7.6-1.tar.gz. Isn’t that the right package for my Fedora 10?

    Best regards
    Jonas

  3. Jonas says:

    Hi
    When i run the command “pkinit-show-cert-guid” on my file I get: “Segmentation fault”. I have installed pkinit-nss-0.7.6-1.tar.gz since pkinit-nss doesn’t seem to be shipped with my Fedora 10. Is that the right version? It seem as if it has been taken away from http://people.redhat.com/~nalin/pkinit-nss/ where I first found it.
    Best regards
    /Jonas

    • Ryan Lane says:

      Jonas,

      See:

      https://bugzilla.redhat.com/show_bug.cgi?id=226300

      It looks like pkinit-nss was removed from Fedora 10 because it ships Kerberos 1.6.3, which natively supports smartcard authentication. It probably doesn’t use NSS yet. You’ll need to read the Kerberos documentation on how to get this working in Fedora. A lot of the configuration is the same, but I know for sure it differs some.

      I originally tested the smartcard support against Kerberos 1.6.3 and got it working. Maybe I’ll do a blog post on that.

  4. Chris says:

    Where can we obtain this “package that is yet to be officially released by Red Hat” – I’ve been looking everywhere

  5. Ryan Lane says:

    The package was recently released in RHEL 5.3. The package version is: pkinit-nss-0.7.6-1

    I tested the package and it works for me.

  6. Chris says:

    I tried for hours and can’t get it to work. I am also using RHEL5.3

    I think the problem is with the PAM module for Kerberos (pam_krb5.so). The manual pages do not make any reference to it being pkinit enabled. For example, there should be a module option called try_pkinit, but it doesn’t appear in the man pages.

    As usual PAM’s logging is dreadfully poor and I don’t have any idea what the error is.

  7. Chris says:

    I also did some protocol analysis on this. PAM is not attempting a pkinit – the AS-REQ to Active Directory looks exactly like a password-based kinit

  8. Ryan Lane says:

    @chris pkinit-nss adds the pkinit extension to kerberos. I’ve tested using 5.2 and just installing the newest pkinit-nss and had no problems.

    I know for sure that pkinit is happening because it asks for my PIN, and I get a kerberos ticket. The AD server I’m testing against is requiring hardware authentication, and my pin isn’t the same as my password.

    Before trying to get pam_krb5 working, make sure you can get a kerberos ticket from the AD server using kinit.

    Also, it is really important that “client_ca_certificate_pool” is set, and the directory you point to has the CAs for your client certificate and your server certificates, and has the root CAs. Remember to do the hash links inside of the directories.

    You also want to ensure that “pkinit_cert_match” is set to the right things. You need to get exactly one certificate back from the card.

    When testing using kinit, try it with debugging turned on:

    /usr/kerberos/bin/kinit -X debug=stdout,99 @.

  9. Ryan Lane says:

    Stupid wordpress stripping things… try kinit this way:

    /usr/kerberos/bin/kinit -X debug=stdout,99 user@SUBDOMAIN.DOMAIN

  10. Ozmen DEMIRKOL says:

    Hi;
    I tried all this things on Centos 5.3. But, when i try to login via console or gnome interface system rejects me back to login screen.
    that In secure log file writes “authentication success”, but i can’t login. Always system returns back to the login screen.
    I think proplem is on pam_pkcs11.so library.
    Do you have any idea? Thank you

  11. Ozmen DEMIRKOL says:

    Unfortunately, i can’t success about login when pin and domain passwords are different. i’m keep going to get “preauthorization failed” message. Just after that message login screen close and reopen.

  12. Ryan Lane says:

    @Ozmen Have you got everything working from the command line? Are you getting something back via pkcs11_inspect, and is pklogin_finder mapping it to a user name?

    If not you need to configure pam_pkcs11 correctly. If so, it may be a Kerberos problem.

    Are you able to get a Kerberos ticket with your smart card using kinit? If not, check your kerberos configuration again; to get debug info with the kinit command, see the above comment for the syntax. If kinit is working, then this may be a PAM problem. Turn on debug messages in pam to see what the issue is.

  13. Ozmen DEMIRKOL says:

    @Ryan. When i use pkcs11_inspect or pklogin_finger i can get right username an i wrote it in cn_map. Additionaly, i can get ticket by using kinit and domain password. But i can’t get it by using smartcard. Only, if i make pin and domain password same and “auth krb5.so use_first_pass” setting in system-auth i can login system and take a ticket. But this is not realy sc login.

    when i use “kinit -X debug=stdout,99 user@SUBDOMAIN.DOMAIN” command i get some messages like “private key not found” and end of the line system ask me user domain password. If i enter correct domain password i can get the ticket.

    If you want to take a look my krb5.conf, system-auth or any other files i can send you or this page. Because that system is for test

    Thank you

    • Ryan Lane says:

      If you send me the debug output, and your krb5.conf, I can probably tell you how to fix your issue. Also send me the output of: rpm -q pkinit-nss

      It does sound like kerberos isn’t able to find a certificate it trusts on your card.

      You can contact me via the “Contact” link at the top left of the blog.

  14. J Hefferman says:

    Hello,

    I’m having some difficulty getting a TGT with a certificate using the MIT kinit client. The logon works properly, but I receive a host of errors when running /usr/kerberos/bin/kinit -X debug=stdout,99 princ@REALM.

    The final error is: ‘Unable to find certificate’.

    I suspect that the client is not able to read the smart card?

    Would it be possible to send you my pam_pkcs11.conf, system-auth and krb5.conf? I could also send the debug from the MIT client if that would help. The problems I’m having may be similar to those of Ozmens.

    I am using pkinit-nss-0.7.6.

    kinit appears to find the certificates defined by client_ca_certificate_pool as it returns

    Added “/etc/pki/tls/certs” to CA certificate search pool.
    Looking for the user’s certificate.
    Scanning text files for certificates.
    Returning list of 0 certs.
    No certificates found.

    It seems to find the root CA in the nss database:

    Scanning slot “NSS User Private Key and Certificate Services ” for certificates.
    Returning list of 0 keys.
    Skipping “CN=CERN Root CA,DC=cern,DC=ch”: no matching private key loaded.

    And finally states:

    Scanning slot “NSS Internal Cryptographic Services ” for certificates.
    No certificates found.
    Need to log in to NSS User Private Key and Certificate Services .
    Need to log in to NSS Internal Cryptographic Services .
    Unable to find certificate.

    Thanks for any help

    • Ryan Lane says:

      Sure, you can send me an email with all of the files, and the debug output. I’ll take a look at it. From reading your initial output, it looks like it isn’t accessing the smart card.

      Have you checked to see if libcoolkeypk11.so is in your system’s NSS database? Run the following command:

      modutil -list -dbdir /etc/pki/nssdb

      It should have a module with “library name: libcoolkeypk11.so”; if not you’ll need to add it:

      modutil -add "CookKey PKCS #11 Module" -libfile libcoolkeypk11.so

      • J Hefferman says:

        Ok thanks a lot, I used modutil -add to add the module to nss (details in e-mail I sent to you), and now kinit can read the card.

        Unfortunately, it returns a generic error at the end of the kinit. The configuration files are attached to the e-mail in case you have time for a quick look.

        Cheers,

        John

  15. Jonas says:

    Hi again Ryan,
    It’s me again trying to use Fedora 10 (and now 11). All works fine but the Kerberos-part. No ticket at login and kinit still wants password. Been trying to read the MIT Kerberos documentation but I guess I miss some packages and/or do the configuration wrong. Is it possible to use pkinit-nss even if MIT Kerberos natively supports pkinit? I think NSS is easier to use than OpenSSL.
    Regards
    /Jonas

    • Ryan Lane says:

      You should be able to. I agree that NSS is easier to deal with, and Red Hat seems to be going that path. Try it and see if it works. My documentation only focuses on NSS.

    • Patrik says:

      Hey Jonas,

      I was curious if you ever got pkinit to work with krb 1.6.3 ?
      And if you did, do you have time to spare me some details about how you made it ?

      Im also running fedora 10 and need to get smartcard working with pkinit to get a ticket from our kdc servers.

      Best regards,
      Patrik, sweden.

  16. marcello mezzanotti says:

    Ryan,

    Im using CentOS 5.4, and im having some isue with openssl command:

    [root@centos5 ~]# openssl s_client -connect dc.vmwarelab.int:636
    CONNECTED(00000003)
    13455:error:140790E5:SSL routines:SSL23_WRITE:ssl handshake failure:s23_lib.c:188:

    Any help?

    Thank you,
    Marcello

    • Ryan Lane says:

      Does your domain controller have an SSL certificate installed? If so, does it have the full CA chain imported and trusted? AD only turns on LDAPS if so. The AD logs should tell you if LDAPS is enabled or not when you try to connect to the port. Unfortunately, this is kind of a tricky thing to troubleshoot in AD.

      • marcello mezzanotti says:

        Ryan,

        Im not sure about a ssl certificate, but i dont think so, anyway, in my dc (vmware lab) i installed MS CA (for others tests), and now its working.

        Anyway, if case where i dont have a MS CA, can you help me (link) on how to do this stuff? (generate, install ssl certificate, ca chain, etc)

        thank you,
        marcello

        • Ryan Lane says:

          If you installed an MS CA, and that is ok with your organization, that is all you really need to do. I’m unlikely to write up documentation on how to install an SSL cert in AD, with the CA chain, because I don’t have Windows Server 2003/2008. I’d be willing to write more documentation if someone was to purchase it and donate it to me.

  17. Wayne says:

    Great article, however, it appears that the /etc/pam.d/system-auth configuration is borked. When I configured my systems according to this last part, I am now able to su – from any account without needing to enter the root password. Has anyone else experienced the same thing?

    Sincerely,

    Wayne

Leave a Comment