Wednesday, August 26, 2009

Groups membership

It should be noted that winbind does not populate Unix groups as per their "member" attribute in AD (or uniqueMember as per RFC2307) but rather uses real Windows group membership.

Also, interesting article about authenticating RHEL-5 with AD can be found at Microsoft Technet site. They describe exactly what I did in my blog (but my blog is better as it covers automounter and ssh, too :-)

Thursday, August 20, 2009

SSH single sign on

Having the machine configured the way I outlined earlier, it is just a piece of cake to configure ssh to accept your Kerberos TGT's and allow you to login to a remote machine without having to type any passwords.

In fact, you do not need to do anything at all (at least on RHEL 5) as sshd is configured by default here to honor GSSAPI authentication - so on RedHat, it should work just out-of-the box.

The only problem arises, if you need to forward your TGT to the remote machine (and you might want it if your home is mounted via NFSv4 and Kerberos security - without a valid TGT the remote machine refuse to allow you access your home directory). If you want your TGT forwarded, 2 things are necessary:
  • You must have forwardable tickets in your cache (see my previous posts). Also kinit -f will do the job.
  • SSH must be configured to delegate GSSAPI credentials, just make sure
    GSSAPIDelegateCredentials yes
    is present in your ssh_config file

Monday, August 10, 2009

Automounter integration

Only automounter version 5 and newer can talk to Active Directory using native protocols - ldap with SASL/GSSAPI authentication mechanism. In this article we show how to set it up.

Prerequisite

  • autofs 5.0 or newer installed
  • cyrus-sasl-gssapi library installed
  • machine joined Active Directory using Samba (see my earlier posts)
  • Automounter configuration

    Example:
    [root@dorado_v3 openldap]# cat /etc/sysconfig/autofs
    LDAP_URI="ldap://dcpra.prague.ad.s3group.com" # AD server name
    SEARCH_BASE="cn=praguetest,cn=prague,dc=ad,dc=s3group,dc=cz"
    Note:
    Newer autofs versions (as of Centos 5.4 and newer) can discover Active Directory controller automagically using DNS SRV records - to apply for this feature enter the LDAP_URI in slightly different format:
    LDAP_URI="ldap:///dc=prague,dc=ad,dc=s3group,dc=com"
    for more information, see the autofs manual (autofs, auto.master)

    Name services switch

    Make sure the automount record in /etc/nsswitch.conf points to ldap

    Automounter authentication configuration

    Is stored in the /etc/autofs_ldap_auth.conf file. Example:

     <autofs_ldap_sasl_conf
    usetls="no"
    tlsrequired="no"
    authrequired="yes"
    authtype="GSSAPI"
    clientprinc="dorado_v3$@PRAGUE.AD.S3GROUP.COM"
    />

    This way we are telling automounter to use maps stored in the LDAP repository that can be accessed with SASL/GSSAPI authentication using the machine credentials stored in the system-wide keytab file.

    Automounter data

    When connecting to the ldap server (Active Directory) directly, autofs uses a different syntax of the maps when comparing to standard NIS maps / flat files. Here is one example of the auto.master map and auto.home map which contains just one record - a home directory for user victim (easy to understand, could be used as a template for other maps creation):

    [root@dorado_v1 etc]# ldapsearch -H ldap://WIN-UG29HR9IEGY -Y DIGEST-MD5 -U "ldapproxy" -w 1234proxy$ -b "cn=praguetest,cn=prague,dc=ad,dc=s3group,dc=cz" objectClass=* cn objectClass nisMapName nisMapEntry
    SASL/DIGEST-MD5 authentication started
    SASL username: ldapproxy
    SASL SSF: 128
    SASL installing layers
    # extended LDIF
    #
    # LDAPv3
    # base with scope subtree
    # filter: objectClass=*
    # requesting: cn objectClass nisMapName nisMapEntry
    #

    # praguetest, prague, ad.s3group.cz
    dn: CN=praguetest,CN=prague,DC=ad,DC=s3group,DC=cz
    objectClass: top
    objectClass: container
    cn: praguetest

    # auto.proj, praguetest, prague, ad.s3group.cz
    dn: CN=auto.proj,CN=praguetest,CN=prague,DC=ad,DC=s3group,DC=cz
    objectClass: top
    objectClass: container
    cn: auto.proj

    # services, praguetest, prague, ad.s3group.cz
    dn: CN=services,CN=praguetest,CN=prague,DC=ad,DC=s3group,DC=cz
    objectClass: top
    objectClass: container
    cn: services

    # 536/tcp, services, praguetest, prague, ad.s3group.cz
    dn: CN=536/tcp,CN=services,CN=praguetest,CN=prague,DC=ad,DC=s3group,DC=cz
    objectClass: top
    objectClass: ipService
    cn: 536/tcp

    # auto.master, praguetest, prague, ad.s3group.cz
    dn: CN=auto.master,CN=praguetest,CN=prague,DC=ad,DC=s3group,DC=cz
    objectClass: top
    objectClass: nisMap
    cn: auto.master
    nisMapName: auto.master

    # /proj, auto.master, praguetest, prague, ad.s3group.cz
    dn: CN=/proj,CN=auto.master,CN=praguetest,CN=prague,DC=ad,DC=s3group,DC=cz
    objectClass: top
    objectClass: nisObject
    cn: /proj
    nisMapName: auto.master
    nisMapEntry: ldap:cn=auto.proj,cn=praguetest,cn=prague,dc=ad,dc=s3group,dc=cz

    # /home, auto.master, praguetest, prague, ad.s3group.cz
    dn: CN=/home,CN=auto.master,CN=praguetest,CN=prague,DC=ad,DC=s3group,DC=cz
    objectClass: top
    objectClass: nisObject
    cn: /home
    nisMapName: auto.master
    nisMapEntry: ldap:cn=auto.home,cn=praguetest,cn=prague,dc=ad,dc=s3group,dc=cz

    # auto.home, praguetest, prague, ad.s3group.cz
    dn: CN=auto.home,CN=praguetest,CN=prague,DC=ad,DC=s3group,DC=cz
    objectClass: top
    objectClass: nisMap
    cn: auto.home
    nisMapName: auto.home

    # victim, auto.home, praguetest, prague, ad.s3group.cz
    dn: CN=victim,CN=auto.home,CN=praguetest,CN=prague,DC=ad,DC=s3group,DC=cz
    objectClass: top
    objectClass: nisObject
    cn: victim
    nisMapName: auto.home
    nisMapEntry: melnik:/vol/vol0/users/&

    # search result
    search: 3
    result: 0 Success

    # numResponses: 13
    # numEntries: 12

    Note: To force mount via NFSv4 & Kerberos security, use nisMapEntry in format like this -fstype=nfs4 -sec=krb5p melnik:/vol/vol0/users/&

    Also note that unlike to users and groups, there is no Windows GUI frontend to edit other RFC2307 attributes (for use by the Linux Automounter). To populate/edit the Ldap attributes, please use either Adsiedit (windows tool) or some command-line tool from the OpenLdap library.

    Trouble shooting autofs errors

    In certain non-standard DNS configurations, autofs might refuse to connect to the AD Controller with the error Server not found in kerberos database (can be seen in /var/log/messages with autofs debugging turned on). This can be resolved by putting the FQDN of the AD KDC directly into /etc/hosts:

    [root@dorado_v3 openldap]# cat /etc/hosts
    # Do not remove the following line, or various programs
    # that require network functionality will fail.
    127.0.0.1 localhost.localdomain localhost
    ::1 localhost.localdomain localhost6 localhost
    192.168.60.202 dcpra.prague.ad.s3group.com

    Kerberized NFSv4 support

    Introduction

    Assuming we have successfully managed to integrate our Linux Box with Active Directory (see my previous post), we can try other features - like Kerberized NFS.

    1. Client/Server common tasks

    To support NFSv4 with Kerberos security, we also need to generate service principal for NFS:

    [root@dorado_v1 root]# net -U administrator ads keytab add nfs
    Also make sure that
    # Set to turn on Secure NFS mounts.
    SECURE_NFS="yes"
    .. in your /etc/sysconfig/nfs configuration file (to make sure the GSS subsystem is properly started)

    2. Server tasks

    1. Configure NFS share like this (note the second line limiting allowed security types):
      /mnt      192.168.0.0/16(rw,fsid=0,crossmnt)
      /mnt/share1 192.168.0.0/16(sec=none:krb5:krb5i:krb5p,rw,crossmnt)
    2. Make sure rpc.svcgssd daemon is successfully started and running
    If you intend to use NetApp NAS as the NFSv4 server, all you need is to follow the wizard to join NetApp to Active Directory and configure some CIFS shares. Once this is done, finish the setup for Kerberized NFS:
  • Setup NFS for Kerberos on the NetApp following this article
  • Setup Kerberos ready NFS share like this:
    /vol/vol0/home  -sec=sys:krb5:krb5i:krb5p,rw
    Note that if you export /vol/vol0 as well, you must allow Kerberos security for it, too
  • Make sure NFSv4 is enabled on the filer:
    nfs.v4.enable                on
  • And that's it...

    3. Client tasks

    It is important, that the rpc.gssd service is running on the NFS client. As of nfs-utils <= 1.1 rpc.gssd looks for the nfs/ principal on startup to access AD and to obtain the TGT to use when dealing with the NFS server.

    Now this principal is treated as a user principal (we use it to obtain TGT) so UPN attribute must be set for the machine account in AD in order to make rpc.gssd happy:

  • Start ADSIEDIT
  • Navigate to the Active Directory computer object that was created when NET ADS JOIN was run
  • Right click the computer object
  • Select Properties
  • Select userPrincipalName Attribute
  • Edit the attribute to set the nfs/hostFDQN@KERBEROS.REALM value.For example (in our case) nfs/dorado_v1@PRAGUE.AD.S3GROUP.COM
  • Verify the ticket availability:

    [root@dorado_v1 /]# klist -k | grep nfs
    4 nfs/dorado_v1@PRAGUE.AD.S3GROUP.COM
    4 nfs/dorado_v1@PRAGUE.AD.S3GROUP.COM
    4 nfs/dorado_v1@PRAGUE.AD.S3GROUP.COM
    4 nfs/dorado_v1.prague.s3group.com@PRAGUE.AD.S3GROUP.COM
    4 nfs/dorado_v1.prague.s3group.com@PRAGUE.AD.S3GROUP.COM
    4 nfs/dorado_v1.prague.s3group.com@PRAGUE.AD.S3GROUP.COM

    Note:For Windows server 2008 omit the Kerberos realm in the UPN attribute (use just nfs/hostFDQN), otherwise it will not work

    Setup the OS

    [root@dorado_v1 /]# service rpcgssd start

    Verify the service rpcgssd got the ticket right:

    [root@dorado_v1 /]# tail -300 /var/log/messages
    Feb 13 11:39:12 dorado_v1 rpc.gssd[4723]: Using keytab file '/etc/krb5.keytab'
    Feb 13 11:39:12 dorado_v1 rpc.gssd[4723]: Processing keytab entry for principal 'nfs/dorado_v1@PRAGUE.AD.S3GROUP.COM'
    Feb 13 11:39:12 dorado_v1 rpc.gssd[4723]: We will use this entry (nfs/dorado_v1@PRAGUE.AD.S3GROUP.COM)
    ...
    Feb 13 11:39:12 dorado_v1 rpc.gssd[4723]: Using (machine) credentials cache: 'MEMORY:/tmp/krb5cc_machine_PRAGUE.AD.S3GROUP.COM'

    Note: rpc.gssd as of nfs-utils >= 1.1 can be started with the -n parameter which makes rpc.gssd to use Kerberos cache instead of the krb5.keytab file. The advantage of this parameter is, that we can create the necessary TGT for the NFS client using the machine account credentials already present in the keytab file:

    dorado_v1# kinit -k dorado_v1$
    Where dorado_v1$ is our machine credential. This way is a bit cleaner as no UPN needs to be set in AD (and besides, setting UPN in AD manually might break Samba functionality).

    User access to the mounted share

    Any user wanting to access an already mounted share must have a valid Ticket Granting Ticket with the des-cbc-crc encryption, otherwise the access will fail:

    [ondrejv@dorado_v1 ~]$ klist -c -e
    klist: No credentials cache found (ticket cache FILE:/tmp/krb5cc_2527)


    Kerberos 4 ticket cache: /tmp/tkt2527
    klist: You have no tickets cached
    [ondrejv@dorado_v1 ~]$ ls -l /mnt/test
    ls: /mnt/test: Access denied
    [ondrejv@dorado_v1 ~]$ kinit
    Password for ondrejv@PRAGUE.AD.S3GROUP.COM:
    [ondrejv@dorado_v1 ~]$ klist -c -e
    Ticket cache: FILE:/tmp/krb5cc_2527
    Default principal: ondrejv@PRAGUE.AD.S3GROUP.COM

    Valid starting Expires Service principal
    02/16/09 14:28:25 02/17/09 00:28:33 krbtgt/PRAGUE.AD.S3GROUP.COM@PRAGUE.AD.S3GROUP.COM
    renew until 02/17/09 14:28:25, Etype (skey, tkt): DES cbc mode with CRC-32, ArcFour with HMAC/md5


    Kerberos 4 ticket cache: /tmp/tkt2527
    klist: You have no tickets cached
    [ondrejv@dorado_v1 ~]$ ls -l /mnt/test
    celkem 4
    -rw-r--r-- 1 ondrejv silicon 0 úno 13 10:54 test.txt
    [ondrejv@dorado_v1 ~]$

    Complete Linux-AD Authentication Details

    Introduction

    There are several articles posted here that discuss, in general terms, how to authenticate Linux against Active Directory.

    With the introduction of Windows Server 2003 R2 and Windows Server 2008 Microsoft did a big step towards the Linux community - why? Active Directory LDAP schema is now much more RFC2307 friendly and so can directly contain Unix attributes (UID, GIDs,...) of users and groups. To apply for this benefit, system administrator is only required to install so-called Identity Management for Unix extension. Unix attributes of users and groups can be then directly edited in the Active Directory Users and Computers snap-in.

    In this article we will use Samba to help us with Linux-AD authentication tasks.

    Suggestions to use Samba in Linux-AD integration scenarios appeared in the comments for the following articles:

    Linux, Active Directory, and Windows Server 2003 R2 Revisited
    Kerberos-Based SSO with Apache

    Samba could be used to help automate the process of creating the appropriate service principals in Active Directory (many similar articles use ktpass.exe and separate user accounts for each service principal - i.e., HOST/ or host/, HTTP/, etc. - this is quite tedious work which can be simplified greatly using Samba). Here’s what I found and the process that I used to successfully integrate the new Linux server into AD with the Samba tools:

    1. Time synchronization

    In this article we are going to use Windows-native authentication methods like Kerberos. Kerberos is well known to be picky about client-server synchronization so make sure you have your time in sync between Windows server and Linux client!

    2. Samba configuration

    1. Next, Samba must be properly configured. I used the following settings in /etc/samba/smb.conf:
      workgroup = PRAGUE
      security = ads
      realm = PRAGUE.AD.S3GROUP.COM
      use kerberos keytab = true
      idmap domains = PRAGUE
      idmap config PRAGUE:schema_mode = rfc2307
      idmap config PRAGUE:backend = ad
      idmap config PRAGUE:readonly = yes
      winbind nss info = rfc2307
      winbind use default domain = yes

    2. If the DNS domain of your Linux server will be different than the DNS domain of the AD domain (for example, perhaps your Linux server will be web1.linux.corp.com whereas Active Directory uses ad.corp.com), then create a computer account in Active Directory. If the Linux server’s DNS domain will be the same as the DNS domain for AD, then we can have Samba create it for us. (I ran into problems here since the Linux server does use a different DNS domain than Active Directory, and pre-creating the computer account was the only way to make it work.)
    3. Run net ads join to join the Linux server to Active Directory. As part of this process, it will add various SPNs to the computer account in Active Directory automatically and create the appropriate entries in the local Kerberos keytab (/etc/krb5.keytab, by default)

    3. Configure Name Services Switch

    Contrary to many other articles we will not use the nss_ldap client but will use winbindd (part of the Samba package) instead. Why? ldap_client is a library, not a daemon so it runs in the user context. That is why we can not use the Kerberos machine credentials (which Samba kindly provided) to contact AD - we would have to define some proxy user instead. Winbind is a daemon running as root so it has access to the machine credentials -> the whole configuration is a lot easier (see the 1 extra configuration line above).

    Note that winbind can only take care of these two databases - everything else must be handled by nss_ldap.so NSS library (ok automounter is an exception here, we will cover autofs later...) - but these two are the most important anyway...:
    [root@dorado_v1 ondrejv]# cat /etc/nsswitch.conf
    passwd: files winbind
    shadow: files winbind
    group: files winbind

    #hosts: db files nisplus nis dns
    hosts: files dns
    automount: files ldap
    When winbindd is correctly configured, you should be able to do a wbinfo -u and wbinfo -i get back a list of user properties for that username. You might also use the wbinfo tool to debug winbind errors. Unfortunately winbind is quite hard to debug as it employs caching (which survive daemon restarts and even machine reboots - and there is no simple way to force cache flush - are you listening, Samba developers? :-) ). To flush winbind cache you might try deleting files in /var/cache/samba/winbind* - but in many cases you just need to wait for the cache to refresh.

    Note:

    Usual debugging commands like gentent passwd and getent group do not work by default with winbind as enumeration those needs to be enabled explicitely

    4. Configure PAM for Kerberos authentication

    Use the system-config-authentication tool (available in RHEL and CentOs) to and configure PAM for Kerberos - the result should look like this:

    [root@dorado_v1 ondrejv]# cat /etc/pam.d/system-auth
    #%PAM-1.0
    # This file is auto-generated.
    # User changes will be destroyed the next time authconfig is run.
    auth required pam_env.so
    auth sufficient pam_unix.so nullok try_first_pass
    auth requisite pam_succeed_if.so uid >= 500 quiet
    auth sufficient pam_krb5.so use_first_pass
    auth required pam_deny.so

    account required pam_unix.so broken_shadow
    account sufficient pam_succeed_if.so uid < 500 quiet
    account [default=bad success=ok user_unknown=ignore] pam_krb5.so
    account required pam_permit.so

    password requisite pam_cracklib.so try_first_pass retry=3
    password sufficient pam_unix.so md5 shadow nis nullok try_first_pass use_authtok
    password sufficient pam_krb5.so use_authtok
    password required pam_deny.so

    session optional pam_keyinit.so revoke
    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
    session optional pam_krb5.so

    Use the same tool to configure the Kerberos library (/etc/krb5.conf) - Samba can not do this for us, unfortunately. Here is my minimal configuration:
    [libdefaults]
    default_realm = PRAGUE.AD.S3GROUP.COM
    default_tgs_enctypes = arcfour-hmac-md5 des-cbc-md5 des-cbc-crc
    default_tkt_enctypes = arcfour-hmac-md5 des-cbc-md5 des-cbc-crc
    permitted_enctypes = arcfour-hmac-md5 des-cbc-md5 des-cbc-crc arcfour-hmac-exp
    dns_lookup_realm = true
    dns_lookup_kdc = true
    passwd_check_s_address = false
    use_tcp_only = true
    ccache_type = 3
    forwardable = true
    [domain_realm]
    .prague.ad.s3group.com = PRAGUE.AD.S3GROUP.COM
    .prague.s3group.com = PRAGUE.AD.S3GROUP.COM
    prague.ad.s3group.com = PRAGUE.AD.S3GROUP.COM
    prague.s3group.com = PRAGUE.AD.S3GROUP.COM
    [realms]

    It is important, that this configuration is consistent across your LAN computers otherwise you might experience some strange Kerberos errors. As you can see, there is no configuration in the [realms] section - it is not needed as the Kerberos library will use DNS SRV records to locate KDC (AD domain controllers). Also note the forwardable = true flag - it instructs pam_krb5 module to create forwardable TGT tickets (important for SSH single sign on)

    Note:


    This setup works, but unfortunately still not everything works just perfectly - for example if your password expired, you are asked to change it - and if you attempt to change it to something which does not fulfill enforced AD policies (like attempt to re-use old password or not complex enough password), you are kicked out without a word of explanation....

    I used this process to integrate a new CentOS 5.3 server into Active Directory (Windows 2008 server based) without any problems whatsoever.