Introduction
In all enterprise networks there are multiple users and multiple applications. Managing these users and application may be a big challenge for the system administrators. Especially when it comes to authentication and authorization. The enterprise network may consist of several different Operating Systems (OS) and applications, even distributed applications like Platform LSF, Symphony and EGO.
To enhance security and general user management overhead, a goal for the System Administrator is usually to do user management for all OS's and applications in one place. As a response to this problem we have seen the adaptations of technologies such as NIS/YP, LDAP and Active Directory from the OS vendors. These schemes allow for centralized user, group and password databases with secure mechanisms for distributing this data to all the OS instances on the enterprise network. But what about multi-user applications?
Often, multi-user applications (ex. Databases and CMS systems) tend to have their own user database separate from the one supplied by the OS. This causes problems for the system administrator, resulting in creative scripts or update procedures for creating, modifying or deleting a user entry in the application user database, trying to keep it in sync with the OS user database. In addition to introducing user management overhead, failure to follow these procedures are a potential threat to the enterprise network security.
As Platform EGO is a distributed, multi-user application system, the problems described above need to be considered. By default EGO will run with it's built in user database, authentication and authorization system. For smaller department size systems this might be sufficient, but for bigger enterprise installation, integration with a centralized user database may be required.
Linux PAM
PAM is short for Pluggable authentication modules. The PAM modules are a mechanism to integrate multiple low-level authentication schemes into a high-level application programming interface (API), which allows programs that rely on authentication to be written independently of the underlying authentication scheme. PAM addresses the problem of multiple authentication schemes. Traditionally, each time a new authentication scheme was developed, it required all the necessary applications to be rewritten to support it.
Linux-PAM provide dynamic authorization for applications and services in a Linux system. PAM provides a way to develop programs that are independent of authentication scheme. These programs need "authentication modules" to be attached to them at run-time in order to work. Which authentication module is to be attached is dependent upon the local system setup and is at the
discretion of the local system administrator. The Linux PAM service is configured in the /etc/pam.conf file or by individual files in the /etc/pam.d/ directory (/etc/pam.d/<pam service name>). Below the listings of a PAM service file on RHEL4 given as an example:
Code:
# cat /etc/pam.d/sshd
#%PAM-1.0
auth required pam_stack.so service=system-auth
auth required pam_nologin.so
account required pam_stack.so service=system-auth
password required pam_stack.so service=system-auth
session required pam_stack.so service=system-auth
session required pam_loginuid.so
PAM configuration is based on a "stack" model. There is a given list, or stack, of required actions for any single service that must be completed before access to the service in question is granted.
Each action in the stack is supplied on a single PAM configuration file line, which contains exactly one each of the following: a module type, a control flag and a module. Each line contains a module type. A module type can be thought of as a specifier for one of four basic contexts within which a PAM stack entry can operate. These module type contexts are shown below:
auth: This stack entry's action is related to user authentication—for example, when asking the user to enter a password for login.
account: This stack entry's action is related to user account management—for example, when checking to see whether a user's account or password has expired.
session: This stack entry's action is related to connection or session management—for example, logging information about the user's login session to the system log.
password: This stack entry's action is related to password management—for example, when updating a user's password as stored in the system /etc/shadow file.
A PAM configuration file, therefore, is simply a list of these stack entries, one per line, which define the entire set of authentication procedures for a Linux system. When new services are installed on a Linux system that require new authentication techniques, they will normally include additional PAM modules, specific to the service in question, along with documentation on how the module is to be used. The new service and modules can then quickly and easily be incorporated into the existing authentication framework.
Note that due to limits of the PAM API, it is not possible for a PAM module to request a Kerberos service ticket from a Kerberos Key Distribution Center (KDC), PAM can only fetch granting tickets. To fetch a service ticket for a particular application, and not prompt the user to enter credentials again, that application must be specifically coded to support Kerberos.
Glibc NSS
The glibc Name Service Switch (NSS) allows Linux configuration databases to be provided by different sources, including local files (for example: /etc/passwd, /etc/group, /etc/hosts), LDAP, and other sources. A system administrator usually configures NSS using the file /etc/nsswitch.conf. This lists databases (such as passwd, shadow and group) and one or more sources for obtaining that information (e.g files for local files, LDAP and NIS). Below is an example section of /etc/nsswitch.conf:
Code:
passwd: db files ldap nis
shadow: db files ldap nis
group: db files ldap nis
NSS is implemented within the GNU C library, so that calls to functions such as getpwent() or getgrent() will call into the appropriate NSS module. Making the modifications at the library level means that existing applications that use these routines for identity information do not require any changes to work with NSS. GNU libc consults /etc/nsswitch.conf for the configuration which describes how it will answer the application's question. For each module listed, libc constructs a soname (libnss_foo.so.version), uses dlopen() to load the named library, and calls into a function provided by that library.
Exactly which function the shared library should export, and what its signature should be, varies based on which function the application actually called, but there's a pattern:
Code:
getpwnam(),getpwnam_r() -> _nss_foo_getpwnam_r()
getpwuid(),getpwuid_r() -> _nss_foo_getpwuid_r()
A simple way to find the available functions provided by the NSS library can for example be done with the command nm:
Code:
# nm -D /usr/lib64/libnss_ldap.so | grep _nss_
0000000000040e20 T _nss_ldap_endaliasent
00000000000430d0 T _nss_ldap_endautomntent
0000000000042b90 T _nss_ldap_endetherent
000000000003de10 T _nss_ldap_endgrent
0000000000040070 T _nss_ldap_endhostent
0000000000040430 T _nss_ldap_endnetent
000000000003fac0 T _nss_ldap_endnetgrent
0000000000040840 T _nss_ldap_endprotoent
000000000003dcc0 T _nss_ldap_endpwent
000000000003fc50 T _nss_ldap_endrpcent
00000000000411c0 T _nss_ldap_endservent
0000000000040c80 T _nss_ldap_endspent
0000000000040e70 T _nss_ldap_getaliasbyname_r
0000000000040d20 T _nss_ldap_getaliasent_r
0000000000042ce0 T _nss_ldap_getautomntbyname_r
0000000000042e70 T _nss_ldap_getautomntent_r
0000000000042a70 T _nss_ldap_getetherent_r
000000000003ddb0 T _nss_ldap_getgrent_r
000000000003de60 T _nss_ldap_getgrgid_r
000000000003ded0 T _nss_ldap_getgrnam_r
00000000000400c0 T _nss_ldap_gethostbyaddr_r
00000000000401a0 T _nss_ldap_gethostbyname2_r
0000000000040260 T _nss_ldap_gethostbyname_r
000000000003fd40 T _nss_ldap_gethostent_r
0000000000042c90 T _nss_ldap_gethostton_r
0000000000040510 T _nss_ldap_getnetbyaddr_r
0000000000040480 T _nss_ldap_getnetbyname_r
0000000000040290 T _nss_ldap_getnetent_r
000000000003f620 T _nss_ldap_getnetgrent_r
0000000000042be0 T _nss_ldap_getntohost_r
00000000000408e0 T _nss_ldap_getprotobyname_r
0000000000040890 T _nss_ldap_getprotobynumber_r
0000000000040700 T _nss_ldap_getprotoent_r
000000000003d940 T _nss_ldap_getpwent_r
000000000003dd60 T _nss_ldap_getpwnam_r
000000000003dd10 T _nss_ldap_getpwuid_r
000000000003fcf0 T _nss_ldap_getrpcbyname_r
000000000003fca0 T _nss_ldap_getrpcbynumber_r
000000000003fb10 T _nss_ldap_getrpcent_r
00000000000412a0 T _nss_ldap_getservbyname_r
0000000000041210 T _nss_ldap_getservbyport_r
0000000000040ec0 T _nss_ldap_getservent_r
0000000000040930 T _nss_ldap_getspent_r
0000000000040cd0 T _nss_ldap_getspnam_r
000000000003e240 T _nss_ldap_initgroups
000000000003df40 T _nss_ldap_initgroups_dyn
0000000000040e50 T _nss_ldap_setaliasent
0000000000043330 T _nss_ldap_setautomntent
0000000000042bc0 T _nss_ldap_setetherent
000000000003de40 T _nss_ldap_setgrent
00000000000400a0 T _nss_ldap_sethostent
0000000000040460 T _nss_ldap_setnetent
000000000003f810 T _nss_ldap_setnetgrent
0000000000040870 T _nss_ldap_setprotoent
000000000003dcf0 T _nss_ldap_setpwent
000000000003fc80 T _nss_ldap_setrpcent
00000000000411f0 T _nss_ldap_setservent
0000000000040cb0 T _nss_ldap_setspent
Note that the application need to use a limited set of standardized functions to access the databases through the NSS scheme. See glibc manual for more information.
The EGO authentication and user scheme
By default EGO uses its own authentication and user scheme based on a centralized XML file/database (users.xml). The default scheme is implemented as a security plugin for vemkd called “egodefault”. In addition there are plugins for Kerberos (kerberos5), Siteminder (siteminder) and a simple generic OS plugin (os). After being authorized on the master host vemkd uses credentials (optionally supplied by the plugins) to authorize the user on the client hosts.
The existing OS plugin works on both Linux and Windows. But on Linux it has some limitations: It only reads the /etc/passwd file. The plugin does “old school” password hash comparison and has no concept of groups. By only reading the /etc/passwd file it is excluded from working with multiple authentication schemes (ex. LDAP) and groups are not available.
It is possble to make EGO support multiple authentication mechanisms by integrating directly with the the different user schemes. One option is to create a EGO security plugin for use with ex. LDAP. This would result in ex. a “egoldap” plugin. But while the standard UNIX user and group databases (/etc/passwd and /etc/group) have standard formats, directories such as LDAP are more complicated. For example an Active Directory schema is different from a standard Open-LDAP schema even though the LDAP protocol is the same. In addition the data formats used might differ, for example the password hash algorithms. All these subtle differences may case a lot of maintenance overhead. In essence one will end up implementing a lot of the same functionality already provided by the PAM and NSS modules.
The PAM security plugin for EGO
The EGO PAM security plugin makes use of the existing PAM and NSS modules provided by the OS vendor or other 3rd party module providers. By creating a EGO security plugin based on the PAM and NSS APIs, the system administrator has full control over the authentication policy and user/group management databases while the EGO security plugin stays the same. The authentication policy is controlled outside EGO (PAM), together with the choice of user/group database source (NSS). No specific directory or database code is needed. By using this plugin, EGO will be able to support any user and authentication scheme supported by the Linux distribution itself.
The plugin is made up of two main parts:
Authentication:
The user authentication (and password verification) is done through the PAM API. The PAM service used (and hence the pam security policy) is configurable via the pamauth.conf plugin configuration file. Example pamauth.conf file:
Code:
# EGO PAM plugin configuration file
# Mandatory parameters
# PAM_ADMIN=<pam-account-name>
# PAM account that should be mapped to EGO 'Admin' user.
# For Active Directory use the format <domain-name>\<username>
PAM_ADMIN=egoadmin
# PAM_SERVICE=<pam-service-name>
# PAM Service file (under /etc/pam.d) defining the
# PAM policy to be used for EGO.
PAM_SERVICE=ego
Hence the plugin can use an existing pam service (ex. sshd) or its own policy. Note that it is up to the PAM modules configured in this PAM service file to decide where (in what database) to find the user, how to authenticate the user and how to verify the password. The PAM modules are also responsible for a verifying that the user account is valid. In other words, the plugin requires the auth and account module types present in the PAM service file.
User/group management:
User and group management are read-only and done using NSS compatible functions:
getpwnam(), getpwent(), getgrnam() and getgrent(). Unfortunately the support for user and group creation and modification is very limited (see putpwent()) through NSS and will probably require specific database scheme code.
The databases (there may be several) accessed are controlled by the /etc/nsswitch configuration, and whatever configuration of the specific NSS library specified require. Hence changing the user database from files to LDAP is done simply by editing the /etc/nsswitch configuration.
Example: Integrating EGO with Active Directory
By using the PAM security plugin for EGO, integration of EGO and Active Directory is now reduced to integration between the Linux OS and Active Directory. In other words, the integration is now a system administrator task, outside the EGO application.
Varying levels of interoperability with Active Directory can be achieved on Linux through standards compliant LDAP clients. But interpretation of group policies and attributes are sometimes missing.
There are also third-party vendors who offer Active Directory integration for Unix platforms. For example:
It is also possible to do authentication (but not user management) using the Linux Kerberos client. This Kerberos setup can be combined with Samba & Active Directory integration.
An alternate option is to use another 3rd party directory service, which can perform a two-way synchronization with Active Directory and thus provide a "deflected" integration with Active Directory that Unix and Linux clients can authenticate to.
Another option is to use OpenLDAP with its translucent overlay, which can extend entries in any remote LDAP server with additional attributes stored in a local database. Clients pointed at the local database will see entries containing both the remote and local attributes, while the remote database remains completely untouched.
Finally, The Samba project are also working on an Active Directory integration.
To conclude, there seems to be no one right solution for integrating Linux with Active Directory. The method of choice needs to be left to the individual system administrator.
Proof of concept using Likewise
As a proof of concept we have chosen to use Likewise Open for this example. Likewise Open is free (but not open source) and provides integration between Linux and Active Directory without needing any changes to the directory server.
likewise Open contains both a PAM module (/lib64/security/pam_lsass.so) and a NSS module (/lib64/libnss_lsass.so.
Basically Likewise Open runs a daemon (lsassd) that handles connections to the AD. The PAM and NSS libraries connect to this daemon when retrieving data and/or authenticating. In addition it modifies /etc/nsswitch and some of the pam service files under /etc/pam.d (ex.sshd). Example of the /etc/nsswitch entries using lsassd:
Code:
passwd: files lsass
shadow: files
group: files lsass
After installing Likewise Open on the Linux host, joining the Active directory domain is done with the following command:
Code:
/opt/likewise/bin/domainjoin-cli join <DOMAIN> Administrator
After Joining the PAM and NSS modules allow for login on the Linux server by using the an AD domain user and password:
Code:
# ssh MYDOMAIN\\Administrator@localhost
Password:
Last login: Fri Nov 14 04:00:55 2008 from 192.168.4.3
-sh-3.00$ id
uid=1170211316(MYDOMAIN\administrator) gid=1170211329(MYDOMAIN\domain^users) groups=1170211328(MYDOMAIN\domain^admins), \
1170211329(MYDOMAIN\domain^users), \
1170211334(MYDOMAIN\schema^admins), \
1170211335(MYDOMAIN\enterprise^admins), \
1170211336(MYDOMAIN\group^policy^creator^owners), \
1170211388(MYDOMAIN\denied^rodc^password^replication^group)
-sh-3.00$
Various lsassd can be controlled in configuration files under /etc/likewise/. Note that it usually is a good idea to make the Active Directory server primary DNS on the Linux host before joining the domain (lsassd uses optional DNS information to join the domain). These options can be viewed from the Linux host by doing:
Code:
# dig @<MY DNS> -t any _ldap._tcp.dc._msdcs.<DOMAIN>
Also, be ware that the Active Directory authentication uses a Kerberos policy that is sensitive to clock skew. It might also be a good idea to run NTP on the Linux host using the Active Directory host as server. Running the Linux host on a virtual machine might create problem with this clock synchronization.
Likewise Open have good documentation explaining the various aspects of configuring and setup.
When Likewise Open is installed and configures, the PAM security plugin for EGO will automatically pick up the new users and groups and authenticate the users in the Active Directory. If the plugin was already running on the standard files databases, no change to the plugin or EGO setup is required.
Get the PAM security plugin for EGO
A link or attachment will be added here soon...