Pages

Friday, June 24, 2011

On FreeBSD and Active Directory Integration: Kerberos and LDAP

Before proceeding with my solution, I wish to thank the authors of the blogs I consulted first: Scott Lowe of blog.scottlowe.org who came up with the solution I used for Windows 2003 Server and Red Hat Linux; and to Jared Barnek of rhyous.com.

The big picture

Since the company has a great number of Windows, Mac and Linux users, user and computer accounts are controlled by Active Directory on Windows 2003 Server R2, not Kerberos on a *nix host.

The problem
  1. I wish to tie FreeBSD 8.2 into Active Directory.
  2. The FreeBSD host must be as simple as we can make it: the Samba suite will not be installed.
  3. Kerberos is to be used for authentication to leverage single-sign-on and eventually enable NFSv4 and Kerberos-enabled HTTP.
  4. Only SSHD is tied into Kerberos for now; console access is granted through local accounts only.
The solution
  1. LDAP is used for authorization (remember Kerberos can only authenticate!)
  2. Simulate kadmin with commands on Windows Server 2003 R2 and manually transferring the keytabs.
Details

Fortunately, the detailed answers for LDAP were already supplied by Mr Lowe (above) and for Kerberos by Microsoft's own document located at http://technet.microsoft.com/en-us/library/bb742433.aspx.

Note: I used the 64-bit FreeBSD 8.2. I had segfaults with the 32-bit OpenLDAP.
Note 2: Mind the word wrap! In the configuration examples, in Courier font, something that looks like a new line may not in fact be a new line!

Ingredients

On Microsoft Windows Server 2003 R2:

    1. An Active Directory (AD)
    2. Subsystem for UNIX-based Applications (SUA) installed
    3. Windows Server 2003 Support Tools installed
    4. Service Pack 1 applied to the AD server (for a bugfix to ktpass.exe)
    5. An SSL certificate signed by an known Certificate Authority applied to the AD server. (See * and **)
    6. At least one account (to test) has been created on Active Directory with its UNIX fields set (especially the shell!)
    7. WinSCP on Active Directory, used to transfer a Kerberos keytab securely.

  1. On a FreeBSD 8.2 host:
    1. A minimal installation of FreeBSD 8.2 will suffice
    2. At least one local non-root account created for transfers and for troubleshooting. Ensure this account is part of the wheel group since you will need to get to root somehow.

      NB: There is no need to install the advanced Heimdall or MIT Kerberos on FreeBSD; the default Heimdall will do.
* You want SSL. Although passwords are not sent over the wire, you don't want a rogue LDAP server sending spoofed group membership info.

** If you need to use your own CA, be sure to export and merge its public cert in FreeBSD.'s /etc/ssl/cert.pem. That, however, is out of the scope of this little post.

Part One: OpenLDAP Authorization
  1. In AD, create a non-Domain User account used for "anonymous" ldap lookups with very restricted rights. This account should not be used to log in to any workstation since its password will be an open secret to whomever looks at the ldap configurations on the FreeBSD hosts. For the sample configurations below, I use an account "ldapaccount." Remember to turn on the UNIX fields for ldapaccount.
  2. Turn off nscd if it is running on the FreeBSD host:

    /etc/rc.d/nscd stop

  3. Install root certificates

    cd /usr/ports/security/ca_root_nss
    make install clean
    (When prompted to create a link, say yes)

  4. Install OpenLDAP with Cyrus SASL, pam_ldap, pam_mkhomedir and nss_ldap:

    cd /usr/ports/net/openldap24-client
    make install clean
    (select Cyrus when prompted)

    cd ../nss_ldap
    make install clean
    (defaults are fine)

    cd /usr/ports/security/pam_ldap
    make install clean

    cd ../pam_mkhomedir
    make install clean

  5. Create the /usr/local/etc/openldap/ldap.conf (used for applications)

    base dc=yourdomain,dc=com
    uri ldaps://activedirectory1.yourdomain.com ldaps://activedirectory2.yourdomain.com
    ssl yes
    tls_cacert /etc/ssl/cert.pem

  6. Create /usr/local/etc/ldap.conf (used for nss)

    base dc=yourdomain,dc=com
    uri ldaps://activedirectory1.yourdomain.com ldaps://activedirectory2.yourdomain.com
    scope sub
    ssl yes
    tls_cacert /etc/ssl/cert.pem
    binddn ldapaccount@yourdomain.com
    bindpw ldapaccount_passwor


    pam_login_attribute sAMAccountName
    pam_filter          objectClass=User
    pam_password        ad

    nss_base_passwd dc=yourdomain,dc=com?sub&(objectClass=user)(uidNumber=*)
    nss_base_shadow dc=yourdomain,dc=com?sub&(objectClass=user)(uidNumber=*)
    nss_base_group dc=yourdomain,dc=com?sub&(objectClass=group)(gidNumber=*)

    nss_map_objectclass posixAccount    User
    nss_map_objectclass shadowAccount   User

    nss_map_attribute   uid         sAMAccountName
    nss_map_attribute   cn              sAMAccountName
    nss_map_attribute   uniqueMember    member
    nss_map_attribute   userPassword    msSFU30Password
    nss_map_attribute   homeDirectory   unixHomeDirectory
    nss_map_attribute   gecos           name
    nss_map_objectclass posixGroup      Group

    # Active Directory Silliness
      referrals no

    Note the nss_map_attributes. They may change if your version of Windows Server is different from mine. If you run into trouble, execute an ldapsearch on the AD server on your username and make note of the field name that holds usernames, groups, home directories, etc.
  7. Link /usr/local/etc/nss_ldap.conf to /usr/local/ldap.conf

    rm -f /usr/local/etc/nss_ldap.conf
    ln -s /usr/local/etc/ldap.conf /usr/local/etc/nss_ldap.conf
    chmod 644 /usr/local/etc/ldap.conf

  8. If the users on AD have their shells set to binaries located in the /bin directory, for example Fedora or Red Hat users, you will want to link installed port shells on FreeBSD such as bash to the /bin directory to avoid heartache.

    ln -s /usr/local/bin/bash /bin/bash  (etc)

  9. Turn on nscd to keep your AD from holding connections open
    /etc/rc.d/nscd start

  10. If nscd does not start on boot, it is a very good idea to make it start on boot:

    echo 'nscd_enable="YES"' >> /etc/rc.conf
Part Two: Kerberos Authentication setup on FreeBSD
  1. Ensure that the system time on FreeBSD is within 5 minutes of AD.
  2. Configure Kerberos in /etc/krb5.conf. The configuration below in monospace was taken from a CentOS5 krb5.conf and edited. Check the man pages for explanations. Replace yourdomain with the correct active directory domain. In this case, activedirectory1 is the master AD server. Note the capitalization: it's important!

    [logging]

     # The logging is not really required as this host is not
     # using kadmin. Kept in as it does no harm.
     # Debugging, if required,
    will be set in the
     # /etc/pam.d/ files.

     default = FILE:/var/log/krb5libs.log
     kdc = FILE:/var/log/krb5kdc.log
     admin_server = FILE:/var/log/kadmind.log

    [libdefaults]
     default_realm = YOURDOMAIN.COM
     ticket_lifetime = 24h

     forwardable = yes

    [realms]
     YOURDOMAIN.COM = {
      kdc = activedirectory1.yourdomain.com:88
      kdc = activedirectory2.yourdomain.com:88
      admin_server = activedirectory1.yourdomain.com:749
     }

    [domain_realm]
     yourdomain.com = YOURDOMAIN.COM
     .yourdomain.com = YOURDOMAIN.COM

    [appdefaults]
     pam = {
       debug = false
       ticket_lifetime = 36000
       renew_lifetime = 36000
       forwardable = true
       krb4_convert = false
     } 
Part Three: Create and transfer the Kerberos Principal

The naming convention for Kerberos principals (service/host.domain.com) is incompatible with Microsoft naming. Windows requires a Kerberos principal to map to a regular Microsoft account.
  1. Option (strongly suggested): create an Organizational Unit (OU) to hold UNIX accounts
  2. Create a User Account on Active Directory (not a Computer Account).
    1. Example: for the host "pentheus.mydomain.com," create an account "hostPentheus"
    2. Fill only the first name field with "hostPentheus." Don't fill in the other name fields.
    3. Fill in a complicated password. This password will never be used by humans so go nuts.
  3. Map a Kerberos principal to the user account and generate the keytab
    1. Open a command line interface on AD
    2. Change to a directory used for holding keytabs or to the desktop
    3. Execute the following:
      ktpass princ host/hostname.yourdomain.com@YOURDOMAIN.COM mapuser userAccount -pass random_complicated_password out new_principal.keytab
  4. Copy the new principal over to FreeBSD from the directory or desktop
      1. Use WinSCP to copy the keytab over the wire to the local non-root account or use the sneaker-net: a USB Key or floppy. FTP is not your friend here and SMB is not in scope.
      2. On FreeBSD: merge the new principal to the (non-existent) /etc/krb5.keytab

        ktutil copy /home/
        local_account/new_principal.keytab /etc/krb5.keytab
        ktutil -k /etc/krb5.keytab list
        chmod 600 /etc/krb5.keytab

      3. For security, delete the keytab from the local account's home directory.
    Part Four:  Configure SSHD to use Kerberos with LDAP as a fallback
    1. Edit /etc/pam.d/sshd
    2. Use the following as a guide. Use man pam_authentication for details :)
      # auth
      auth    sufficient pam_krb5.so                no_warn
      auth    sufficient /usr/local/lib/pam_ldap.so no_warn try_first_pass
      auth    required   pam_unix.so                no_warn try_first_pass

      # account
      account required   pam_nologin.so
      account required   pam_krb5.so
      account required   /usr/local/lib/pam_ldap.so no_warn ignore_authinfo_unavail ignore_unknown_user

      account required   pam_login_access.so

      account required   pam_unix.so

      # session
      session required   pam_permit.so
      session required   /usr/local/lib/pam_mkhomedir.so umask=0022 skel=/usr/share/skel

      # password
      password sufficient pam_krb5.so no_warn
      password required   pam_unix.so no_warn try_first_pass
    Part Five: Set nsswitch and lock down SSH
    1. Edit /etc/nsswitch.conf. The following lines should be set:

      group: files ldap
      passwd: files ldap

    2. Go into /etc/ssh/sshd_config and with either AllowUsers or AllowGroups restrict shell access as required. Restart sshd with /etc/rc.d/sshd restart as needed.

    Part Six: Enable GSSAPI on ssh and sshd
    1. Ensure the following is uncommented and set in /etc/ssh/ssh_config on the FreeBSD host and on the hosts from which you will ssh:

      GSSAPIAuthentication yes

      GSSAPIDelegateCredentials yes

    2. Ensure that the following is uncommented and set in /etc/ssh/sshd_config on the FreeBSD host. Please note that PAM is enabled in sshd by default in FreeBSD 8.2.

      KerberosAuthentication yes
      GSSAPIAuthentication yes
      GSSAPICleanupCredentials yes
    3. Restart the sshd service with /etc/rc.d/sshd restart 


    Part Seven: Test


    On another Kerberized host, ensure you have a TGT by using the klist command. If you don't have a TGT, use kinit. Now go ahead and try ssh'ing in. If SSH demands a password (or worse, a password is demanded by LDAP) there is a problem. Append debug to the pam_krb5.so entries in /etc/pam.d/sshd, try logging in again and look at the /var/log/debug file for hints.

    If you find any errors or have questions, please comment!

      No comments: