Contents


Integration of OS authentication with Microsoft Active Directory on IBM PureApplication System

Comments

When implementing IBM PureApplication System, IBM recommends integration with an external LDAP subsystem. This enables offloading the authentication as well as group membership to an existing corporate directory within the IT landscape. It applies to the users and groups for the administrative interfaces of IBM PureApplication System, such as the system console, workload console, Pure CLI, and REST interface.

With the LDAP integration described in place, it is important to point out that the operating system that gets deployed with each virtual machine on the system does not automatically integrate with that LDAP. Many clients have a requirement for the OS to integrate with an external LDAP, as it greatly simplifies managing the security for large sets of VMs on PureApplication System.

This article describes how to integrate the OS security on IBM PureApplication System with Microsoft Active Directory, an LDAP implementation used by many clients. Described here in detail is how this integration can be automated using script packages for VMs that are part of a virtual system pattern. The setup required in Active Directory for this integration to work is also highlighted.

The solution described here is only applicable to the Intel® IBM PureApplication System models (8283/W1500 and 8283/W2500) running Red Hat Enterprise Linux®.

The problem

When deploying a virtual system pattern, the administrator must specify the password for one or more OS accounts at deployment time that will be defined within the Red Hat Enterprise Linux (RHEL) OS. Accounts always include root and virtuser, but depending on the virtual system pattern, there can be others as well (such as db2inst1 for IBM DB2®).

The deployment of a virtual system pattern on PureApplication System drives the deployment of one or more virtual machines. As a result, managing a large number of VMs becomes challenging. Administrators need to be handed the passwords of those OS accounts. Managing the lifecycle for those accounts can be cumbersome; for example, how do you enforce a password policy that requires passwords to be changed every three months? Other challenges include new people joining the team of administrators and other people leaving.

With these difficulties in mind, integrating the RHEL OS with an existing Microsoft Active Directory service would bring a lot of benefits. Lifecycle management of passwords would no longer be within the scope of the VM on PureApplication System itself. You would need a mechanism for a user that exists in Active Directory to logon to a deployed VM. The RHEL OS would need to be configured such that it would reach out to Active Directory to validate a user’s credentials and group memberships when the user attempts to logon over SSH. Group membership could be used to restrict access to a VM to a subset of users present in Active Directory.

Implementation

This sample solution uses Samba to perform the authentication against Active Directory. Pluggable authentication modules (PAM) and winbind are configured and actually join the RHEL host into the Active Directory domain. Joining the domain requires a container in Active Directory as well as a bind user with sufficient permissions to create computer objects in the domain.

Once that is done, the OS can perform authentication against the Active Directory using challenge/response. Group memberships for the user are also obtained from Active Directory, and a consistent mapping onto uids and gids can be configured. Because the RHEL host has joined the domain, it can obtain Kerberos tickets as well. This enables Single Sign-On (SSO) within a domain, which is a powerful feature. Once logged onto one VM, a user can SSH into another VM within the same domain without having to re-enter his password.

Because VMs on Pure Application System can be deleted, you also need to remove the corresponding computer object in the Active Directory. Consequently, this requires the bind user to have sufficient permissions to delete computer objects in Active Directory (Figure 1).

Figure 1. Overview of the solution
Overview of the solution
Overview of the solution

The intention is to hand out permissions based on group membership of the user in Active Directory. For each workload on the system, you can use group membership to determine whether a user is permitted to logon over SSH, or whether the user can perform a switch user (su) to a technical user or to root:

  • GRP_IPAS_<workload>_login
    Members of this group are permitted to login to the OS using SSH.
  • GRP_IPAS_<workload>_middleware
    Members of this group are permitted to switch user (su) to one or more different technical users on the OS; for example, virtuser or db2inst1.
  • GRP_IPAS_<workload>_root
    Members of this group are permitted to switch user (su) to root.

Active Directory setup

The sections below describe what setup is required in the Active Directory domain. This needs to be in place before attempting to configure OS security in RHEL and joining the domain.

  • Containers

    To simplify the Active Directory structure for this example, place all related components in a single container at the root of the Active Directory domain:

    OU=IPAS,DC=dw,DC=ibm,DC=com

    Within this container, create three additional containers for service accounts, groups, and the actual hosts joining the domain:

    OU=Service Accounts,OU=Users,OU=IPAS, DC=dw,DC=ibm,DC=com
    OU=Management,OU=Groups,OU=IPAS, DC=dw,DC=ibm,DC=com
    OU=Servers,OU=IPAS, DC=dw,DC=ibm,DC=com

    Figure 2 illustrates the structure you need to have in place.

    Figure 2. Active Directory tree setup
    Active Directory tree setup
  • Service account

    You need a service account in Active Directory that can create new computer objects when joining the domain. The account would need permissions to create new computer objects in the container OU=Servers,OU=IPAS,DC=dw,DC=ibm,DC=com. Upon leaving the domain, the computer object would have to be removed from the container. Therefore, the account would also need to have permissions to delete computer objects from the container:

    CN=IPASAD,OU=Service Accounts,OU=Users,OU=IPAS,DC=dw, DC=ibm, DC=com

  • Groups and users

    Once joined into the domain, you will use group membership to determine what permissions a user has on that OS. Therefore, you need to create a number of groups that you can use for that purpose; of course, more groups can be added over time:

    • GRP_IPAS_myWorkload_login
      Members of this group are permitted to login to the OS using SSH.
    • GRP_IPAS_myWorkload_middleware
      Members of this group are permitted to switch user (su) to one or more different technical users on the OS; for example, virtuser or db2inst1.
    • GRP_IPAS_myWorkload_root
      Members of this group are permitted to switch user (su) to root.

    Naturally, a number of users would have to be defined as well. For testing purposes, you should have users in place with different group memberships.

  • Required RPMs

    The following RPM files are required in order for the integration with Active Directory to work. Be aware that the version can be important; we found inconsistent behaviour for group membership with an older version of the Samba/winbind binaries. The RPM versions listed here have been tested and should be considered as minimal version numbers.

    These RPMs need to be installed before configuring the RHEL OS. Depending on the virtual image used by your virtual system pattern, some of these RPMs might already be installed:

    • libsmbclient-3.6.9-151.el6.x86_64.rpm
    • libtalloc-2.0.7-2.el6.x86_64.rpm
    • libtdb-1.2.10-1.el6.x86_64.rpm
    • openldap-clients-2.4.23-20.el6.x86_64.rpm *
    • openldap-clients-2.4.23-26.el6_3.2.x86_64.rpm *
    • openldap-clients-2.4.23-32.el6_4.1.x86_64.rpm *
    • openldap-clients-2.4.23-34.el6_5.1.x86_64.rpm *
    • samba-3.6.9-151.el6.x86_64.rpm *
    • samba-3.6.9-151.el6_4.1.x86_64.rpm *
    • samba-3.6.9-169.el6_5.x86_64.rpm *
    • samba-client-3.6.9-151.el6.x86_64.rpm
    • samba-common-3.6.9-151.el6.x86_64.rpm
    • samba-winbind-3.6.9-151.el6.x86_64.rpm
    • samba-winbind-clients-3.6.9-151.el6.x86_64.rpm

    For packages in this list marked with *, the exact version to use depends on the virtual image.

  • Required data

    This is the data you need as variables to execute your scripts (defined below):

    $ADS_username
    $ADS_password
    $ADS_container_shortname
    $ADS_domain
    $ADS_workgroup
    $ADS_realm
    $ADS_login_group
    $ADS_middleware_group
    $ADS_root_group

    • Service account username and password: The username and password of the service account defined earlier in the Active Directory are required for the computer object to be created (and deleted).
    • Container name: The name of the container (OU) to store the computer object is required by the net ads join command. The OU string reads from top to bottom without relative distinguished names (RDNs), and is delimited by a “/.” In this example, your container OU=Servers,OU=IPAS, DC=dw,DC=ibm,DC=com should be given as “IPAS/Servers.”
    • Domain: The domain of the virtual machine is necessary, especially for the net ads join command. As the qualified hostname is given at deployment time by Pure Application System, you will use the hostname –domain command to get the domain name, so it is not required to expose it as a script package variable.
    • Workgroup: The name of the workgroup to join will be used by Samba. In the code samples below, this data is stored in the $ADS_workgroup variable.
    • Realm: The name of the realm is used by the Samba and Kerberos configurations. It also used to create the UPN (User Principal Name) while joining the Active Directory. In the code samples below, this data is stored in the $ADS_realm variable.
    • Group names: The names of the three groups are required to setup the correct permissions:
      • GRP_IPAS_myWorkload_login
      • GRP_IPAS_myWorkload_middleware
      • GRP_IPAS_myWorkload_root.

Configuring RHEL 6 OS

The sections below describe the steps required to configure security in RHEL 6 in order to integrate with Active Directory.

1. Identify configuration file paths

Here you will use here the default file paths for configuration files. The files to work on are:

  • /etc/samba/smb.conf
  • /etc/security/pam_winbind.conf
  • /etc/security/access.conf
  • /etc/krb5.conf
  • /etc/sudoers.

2. Start services

Once all the required RPMs are installed, the first step is to ensure that services messagebus, oddjobd, smb and winbind are all started.

3. Set initial samba configuration

Replace the content of file /etc/samba/smb.conf with the code shown in Listing 1. Keep a backup copy of the file before replacing its content.

Listing 1.
     [global]
     idmap config ${HomeDirDomain} : backend=rid
     idmap config ${HomeDirDomain} : range=100000-2000000000
     winbind enum users = false
     winbind enum groups = false
     # http://www.samba.org/samba/docs/man/manpages-3/smb.conf.5.html#KERBEROSMETHOD
     kerberos method = secrets and keytab
     client ldap sasl wrapping = sign
     username level = 3
     server string = Samba Server Version %v
     log file = /var/log/samba/log.%m
     max log size = 50
     passdb backend = tdbsam

Be aware that the ${HomeDirDomain} string must be replaced by the domain shortname, which can be retrieved with this command:

HomeDirDomain=$(echo $ADS_domain | awk -F'.' '{print $1}' | tr '[:lower:]' '[:upper:]')

Also, make sure that the /var/log/samba directory exists, otherwise nothing gets logged.

4. Modify configuration files

Run the authconfig utility to modify the configuration files (Listing 2).

Listing 2.
     authconfig \
     --disablecache \
     --enablewinbind \
     --enablewinbindauth \
     --smbsecurity=ads \	
     --smbworkgroup=$ADS_workgroup \
     --smbrealm=$ADS_realm \
     --enablewinbindusedefaultdomain \
     --winbindtemplateshell=/bin/bash \
     --winbindtemplatehomedir=/home/${HomeDirDomain}/%U \
     --krb5realm=$ADS_realm \
     --enablekrb5kdcdns \
     --enablekrb5realmdns \
     --smbidmapuid=100000-2000000000 \
     --smbidmapgid=100000-2000000000 \
     --enablelocauthorize \
     --enablepamaccess \
     --enablemkhomedir \
     --disablefingerprint \
     --disablesmartcard \
     --updateall

Option --winbindtemplatehomedir=/home/${HomeDirDomain}/%U is added so that when a user logs in for the first time on the system, a home directory /home/<domain>/<user> will be created.

After you run this command, the generated samba configuration should look like Listing 3. (Remember, workgroup and realm values are sample values shown as examples.)

Listing 3.
     [global]
     #--authconfig--start-line--
     
     # Generated by authconfig on 2014/01/15 18:15:56
     # DO NOT EDIT THIS SECTION (delimited by --start-line--/--end-line--)
     # Any modification may be deleted or altered by authconfig in future
     
     workgroup = DW
     realm = DW.IBM.COM
     security = ads
     idmap uid = 100000-2000000000
     idmap gid = 100000-2000000000
     template shell = /bin/bash
     winbind use default domain = true
     winbind offline logon = false
     
     #--authconfig--end-line--
     idmap config DW : backend=rid
     idmap config DW : range=100000-2000000000
     winbind enum users = false
     winbind enum groups = false
     # http://www.samba.org/samba/docs/man/manpages-3/smb.conf.5.html#KERBEROSMETHOD
     kerberos method = secrets and keytab
     client ldap sasl wrapping = sign
     username level = 3
     server string = Samba Server Version %v
     log file = /var/log/samba/log.%m
     max log size = 50
     passdb backend = tdbsam

The PAM configuration is also generated, producing the files /etc/pam.d/system-auth-ac and /etc/pam.d/password-auth-ac (Listing 4).

Listing 4.
     #%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_winbind.so use_first_pass
     auth        required      pam_deny.so
     
     account     required      pam_access.so
     account     required      pam_unix.so broken_shadow
     account     sufficient    pam_localuser.so
     account     sufficient    pam_succeed_if.so uid < 500 quiet
     account     [default=bad success=ok user_unknown=ignore] pam_winbind.so
     account     required      pam_permit.so
     
     password    requisite     pam_cracklib.so try_first_pass retry=3 type=
     password    sufficient    pam_unix.so sha512 shadow nullok try_first_pass use_authtok
     password    sufficient    pam_winbind.so use_authtok
     password    required      pam_deny.so
     
     session     optional      pam_keyinit.so revoke
     session     required      pam_limits.so
     session     optional      pam_oddjob_mkhomedir.so
     session     [success=1 default=ignore] pam_succeed_if.so service in crond quiet use_uid
     session     required      pam_unix.so

5. Modify Kerberos configuration

The /etc/krb5.conf file must be modified to:

  • Remove the references to EXAMPLE.COM.
  • Add default encryption types.
  • Add the default_realm entries in the libdefaults section.
  • Add the realm entries to the realm section.
  • Add entries for the domain_realm section.

This can be done with the code shown in Listing 5.

Listing 5.
     # creating backup of original config file 
     cp $ADS_kerberos_config_file $ADS_kerberos_config_file.bk
     
     # remove "EXAMPLE.COM" samples entries from config file
     #cat $ADS_kerberos_config_file.bk | sed '/EXAMPLE.COM.*{.*}/d'| 
     sed '/EXAMPLE.COM.*{/,/}/d' | grep -v EXAMPLE.COM > $ADS_kerberos_config_file
     cat $ADS_kerberos_config_file.bk |grep -vi EXAMPLE |grep -v } > 
     $ADS_kerberos_config_file
     
     # configure use of arcfour-hmac-md5 and aes256-cts-hmac-sha1-96 as defaults for 
     kerberos tickets in kerberos configuration file (this is required when ADS is running 
     on Windows 2008R2 server!)
     sed -i "s/^\[libdefaults\]/\[libdefaults\]\n default_tkt_enctypes = arcfour-hmac-md5 
     aes256-cts-hmac-sha1-96\n default_tgs_enctypes = arcfour-hmac-md5 aes256-cts-hmac-sha1-96/" 
     $ADS_kerberos_config_file
     
     # add default_realm entries to libdefaults section
     sed -i "s/^\[libdefaults\]/\[libdefaults\]\n default_realm = $ADS_realm/" 
     $ADS_kerberos_config_file
     
     # add realm entries to realm section
     sed -i "s/^\[realms\]/\[realms\]\n $ADS_realm = {\n  } /" $ADS_kerberos_config_file
     
     # add entries for the domain of the actual host to kerberos configuration file to ensure 
     that they are part of the realm 
     sed -i "s/^\[domain_realm\]/\[domain_realm\]\n `hostname -d` = $ADS_realm\n .`hostname -d` 
     = $ADS_realm/" $ADS_kerberos_config_file

The modified /etc/krb5.conf file should now look like Listing 6.

Listing 6.
     [logging]
     default = FILE:/var/log/krb5libs.log
     kdc = FILE:/var/log/krb5kdc.log
     admin_server = FILE:/var/log/kadmind.log
     
     [libdefaults]
     default_tkt_enctypes = arcfour-hmac-md5 aes256-cts-hmac-sha1-96
     default_tgs_enctypes = arcfour-hmac-md5 aes256-cts-hmac-sha1-96
     default_realm = DW.IBM.COM
     dns_lookup_realm = true
     dns_lookup_kdc = true
     ticket_lifetime = 24h
     renew_lifetime = 7d
     forwardable = true
     
     [realms]
     
     DW.IBM.COM = {
     }
     
     [domain_realm]
     dw.ibm.com = DW.IBM.COM
     .dw.ibm.com = DW.IBM.COM

6. Join Active Directory domain

Next, you will make the machine join the Active Directory domain. This is achieved using the net ads join command. More precisely, you will run the commands shown in Listing 7.

Listing 7.
     net ads join -w $ADS_workgroup -U $ADS_username%$ADS_password 
     createupn=host/`hostname -f`@$ADS_realm createComputer=$ADS_container_shortname 
     2> /dev/null | grep -v "DNS Update"
     
     if [[ `net ads testjoin` == "Join is OK" ]]; then
     logger_info "join_ads_domain: Successfully joined domain!"
     else
     logger_error "join_ads_domain: Failed to join domain!"
     fi

The variables passed in this command are:

  • $ADS_workgroup
    Name of the workgroup in the domain.
  • $ADS_username
    Username of the Active Directory Service Account.
  • $ADS_password
    Password of the Active Directory Service Account.
  • $ADS_realm
    Realm for the domain (for example, DW.IBM.COM).
  • $ADS_container_shortname
    Short name of the container where the host will be registered as Computer Object (for example, “IPAS/Servers” if its distinguished name is OU=Servers,OU=IPAS, DC=dw,DC=ibm,DC=com).

Notice that the hostname of the actual Active Directory Server is never used here. Instead, the following two lines in /etc/krb5.conf ensure that the Active Directory domain controllers are looked up through DNS:

dns_lookup_realm = true
dns_lookup_kdc = true

Upon joining the domain (that is, when running the net ads join command), Kerberos will obtain the Active Directory domain controllers from DNS records. The domain controllers here will act as Kerberos Authentication Servers as well as Key Distribution Centers (KDCs). Know that the DNS records are of type=SRV and the name needs to be of the format _kerberos._tcp.<domain>. Here, <domain> is the domain of the host (as reported by the command hostname –d). When using multiple domain controllers for a single domain, there should be a record in DNS for each of them.

The solution we describe here requires that these records for the domain controllers are present in DNS.

Listing 8 shows an example of how to lookup these records using DNS. In this case, you have a total of seven domain controllers for the domain test.dw.ibm.com.

Listing 8.
     nslookup -type=SRV _kerberos._tcp.test.dw.ibm.com 
     
     ;; Truncated, retrying in TCP mode.
     Server:         10.16.81.21
     Address:        10.16.81.21#53
     
     _kerberos._tcp.test.dw.ibm.com   service = 0 100 88 dw238vdcw9re.test.dw.ibm.com.
     _kerberos._tcp.test.dw.ibm.com   service = 0 100 88 dw244vdcw9rb.test.dw.ibm.com.
     _kerberos._tcp.test.dw.ibm.com   service = 0 100 88 dw243vdcw9rb.test.dw.ibm.com.
     _kerberos._tcp.test.dw.ibm.com   service = 0 100 88 dw242vdcw9re.test.dw.ibm.com.
     _kerberos._tcp.test.dw.ibm.com   service = 0 100 88 dw376vdcw9rb.test.dw.ibm.com.
     _kerberos._tcp.test.dw.ibm.com   service = 0 100 88 dw239vdcw9rb.test.dw.ibm.com.
     _kerberos._tcp.test.dw.ibm.com   service = 0 100 88 dw286vdcw9re.test.dw.ibm.com.

Once the server has successfully joined the domain, you can obtain more details using the command shown in Listing 9. This shows you the computer object that has been created in the container IPAS within Active Directory.

Listing 9.
     -bash-4.1# net ads status -U $ADS_username%********
     objectClass: top
     objectClass: person
     objectClass: organizationalPerson
     objectClass: user
     objectClass: computer
     cn: HOSTNAME
     distinguishedName: CN=HOSTNAME,OU=Servers,OU=IPAS,DC=dw,DC=ibm,DC=com
     instanceType: 4
     whenCreated: 20140122165553.0Z
     whenChanged: 20140122165553.0Z
     uSNCreated: 1876615
     uSNChanged: 1876622
     name: ON01P015
     objectGUID: 35ab4986-1775-4214-86ef-47efa308ba2a
     userAccountControl: 69632
     badPwdCount: 0
     codePage: 0
     countryCode: 0
     badPasswordTime: 0
     lastLogoff: 0
     lastLogon: 130348833536553755
     localPolicyFlags: 0
     pwdLastSet: 130348833532803611
     primaryGroupID: 515
     objectSid: S-1-5-21-1679220263-2264458565-1637611664-27733
     accountExpires: 9223372036854775807
     logonCount: 2
     sAMAccountName: DW01P015
     sAMAccountType: 805306369
     dNSHostName: hostname.dw.ibm.com
     userPrincipalName: host/hostname.dw.ibm.com@DW.IBM.COM
     servicePrincipalName: HOST/hostname.dw.ibm.com
     servicePrincipalName: HOST/HOSTNAME
     objectCategory: CN=Computer,CN=Schema,CN=Configuration,DC=dw,DC=ibm,DC=com
     isCriticalSystemObject: FALSE
     dSCorePropagationData: 16010101000000.0Z
     lastLogonTimestamp: 130348833536084987

Assuming Kerberos has been setup correctly, you should also be able to see the keys (KVNOs) from the local keytab file (/etc/krb5.keytab). The flag -e ensures that the encryption types used are also shown (Listing 10).

Listing 10.
     -bash-4.1# klist -ke
     Keytab name: WRFILE:/etc/krb5.keytab
     KVNO Principal
     ---- --------------------------------------------------------------------------
     2 host/hostname.dw.ibm.com@DW.IBM.COM (des-cbc-crc)
     2 host/hostname.dw.ibm.com@DW.IBM.COM (des-cbc-md5)
     2 host/hostname.dw.ibm.com@DW.IBM.COM (arcfour-hmac)
     2 host/hostname.dw.ibm.com@DW.IBM.COM (aes128-cts-hmac-sha1-96)
     2 host/hostname.dw.ibm.com@DW.IBM.COM (aes256-cts-hmac-sha1-96)
     2 host/hostname @DW.IBM.COM (des-cbc-crc)
     2 host/hostname @DW.IBM.COM (des-cbc-md5)
     2 host/hostname @DW.IBM.COM (arcfour-hmac)
     2 host/hostname @DW.IBM.COM (aes128-cts-hmac-sha1-96)
     2 host/hostname @DW.IBM.COM (aes256-cts-hmac-sha1-96)
     2 HOSTNAME$@DW.IBM.COM (des-cbc-crc)
     2 HOSTNAME$@DW.IBM.COM (des-cbc-md5)
     2 HOSTNAME$@DW.IBM.COM (arcfour-hmac)
     2 HOSTNAME$@DW.IBM.COM (aes128-cts-hmac-sha1-96)
     2 HOSTNAME$@DW.IBM.COM (aes256-cts-hmac-sha1-96)

7. Modify generated PAM winbind configuration for Kerberos SSO

Next, you will modify the PAM winbind configuration by editing the generated /etc/security/pam_winbind.conf file. Set the following parameters:

  • krb5_auth = yes
  • krb5_ccache_type = FILE
  • winbind refresh tickets = yes.

These options enable Kerberos Single-Sign-On (SSO). More precisely, they mean that PAM winbind will use Kerberos to authenticate when talking to the Active Directory domain controller, and a file is used to cache the retrieved Ticket Granting Ticket (TGT). The winbind refresh tickets = yes parameter, in conjunction with krb5_auth = yes, makes winbind keep the TGT up-to-date by refreshing it whenever necessary.

This can be done using the commands in Listing 11.

Listing 11.
     sed -i "s/.krb5_auth.*/krb5_auth = yes/g" /etc/security/pam_winbind.conf
     sed -i "s/.krb5_ccache_type.*/krb5_ccache_type = FILE/g" /etc/security/pam_winbind.conf
     echo "winbind refresh tickets = yes" >> /etc/security/pam_winbind.conf

The file /etc/security/pam_winbind.conf should now look like Listing 12.

Listing 12.
     #
     # pam_winbind configuration file
     #
     # /etc/security/pam_winbind.conf
     #
     
     [global]
     
     # turn on debugging
     ;debug = no
     
     # turn on extended PAM state debugging
     ;debug_state = no
     
     # request a cached login if possible
     # (needs "winbind offline logon = yes" in smb.conf)
     ;cached_login = no
     
     # authenticate using kerberos
     krb5_auth = yes
     
     # when using kerberos, request a "FILE" krb5 credential cache type
     # (leave empty to just do krb5 authentication but not have a ticket
     # afterwards)
     krb5_ccache_type = FILE
     
     # make successful authentication dependend on membership of one SID
     # (can also take a name)
     ;require_membership_of =
     
     # password expiry warning period in days
     ;warn_pwd_expire = 14
     
     # omit pam conversations
     ;silent = no
     
     # create homedirectory on the fly
     ;mkhomedir = no
     winbind refresh tickets = yes

Configuring RHEL 6 OS user permissions

With the integration of users and groups from Active Directory within the RHEL 6 OS, you can now start applying permissions. A relatively simple configuration is shown here, but more complex permissions could be setup as required.

8. Configure PAM access

The file /etc/security/access.conf is used to control access to the RHEL 6 OS. With this file:

  1. Clear the existing configuration file.
  2. Configure all users with access to cronjobs.
  3. Deny access to all users except root and members of the groups defined earlier in Active Directory.

The shell script in Listing 13 shows how these steps can be automated.

Listing 13.
     # creating backup of original config file 
     cp /etc/security/access.conf /etc/security/access.conf.bk
     
     # clear existing pam access configuration file
     >/etc/security/access.conf
     
     # configure all users access for cron jobs
     printf "+:ALL:cron\n" >> /etc/security/access.conf
     
     # configure access for root and the user(s) and groups \"${ADS_login_group}\", 
     \"${ADS_middleware_group}\" and \"${ADS_root_group}\"
     if [[ -n ${Local_users} ]];
     then
     for usr in $(echo ${Local_users}|tr "," " ")
     do
     if [[ $usr == "root" ]];
     then
     echo "root found in variable Local_users. This value is not processed. By default 
     root will be added to access.conf."
     continue
     else
     Usrs=$(printf "%s %s" "${Usrs}" "${usr}" )
     fi
     done
     fi
     
     if [[ -n ${Local_groups} ]];
     then
     for gp in $(echo ${Local_groups} |tr "," " ")
     do
     Grps=$(printf "%s %s" ${Grps} "(${gp})" )
     done
     fi
     
     printf "%sALL EXCEPT root%s %s %s %s %s:ALL\n" "-:" "${Usrs}" "${Grps}" "(${ADS_login_group})" 
     "(${ADS_middleware_group})" "(${ADS_root_group})" >> /etc/security/access.conf

The /etc/security/access.conf file should now look like Listing 14:

Listing 14.
     +:ALL:cron
     -:ALL EXCEPT root GRP_IPAS_myWorkload_login GRP_IPAS_myWorkload_middleware 
     GRP_IPAS_myWorkload_root :ALL

9. Configure sudo

Modify the /etc/sudoers file in order to configure the ability to switch the user defined in the Permissions section (Listing 15). A list of local middleware users is passed in using the ${ADS_middleware_users} variable. By default, Pure Application System uses virtuser as the middleware administrator (that is, IBM WebSphere Application Server administrator), but more users can be added to this list.

Listing 15.
     # creating backup of original config file 
     cp /etc/sudoers /etc/sudoers.bk
     
     # clear existing sudo configuration file
     >/etc/sudoers
     
     # configure default settings for sudo configuration file
     printf 'Defaults   !visiblepw\nDefaults    always_set_home\nDefaults    env_reset\nDefaults    
     env_keep =  "COLORS DISPLAY HOSTNAME HISTSIZE INPUTRC KDEDIR LS_COLORS"\nDefaults    
     env_keep += "MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE"\nDefaults    
     env_keep += "LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES"\nDefaults    
     env_keep += "LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE"\nDefaults    
     env_keep += "LC_TIME LC_ALL LANGUAGE LINGUAS _XKB_CHARSET XAUTHORITY"\nDefaults    
     secure_path = /sbin:/bin:/usr/sbin:/usr/bin\n' > /etc/sudoers
     
     # configure root with all permissions in sudo configuration file
     printf "root            ALL=(ALL)       ALL\n" >> /etc/sudoers
     
     # configure members of group ${ADS_middleware_group} to switch to the users 
     \"${ADS_middleware_users}\" in sudo configuration file
     local sudostring=""
     IFS=","
     for username in ${ADS_middleware_users}; do
     sudostring="${sudostring} /bin/su ${username}, /bin/su - ${username}, /bin/su - ${username} 
     -c whoami,"
     done
     unset IFS
     # remove last character from sudostring as it is a ','
     sudostring=`echo ${sudostring} | rev | cut -c 2- | rev`
     printf "%%${ADS_middleware_group} ALL=NOPASSWD:${sudostring}\n" >> /etc/sudoers
     
     # configure members of group ${ADS_root_group} to switch to root in sudo configuration file
     printf "%%${ADS_root_group} ALL=NOPASSWD:ALL\n" >> /etc/sudoers

The file should now look like Listing 16.

Listing 16.
     Defaults   !visiblepw
     Defaults    always_set_home
     Defaults    env_reset
     Defaults    env_keep =  "COLORS DISPLAY HOSTNAME HISTSIZE INPUTRC KDEDIR LS_COLORS"
     Defaults    env_keep += "MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE"
     Defaults    env_keep += "LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES"
     Defaults    env_keep += "LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE"
     Defaults    env_keep += "LC_TIME LC_ALL LANGUAGE LINGUAS _XKB_CHARSET XAUTHORITY"
     Defaults    secure_path = /sbin:/bin:/usr/sbin:/usr/bin
     root            ALL=(ALL)       ALL	
     %GRP_IPAS_myWorkload_middleware ALL=NOPASSWD:/bin/su virtuser, /bin/su - virtuser, 
     /bin/su - virtuser -c whoami
     %GRP_IPAS_myWorkload_root ALL=NOPASSWD:ALL

Finalizing configuration

Now that the entire configuration is complete, the last step is to restart the messagebus, oddjobd, smb and winbind services after having correctly set their run levels.

10. Configure run levels for services

You need to enable these services for runlevels 2, 3, 4 and 5:

  • Messagebus
  • Oddjobd
  • Smb
  • winbind

You can do this with the code shown in Listing 17.

Listing 17.
     chkconfig messagebus on --level 2345
     chkconfig oddjobd on --level 2345
     chkconfig smb on --level 2345	
     chkconfig winbind on --level 2345

11. Start services

Your final step is to ensure that these services are all started. The script in Listing 18 shows how this can be done in an automated fashion.

Listing 18.
     printf "start_services: ensure services \"messagebus\", \"oddjobd\", \"smb\" 
     and \"winbind\" are all started"
     
     # Verify status of service "messagebus" and start if not running yet.
     status=`service messagebus status`
     printf $status
     if [[ $status == "messagebus is stopped" ]]; then
     printf "start_services: messagebus not running, starting..."
     printf "start_services: `service messagebus start`"
     printf "start_services: messagebus started"
     fi
     
     # Verify status of service "oddjobd" and start if not running yet.
     status=`service oddjobd status`
     printf $status
     if [[ $status == "oddjobd is stopped" ]]; then
     printf "start_services: oddjobd not running, starting..."
     printf "start_services: `service oddjobd start`"
     printf "start_services: oddjobd started"
     fi
     
     # Verify status of service "smb" and start if not running yet.
     local status=`service smb status`
     printf $status
     if [[ $status == "smbd is stopped" ]]; then
     printf "start_services: smb not running, starting..."
     printf "start_services: `service smb start`"
     printf "start_services: smb started"
     fi
     
     #Verify status of service "winbindd" and start if not running yet.
     status=`service winbind status`
     printf $status
     if [[ $status == "winbindd is stopped" ]] || [[ $status == "winbindd dead but 
     pid file exists" ]]; then
     printf "start_services: winbind not running, starting..."
     printf "start_services: `service winbind start`"
     printf "start_services: winbind started"
     fi
     
     printf "start_services: all services started"
     return 0

Enforcing RHEL 6 OS authentication with Active Directory

By default, RHEL 6 OS is enforcing its local password policy. Now that the virtual machine is using Active Directory for authentication, you can disable RHEL local policy and use the Active Directory password policy.

To disable RHEL 6 local password policy, make the changes shown in Listing 19 to /etc/security/system-auth-ac.

Listing 19.
     #%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_winbind.so use_first_pass
     auth        required      pam_deny.so
     
     account     required      pam_access.so
     account     required      pam_unix.so broken_shadow
     account     sufficient    pam_localuser.so
     account     sufficient    pam_succeed_if.so uid < 500 quiet
     account     [default=bad success=ok user_unknown=ignore] pam_winbind.so
     account     required      pam_permit.so
     
     # password    requisite     pam_cracklib.so try_first_pass retry=3 type=
     password    sufficient    pam_unix.so sha512 shadow nullok try_first_pass use_authtok
     # password    sufficient    pam_winbind.so use_authtok
     password    sufficient    pam_winbind.so
     password    required      pam_deny.so
     
     session     optional      pam_keyinit.so revoke
     session     required      pam_limits.so
     session     optional      pam_oddjob_mkhomedir.so
     session     [success=1 default=ignore] pam_succeed_if.so service in crond quiet use_uid
     session     required      pam_unix.so

Listing 20 shows an example of Active Directory enforcing its password policy.

Listing 20.
     -bash-4.1$ passwd
     Changing password for user dwuser01.
     Changing password for dwuser01
     (current) NT password:
     New password:
     Retype new password:
     Password does not meet complexity requirements
     Your password must be at least 8 characters; cannot repeat any of your previous 
     10 passwords; must contain capitals, numerals or punctuation; and cannot contain your 
     account or full name; Please type a different password. Type a password which meets these 
     requirements in both text boxes.
     passwd: Authentication token manipulation error

Removing virtual machine from Active Directory

When the virtual machine is deleted (typically as the result of the deletion of the virtual system instance it belongs to), the host associated with that virtual machine should leave the Active Directory domain. This will also remove the corresponding computer object in Active Directory. The following command can be issued to leave the domain:

net ads leave -U $ADS_username%$ADS_password

The variables $ADS_username and $ADS_password are the username and password of the Active Directory Service Account.

Putting it all together

Now that you have seen how to automate the configuration of Active Directory integration, you are ready to build script packages. These can then be included in virtual system patterns, as you will see a little later.

Script packages

For the purpose of this article, two script packages have been included as examples:

  • add_ad_os_authentication must be run at VM creation, and basically configures and integrates the VM to the Active Directory domain.
  • remove_ad_os_authentication must be run at VM deletion and removes this VM from the Active Directory domain.

Script Package: add AD OS authentication

This script package performs steps 1 through 11 described in this article to integrate RHEL 6 authentication with Active Directory:

  1. Identify configuration file paths
  2. Start services
  3. Set initial samba configuration
  4. Modify configuration files
  5. Modify Kerberos configuration
  6. Join Active Directory domain
  7. Modify generated PAM winbind configuration for Kerberos SSO
  8. Configure PAM access
  9. Configure Sudo
  10. Configure run levels for services
  11. Start services

In this script package, the installation of RPMs is done using local files included in the script package zip file. A better solution would be to use the RedHat OS Update Shared Service provided by PureApplication System instead.

As this sample script package uses local RPM files, an additional parameter called OS_IMAGE is introduced to ensure that the correct RPMs for the image would be installed. It refers to the virtual image taken from the catalog that is used by the virtual system pattern for each part of the pattern. This virtual image type could be, for example, "Core OS 2.0.0.4", "DB2 Enterprise 9.7.0.8" or "WAS 8.5.5.1."

name: add AD OS authentication
execmode: 0 (at virtual system creation)
description: Install RPMs and configure for Active Directory OS authentication
envonly: TRUE
savevars: 0

Table 1. Parameters for add AD OS authentication
ParameterTypeRequiredExample valueDescription
OS_IMAGE(default)TrueValid values are:
BPM 8.0.1.0
BPM 8.5.0.1
Core OS 2.0.0.1
Core OS 2.0.0.3
Core OS 2.0.0.4
Core OS 2.1.0.0
IIS 9.1.0.0 CN
IIS 9.1.0.0 EN
WAS 8.0.0.4
WAS 8.0.0.5
WAS 8.0.0.7
WAS 8.5.0.0
Denotes the virtual system image used for deployment of the VM. This list is used in order to install the correct RPMs. This list needs to be adapted.
ADS_username(default)TrueipasadThe username to bind with Active Directory and has permissions to add computer object
ADS_passwordpasswordTrue********Password for the above username
ADS_container_shortname(default)TrueIPAS/ServersThe name of the container (OU) to store the computer object is required by the net ads join command. The OU string reads from top to bottom without relative distinguished names (RDNs), and is delimited by “/.”
ADS_workgroup(default)TrueDWName of the workgroup in the domain
ADS_realm(default)TrueDW.IBM.COMName of the realm is used by the Samba and Kerberos configurations.
ADS_login_group(default)TrueGRP_IPAS_<workload>_loginMembers of this group in Active Directory are permitted to login to the OS using SSH
ADS_middleware_group(default)TrueGRP_IPAS_<workload>_middlewareMembers of this group in Active Directory are permitted to switch user (su) to one or more different technical users on the OS, as specified by ADS_middleware_users.
ADS_root_group(default)TrueGRP_IPAS_<workload>_rootMembers of this group in Active Directory are allowed to switch user (su) to “root”.
ADS_middleware_users(default)Truevirtuser,db2inst1Comma-separated list containing the technical user(s) for middleware on the OS defined in the Active Directory (for example, virtuser, db2inst1, and so on).

Script package: remove AD OS authentication

The purpose of this script package is to ensure that the host leaves the domain upon deletion of the virtual machine. Therefore, this script package is configured to run at virtual system deletion. As this script package will be executed at deletion time, keep in mind that the virtual machine has to be running when deleting the virtual system instance. If the virtual machine is stopped, the script package will not be executed.

name: remove AD OS authentication
execmode: 1 (at virtual system deletion)
description: Remove virtual machine from Active Directory
envonly: TRUE
savevars: 0

Table 2. Parameters for remove AD OS authentication
ParameterTypeRequiredExample valueDescription
Remove_AD_ADS_container(default)TrueOU=IPAS,DC=dw,DC=ibm,DC=comDistinguished name of the container where the computer object is stored in the Active Directory.
Remove_AD_ADS_user(default)TrueipasadThe username to bind with Active Directory and has permissions to remove computer object
Remove_AD_ADS_passwordpasswordTrue********Password for the above username

Virtual system pattern

With the above two script packages, you can now build a simple virtual system pattern that will automatically join an Active Directory domain at deployment time. You just have to add the two script packages to each VM on which you want Active Directory authentication (Figure 3). Be careful to select the correct value for OS_IMAGE parameter, depending on the VM on which you’re adding the script packages.

Figure 3. Sample virtual system pattern (Pure Application System v2.0 firmware)
Sample virtual system pattern (Pure Application System v2.0 firmware)
Sample virtual system pattern (Pure Application System v2.0 firmware)

Logging on using Active Directory credentials

Listing 21 shows an example of a user logging with Active Directory credentials, showing group membership. This group membership enables the user to perform sudo su – virtuser and sudo –i (root).

Listing 21.
     login as: dwuser01
     dwuser01@pas01-grp063.dw.ibm.com's password:
     -bash-4.1$ id
     uid=138373(dwuser01) gid=100513(domain users) groups=100513(domain users),
     138530(GRP_IPAS_myWorkload_login),138531(GRP_IPAS_myWorkload_middleware),
     138532(GRP_IPAS_myWorkload_root)
     -bash-4.1$ sudo -i
     -bash-4.1$ id
     uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel)
     -bash-4.1$ logout
     -bash-4.1$ sudo su - virtuser
     [virtuser@pas01-grp063 ~]$ id
     uid=1000(virtuser gid=501(virtuser) groups=501(virtuser)
     [virtuser@pas01-grp063 ~]$

Logging on using SSO

Listing 22 shows an example of a user logging in from one VM (pas01-grp063.dw.ibm.com) to another (pas01-grp064.dw.ibm.com) using Single Sign-On. As both are part of the same Active Directory domain, no password is required since Kerberos handles this through Single Sign-On.

Listing 22.
     login as: dwuser01
     dwuser01@pas01-grp063.dw.ibm.com's password:
     -bash-4.1$ id
     uid=138373(dwuser01) gid=100513(domain users) groups=100513(domain users),
     138530(GRP_IPAS_myWorkload_login),138531(GRP_IPAS_myWorkload_middleware),
     138532(GRP_IPAS_myWorkload_root)
     -bash-4.1$ ssh pas01-grp064.dw.ibm.com
     -bash-4.1$ id
     uid=138373(dwuser01) gid=100513(domain users) groups=100513(domain users),
     138530(GRP_IPAS_myWorkload_login),138531(GRP_IPAS_myWorkload_middleware),
     138532(GRP_IPAS_myWorkload_root)
     -bash-4.1$

Virtual System Pattern (classic)

The solution is exactly the same with a classic virtual system pattern, and the same script packages can be used. You have to add both script packages to each part on which you want Active Directory authentication (Figure 4). Be careful to select the correct value for OS_IMAGE parameter, depending on the part on which you’re adding the script packages.

Figure 4. Sample virtual system pattern (Classic)
Sample virtual system pattern (Classic)
Sample virtual system pattern (Classic)

Conclusion

Integrating virtual machines running on IBM PureApplication System with a corporate Active Directory is useful, as it brings consistency across the IT infrastructure. Users and groups can be centrally managed in Active Directory and existing password policies can be leveraged, greatly reducing the effort to maintain a large number of virtual machines on PureApplication System. This article described the steps required for this integration with VMs running RedHat OS, and provided a set of sample script packages that can be used to accelerate the implementation.


Downloadable resources


Related topics


Comments

Sign in or register to add and subscribe to comments.

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=WebSphere, Cloud computing
ArticleID=985418
ArticleTitle=Integration of OS authentication with Microsoft Active Directory on IBM PureApplication System
publish-date=02112015