Rate this page del.icio.us  Digg slashdot StumbleUpon

Serving Apples: Integrating Mac OS X clients into a Fedora network

by W. Michael Petullo

Since its debut in March of 2001, Mac OS® X® has been a very attractive operating system for many Linux® and Unix™ enthusiasts. The operating system brings the interface design Apple is known for to Unix and builds on the previous efforts of A/UX® and especially NeXT®. This article will introduce the reader to a technique for configuring a Fedora® 8 server and corresponding workstation running Mac OS X Tiger (10.4). I will discuss ways to provide three key services: authorization, authentication, and file sharing.

Network information

OpenLDAP provides directory services and is often used to provide network information. This information may include users and groups. Our server will use OpenLDAP to provide basic account information and network authorization.

Note:
If you are running Fedora’s firewall, iptables, then you must configure it to allow incoming LDAPS, Kerberos and NFSv3 traffic. On Fedora 7, this configuration may be done using the system-config-securitylevel tool. LDAPS and Kerberos are straightforward, simply list ldaps:tcp and kerberos:udp in the “Other” field of the Firewall Customization interface. NFSv3 is actually a suite of software running on various ports. In order to allow NFSv3 traffic, allow connections on the following ports: nfs:tcp nfs:udp sunrpc:tcp sunrpc:udp 32803:tcp 892:tcp 892:tcp 662:tcp 662:udp 875:tcp 875:udp filenet-rpc:udp. These ports correspond to the ports configured in /etc/sysconfig/nfs.

The Fedora Linux server will require the nss_ldap, openldap-clients, and openldap-servers packages. These packages may be installed using the command, yum install nss_ldap openldap-clients openldap-servers.

The first step in setting up the OpenLDAP server is to configure the stand-alone LDAP server (slapd). Write the following to /etc/openldap/slapd.conf to configure slapd:

include         /etc/openldap/schema/core.schema
include         /etc/openldap/schema/cosine.schema
include         /etc/openldap/schema/inetorgperson.schema
include         /etc/openldap/schema/nis.schema
include         /etc/openldap/schema/misc.schema
include         /etc/openldap/schema/redhat/autofs.schema

allow           bind_v2

pidfile         /var/run/openldap/slapd.pid
argsfile        /var/run/openldap/slapd.args

TLSCACertificateFile /etc/pki/tls/certs/ca-bundle.crt
TLSCertificateFile /etc/pki/tls/certs/slapd.pem
TLSCertificateKeyFile /etc/pki/tls/certs/slapd.pem

database        bdb
suffix          "dc=example,dc=com"
rootdn          "cn=Manager,dc=example,dc=com"
rootpw          {SSHA}REPLACEME

directory       /var/lib/ldap

index objectClass                       eq,pres
index ou,cn,mail,surname,givenname      eq,pres,sub
index uidNumber,gidNumber,loginShell    eq,pres
index uid,memberUid                     eq,pres,sub
index nisMapName,nisMapEntry            eq,pres,sub

The interesting portion of the configuration file is the definition of the suffix as “dc=example,dc=com.” This sets the suffix that will be used for queries to the LDAP server. This is essentially an administrative domain. To generate a real password for the rootpw field, use the slappasswd command. Copy the output of slappasswd and paste it into the rootpw field in slapd.conf.

In order to prevent users from observing LDAP traffic as it passes across the network, we will configure slapd to encrypt its traffic. To require that slapd uses LDAP over TLS (LDAPS), add the following lines to /etc/sysconfig/ldap:

SLAPD_LDAP=no
SLAPD_LDAPS=yes

Once slapd is set up, we will configure the Linux server to act as its own client. This ensures that accounts set up for the network are valid on the server as well. The file /etc/openldap/ldap.conf configures OpenLDAP client software to connect to localhost using LDAP over TLS (LDAPS):

BASE          dc=example,dc=com
URI           ldaps://localhost
TLS_REQCERT   allow
TLS           hard
TLS_CACERTDIR /etc/openldap/cacerts

Now that LDAP is fully configured, issue the commands /sbin/service ldap start to start the service and /sbin/chkconfig ldap on to cause it to start each time the system boots. We may now populate LDAP’s database. The first step to doing this is to generate a database shell and save it to any file (e.g., filename.ldif):

dn: dc=example,dc=com
objectClass: organization
objectClass: dcObject
o: Example, Inc.
dc: example

dn: ou=people,dc=example,dc=com
objectClass: organizationalUnit
ou: people

dn: ou=group,dc=example,dc=com
objectClass: organizationalUnit
ou: group

Once this file has been created, you may import it into LDAP using ldapadd -x -D 'cn=Manager,dc=example,dc=com' -W -f filename.ldif. We may now create an account consisting of a user and group (e.g., user.ldif):

dn: uid=user,ou=People,dc=example,dc=com
uid: user
cn: Joe User
objectClass: account
objectClass: posixAccount
objectClass: top
userPassword:: XXXX
loginShell: /bin/bash
uidNumber: 500
gidNumber: 500
homeDirectory: /home/user
gecos: Joe User

dn: cn=user,ou=Group,dc=example,dc=com
objectClass: posixGroup
objectClass: top
cn: user
userPassword:: XXXX
gidNumber: 500

Many of these fields may look familiar if you are familiar with /etc/passwd, the standard Unix account information file. Again, we will use ldapadd to insert this LDIF data into the LDAP database: ldapadd -x -D 'cn=Manager,dc=example,dc=com' -W -f user.ldif.

The LDAP server has been configured and its database is populated. We may now query it from the command line using ldapsearch -x. This should display all of the data we have entered into the LDAP database. Ldapadd and ldapdelete are the commands OpenLDAP provides to manipulate its database. Refer to the OpenLDAP documentation for more details about these commands.

The final configuration is of OpenLDAP’s GNU C library counterpart, the ldap_nss module. The following goes in /etc/ldap.conf and will configure ldap_nss to resolve system database queries using LDAPS.

bind_policy soft
base dc=example,dc=com
uri ldaps://localhost
ssl start_tls
ssl on
nss_initgroups_ignoreusers ldap

In order to tell the GNU C library to use the nss_ldap module configured above, ensure /etc/nsswitch.conf contains the following two lines:

[...]
passwd:     files ldap
group:      files ldap
[...]

Now that the name service switch is configured to query using LDAP, getent passwd should return some account information for the user we created above. The output should be as follows:

[...]
user:*:500:500:Joe User:/home/user:/bin/bash

The first service on the Linux server, authorization, is now available. Let’s turn our focus to the workstation.

Assume that we have a fresh Mac OS X installation on the workstation. The first time it is booted, the OS prompts the user to create a user account. Although most account information will be served by LDAP, it is still important to have a local administrator account. We will use this account to configure the workstation. Name the account “Local Administrator Account” and give it a short name of “local.” Log in to the local account.

Different flavors of Unix have different techniques for numbering UID’s. For example, Fedora starts new users at 500. Mac OS X starts at 501. It is
important to ensure that the local Mac OS X user does not collide with LDAP users. The following commands change the UID of our local account
so that it is compatible with the accounts that will be served by the Linux server.

First, identify local’s current UID and GID:

sudo niutil -read . /users/local | grep '^uid'
sudo niutil -read . /users/local | grep '^gid'

Next, change local’s GID, primary group and UID to 499, making room for the Linux accounts that will start with 500:

sudo niutil -createprop . /groups/local gid 499
sudo niutil -createprop . /users/local gid 499
sudo niutil -createprop . /users/local uid 499

At this point it becomes necessary to log out and then back in to the local account. This ensures that the new UID and GID are adopted by the
running session. However, existing files that are owned by local will retain the now incorrect UID and GID of 501. This is easily fixed with the
following two commands:

sudo find / -user 501 -exec chown 499 {} ;
sudo find / -group 501 -exec chgrp 499 {} ;

Now we are done changing the user local’s UID and GID. Logging out and back in again will ensure the account is fully operational.

The next step is for convenience. So that we don’t have to refer to the server by IP address, we will add an entry to the workstation’s /etc/hosts file. Add:

192.168.0.10 server.example.com server

where 192.168.0.10 is replaced with your server’s IP address.

Fig 1. Directory Access Screenshot

Fig 1. Directory Access Screenshot

Figure 1 is a picture of Mac OS X Directory Access® configuration tool. We will use this tool to configure our workstation to use LDAP for network information. The Directory Access tool is found in Applications/Utilities. Once the tool is running, select the “Services” tab and ensure that only the LDAPv3 block is checked. Highlight LDAPv3 and press the “Configure” button. Select the “New…” button. You should now see the window pictured in Figure 2.

Fig 2. Directory Access: Configure Screenshot

Fig 2. Directory Access: Configure Screenshot

Fill out the form as documented in Figure 2 and press “Continue.” Fill in the rest of the form as documented in Figure 3 and press “Continue” again. Select “Ok” and name the configuration something relevant to your network. Click “Ok” and “Apply” to apply the configuration. You may now quit the Directory Access application.

Fig 3. Directory Access: Configure: New Screenshot

Fig 3. Directory Access: Configure: New Screenshot

The LDAP configuration is tested much like it was tested on the Linux server. The following command should print the contents of the Linux server’s LDAP database: ldapsearch -H ldaps://server -b dc=example,dc=com -x.

The graphical login tool on Mac OS X does not recognize LDAP accounts. Because of this, it will not list these accounts as available for use. To get around this, configure the login window to allow the input of both usernames and passwords. This is configured by opening the Mac OS X System Preferences tool and selecting the Accounts applet. Press the “Login Options” button to configure the login window. See Figure 4.

Fig 4.

Fig 4. Accounts Screenshot

Authentication

Now that the server and workstation both have their corresponding LDAP systems operational, we will configure the authentication service using a system called Kerberos. Kerberos is an authentication system that uses a key distribution center to manage access to network resources. This KDC will reside on our Linux server.

The server will require the krb5-libs, krb5-workstation, krb5-server, pam_krb5, and ntp packages.

To start configuring the Kerberos service, add the following to /etc/krb5.conf:

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

[libdefaults]
default_realm = example.com
dns_lookup_realm = false
dns_lookup_kdc = false
ticket_lifetime = 24h
forwardable = yes

[realms]
    example.com = {
    kdc = server.example.com:88
    admin_server = server.example.com:749
    default_domain = example.com
}

[domain_realm]
.example.com = example.com
example.com = example.com

[kdc]
profile = /var/kerberos/krb5kdc/kdc.conf

[appdefaults]
pam = {
    debug = false
    ticket_lifetime = 36000
    renew_lifetime = 36000
    forwardable = true
    krb4_convert = false
    kdc_timeout = 1
    max_retries = 1
}

Next, initialize the Kerberos system with kdb5_util create -s. Add the following to /var/kerberos/krb5kdc/kdc.conf:

[kdcdefaults]
v4_mode = nopreauth
kdc_ports = 88,750
kdc_tcp_ports = 88

[realms]
example.com = {
    acl_file = /var/kerberos/krb5kdc/kadm5.acl
    dict_file = /usr/share/dict/words
    admin_keytab = /var/kerberos/krb5kdc/kadm5.keytab
    supported_enctypes = des3-hmac-sha1:normal arcfour-hmac:normal des-hmac-sha1:normal des-cbc-md5:normal des-cbc-crc:normal des-cbc-crc:v4 des-cbc-crc:afs3
}

As before, use service and chkconfig to start the service: /sbin/service krb5kdc start and /sbin/chkconfig krb5kdc on.

The Kerberos system is now fully initialized on the server. It is now possible to add users to the Kerberos database. User information is stored in LDAP, but their authentication tokens exist in Kerberos. Add the user “user” to the Kerberos database using /usr/kerberos/sbin/kadmin.local:

/usr/kerberos/sbin/kadmin.local
> addprinc user

An account that has a token in Kerberos and a record in LDAP is almost complete. The final step is to create a home directory for the user:

mkdir /home/user
chown user:user /home/user

The Kerberos protocol is heavily dependent on synchronized system clocks. We will use NTP to ensure our computers’ clocks are synchronized. Run ntpdate -u 128.101.101.101 to synchronize the server’s clock. Use /sbin/service ntpd start and /sbin/chkconfig ntpd on to ensure it stays synchronized.

As with LDAP, we want our Linux server to also act as a client, allowing network accounts to be valid on the server (note, you may want to restrict
accounts on the server later). On Linux, the PAM system provides a module to authenticate users using Kerberos. The command authconfig --enablekrb5 --update will configure PAM to allow authenticating against the Kerberos KDC.

We will now turn our attention to the workstation.

As before, we must set up NTP. Mac OS X provides a preferences applet to do this as documented in Figure 5.

Fig 5. Date & Time Screenshot

Fig 5. Date & Time Screenshot

Next, we will configure the Kerberos client libraries on the workstation. Edit /Library/Preferences/edu.mit.Kerberos to contain the following:

[libdefaults]
default_realm = example.com
dns_lookup_realm = false
dns_lookup_kdc = false
ticket_lifetime = 24h
forwardable = yes

[realms]
example.com = {
    kdc = server.example.com:88
    admin_server = server.example.com:749
    default_domain = example.com
}

[domain_realm]
.example.com = example.com
example.com = example.com

The next step is to configure the login window to authenticate accounts using Kerberos. To do this, edit /private/etc/authorization. Search for system.login.console. Within the <dict> entry, look for the mechanisms <key> and, within it, the <string> containing authinternal. Change the string “authinternal” to “builtin:krb5authnoverify,privileged.”

Kerberos is now configured. The configuration may be tested using /System/Library/CoreServices/Kerberos. Click new and fill out the form with valid account information as depicted in Figure 6. You should be able to authenticate the user “user” against the Kerberos server.

Fig 6. Kerberos Screenshot

Fig 6. Kerberos Screenshot

File sharing

The final service we will configure is file sharing. We will support file sharing by using NFS version 3. Once again we will begin by turning our attention to the Linux server. The server will require the nfs-utils package.

Before starting the NFS service, we will configure a few of the daemons in the NFSv3 suite. Adding the following to /etc/sysconfig/nfs will ensure that the daemons listen on predictable ports, making the configuration of a firewall easier:

RQUOTAD_PORT=875
LOCKD_TCPPORT=32803
LOCKD_UDPPORT=32769
MOUNTD_PORT=892
STATD_PORT=662
STATD_OUTGOING_PORT=2020

Start the NFS service using /sbin/service nfs start and /sbin/chkconfig nfs on.

The file /etc/exports determines which portion of the server’s filesystem is exported by NFS. The following will export /home on the server to both NFSv3 and NFSv4 clients:

/home *(rw,fsid=0,insecure,no_subtree_check,sync)

The command exportfs -rv will tell the NFS daemon to reread the /etc/exports file. This NFS export may be tested with mount server:/home /somedirectory.

Fig 7. NetInfo Manager Screenshot

Fig 7. NetInfo Manager Screenshot

Mac OS X does not yet support NFSv4. However, Mac OS X does have solid support for NFSv3, including an automounter. The NetInfo Manager may be used to configure the automounter and is found in Applications/Utilities. This tool is shown in Figure 7. To create a mount, select the mounts folder and create a subfolder named server.example.com:/home. Within this new folder, add the following properties and values by selecting Directory  >  New Property from the applicaion menu:

Property: dir        Value:  /Network/Servers
Property: vfstype    Value:  nfs
Property: opts       Values: net
                             -i
                             -P

The “opts” property has multiple values. These may be input by repeatedly selecting Directory  >  Insert Value from the application menu.

You may force the automounter to reread its new configuration using sudo kill -HUP `cat /var/run/automount.pid`.

The options we have specified will cause the NFS share server.example.com:/home to be mounted at /automount/Servers/server.example.com/home whenever the directory is accessed. In order to make this share available as a user’s home directory in /home, create a symbolic link:

sudo ln -s /automount/Servers/server.example.com/home /home

Now a user’s home directory will be mounted at login.

Conclusion

This article has described how to configure a Fedora Linux server to provide network authorization, authentication, and file sharing services. It has also shown how to integrate a Mac OS X workstation into such an environment. Linux provides a very powerful server platform. The combination of Mac OS X and Linux workstations creates an environment that may run a very wide variety of applications and will appeal to many different user requirements.

8 responses to “Serving Apples: Integrating Mac OS X clients into a Fedora network”

  1. Alan Weber says:

    Great article!
    Neat mini-howto to ldap and Kerberos beyond the mac stuff.
    Is there any similar solution available for XP/Win2k clients?
    Mainly interested in centralizing account management. Samba can do the rest.
    Thanks.

  2. ITX ler says:

    Great HowTo for OS X Tiger. Work excelllent with my opensuse 10.3 LDAP, NFS Server and Samba for Windows Clients. How can NFS Home Mounts solve with OSX Leopard? Thanks for your Request.

  3. G. Reincke says:

    Hi, this is a very interisting article! I’ve tried to set this up using centos 5.1, but can’t ses the user created by calling “getent passwd”. The output hangs at this point. Any ideas? May I go on setting up teh os x client stuff? Thanks for a hint!

  4. Mike says:

    G.,

    If the “getent passwd” command fails, then NSS LDAP is probably not configured correctly.

    What happens when you run “ldapsearch -x” on the LDAP server? You should see the contents of your LDAP database. This indicates that your OpenLDAP server and clients are configured right.

    Now, /etc/ldap.conf configures the NSS LDAP package. Are you sure you created this file properly?

  5. Allan Porto says:

    Congratulations!!!
    Your article is great, but I tried to cache user account information for mobile users, and I Have not found any information about that. Do you know how make that?

  6. Mike says:

    Integrating mobile users into a LDAP / Kerberos system is still an open problem on Fedora. I have some notes available at http://www.flyn.org/laptopldap/laptopldap.html, but there does not yet seem to be a complete solution.

  7. joshuadf says:

    Thanks for the facinating article.

    On the server side, there is a LDAP/Kerberos integration project called freeIPA which has actual LDAP management tools rather than raw LDIF files. It’s just released but looks very nice.

    It even has documentation on configuring Mac OS 10.4 clients already, though this article goes into more depth.

  8. Santo says:

    Hi thanks for the HowTo. We can integrate NFS Home for my Leopard Clients. Thanks for one request.

Leave a reply