Big Note: This document was written for v10.2, and so is now depreciated.
This document aims to clearly describe the configuration of Mac OS X Server and Mac OS X
to achieve the following:
- The server will host a network netinfo domain accessible via ldap.
- The client will bind to this domain using ldap, and log in with a network user account.
- The client will automount a network home directory from the server via afp.
- All the ldap transactions will be through SSL. This includes setting up a demo
certificate authority, generating the cert requests, signing them, and properly configuring
the client and server to use the new certificate.
These directions assume that you're starting with a freshly configured server. One thing to watch
out for is that sometimes the server will come up with a hostname of 'localhost' the first time
it's rebooted, after you've gone through the setup assistants. Reboot again so that the hostname
as reported in a terminal shell prompt is correct.
Setting up a network netinfo domain with automounts
- Launch Open Directory Assistant on the server and proceed with the following options (note:
this configuration can also be accomplished using the command line tool NeST):
- This server your.host.name at 1.2.3.4 is using a permanent IP address and subnet. Choosing
the other option here prevents you from continuing. It is useful also prior to a reconfiguration
of a Mac OS X Server, in order to remove references to network domains and other values which
might change (such as IP address).
- This server will provide directory information to other computers. This creates a network
netinfo database.
- Enable LDAP support on this server (checked)
- Password and authentication information will be provided to other systems. This fires up
password server and sets the admin account to use the password server.
- Accept the default set of enabled encrypted authentication protocols
- Reboot
- Launch Workgroup manager, and connect to the server
- Make sure that you're operating in the network netinfo domain (choose "/Netinfo/root" from
the popout menu at the bottom left of the workgroup manager window. If you don't have that option,
try step 1 again. Also, you can use sudo NeST -getparentconfig to verify that Open Directory Assistant
did its job - if it did, it'll report itself as a netinfo and ldap parent.)
- Click the Sharing button, select the Users share point, and set it to automount to clients in
Netinfo/root dynamically, via afp.
- Click the Accounts button, and create an account which will be your network user.
- To provide the network home directory, set the network user's home to Network, select the
automounted Users share point (you have to click on it, grey highlight does not mean selected...),
and click Save.
- Before we can configure the client, we need to find the LDAP search base that the server is using.
We can find this in the /machines directory of the parent netinfo domain by executing the following
on the server:
[pimp:/etc] root# nicl / -list /machines
2 pimp.dreness.com
[pimp:/etc] root# nicl / -read /machines/pimp.dreness.com
name: pimp.dreness.com
ip_address: 216.231.49.47
serves: ./network pimp.dreness.com/local
suffix: dc=dreness,dc=com
First we get the exact machine name of the server as it exists in netinfo, then we list the
contents of that record. My search base in this example is dc=dreness,dc=com.
- Configure Directory Access on the client machine to include the network netinfo domain.
- Launch Directory access on the client machine, select LDAPv3, and click configure
- Click the disclosure triangle if necessary, then click "New..." to create a new entry
- Configuration Name = LDAP
- Server Name or IP Address = 1.2.3.4, --use your server's IP or hostname
- LDAP Mappings = Open Directory Server.
When prompted for the search base, use the results from the previous step (e.g. dc=dreness,dc=com).
- Click the Edit button if you have not already to reveal the LDAP timeout settings; change them to something a bit more reasonable.
This makes it less frustrating when it doesn't work as expected.
- Click "Use authentication when connecting",
and supply the credientials of your network user as follows: Distinguished Name: uid=username,cn=users,dc=dreness,dc=com
(where dc=dreness,dc=com is the search base you found from the previous step, and username is... well... you know ;). In the password
field, put the user's regular ol' password.
- Leave SSL off for now.
- Click OK until you return to the main Directory Access window
- Click the Authentication tab, choose "Custom Path" from the Search popout, click the Add... button,
and add the LDAP entry you just created to the search path
- Use Server Settings to verify that Guest Access is enabled for AFP
- At this point you should reboot the client and verify that you can log in as the network
user you created earlier with Workgroup Manager. The network user's home directory should be
created automatically; alternatively you can use sudo createhomedir -a on the server to pre-create it. Also,
though we have configured authenticated LDAP binding on the client, we have not yet disabled anonymous binding on the server
Creating a Certificate Authority, creating certificate requests, and signing the requests
A Certificate Authority allows us to sign ssl certificate requests, in lieu of paying for a real
ssl certificate from one of the various authorities (verisign, etc). Most of the ssl work involves
use of the openssl command; however, included with the OpenSSL distribution is a perl script called
CA.pl which simplifies the process a little. The following is a condensed version of
http://www.post1.com/home/ngps/m2/howto.ca.html:
- Create a directory in root's home directory called demoCA. Copy openssl.cnf and CA.pl into this directory:
[pimp:~] root# mkdir demoCA
[pimp:~] root# cp /System/Library/OpenSSL/openssl.cnf demoCA/
[pimp:~] root# cp /System/Library/OpenSSL/misc/CA.pl demoCA/
- Create a new Certificate Authority. When prompted, press enter to create a new authority. The
PEM pass phrase is required later to sign certificates with this authority. * * * Common Name should be
your server's fully qualified domain name * * *(e.g. pimp.dreness.com).
[pimp:~] root# cd demoCA/
[pimp:~/demoCA] root# ./CA.pl -newca
CA certificate filename (or enter to create) [enter]
Making CA certificate ...
Using configuration from /System/Library/OpenSSL/openssl.cnf
Generating a 1024 bit RSA private key
............................................++++++
.......++++++
writing new private key to './demoCA/private/cakey.pem'
Enter PEM pass phrase: [passphrase]
Verifying password - Enter PEM pass phrase: [passphrase]
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:US
State or Province Name (full name) [Some-State]:Washington
Locality Name (eg, city) []:Seattle
Organization Name (eg, company) [Internet Widgits Pty Ltd]:EarthGov
Organizational Unit Name (eg, section) []:dreness
Common Name (eg, YOUR name) []:pimp.dreness.com
Email Address []:dre@mac.com
- Create a certificate request. We could use CA.pl -newreq, but this generates an encrypted private key,
which isn't what we want, since this is intended to be used on an unattended server (I believe this would
require manually entering a passphrase to start up the ssl services). Instead, we'll create a new request
manually and use the -nodes option to openssl (which I believe is read "no des", as in DES encryption).
This means that you must securely store the resulting private key
contained in newreq.pem. Also, just press enter on the 'extra' attributes.
[pimp:~/demoCA] root# openssl req -new -nodes -keyout newreq.pem -out newreq.pem
Using configuration from /System/Library/OpenSSL/openssl.cnf
Generating a 1024 bit RSA private key
.............++++++
.............................................................................++++++
writing new private key to 'newreq.pem'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:US
State or Province Name (full name) [Some-State]:Washington
Locality Name (eg, city) []:Seattle
Organization Name (eg, company) [Internet Widgits Pty Ltd]:EarthGov
Organizational Unit Name (eg, section) []:dreness
Common Name (eg, YOUR name) []:pimp.dreness.com
Email Address []:dre@mac.com
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []: [enter]
An optional company name []: [enter]
[pimp:~/demoCA] root# ls
CA.pl demoCA newreq.pem openssl.cnf
- Next we sign the certificate with the demo certificate authority we've created. We
will be prompted for the PEM pass phrase; this is the one supplied when we created the
certificate authority.
[pimp:~/demoCA] root# ./CA.pl -sign
Using configuration from /System/Library/OpenSSL/openssl.cnf
Enter PEM pass phrase:
Check that the request matches the signature
Signature ok
The Subjects Distinguished Name is as follows
countryName :PRINTABLE:'US'
stateOrProvinceName :PRINTABLE:'Washington'
localityName :PRINTABLE:'Seattle'
organizationName :PRINTABLE:'EarthGov'
organizationalUnitName:PRINTABLE:'dreness'
commonName :PRINTABLE:'pimp.dreness.com'
emailAddress :IA5STRING:'dre@mac.com'
Certificate is to be certified until May 20 07:01:48 2004 GMT (365 days)
Sign the certificate? [y/n]:y
1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated
Signed certificate is in newcert.pem
[pimp:~/demoCA] root# ls
CA.pl demoCA newcert.pem newreq.pem openssl.cnf
Configuring SSL on the client and server
Okay, almost there. All that's left is to move the various ssl keys / authority files into their
proper homes, and tweak a couple config files to add references to the newly placed files.
On the server:
- Copy newreq.pem to /etc/openldap, and rename it to serverkey.pem. Also, secure this file
[pimp:~/demoCA] root# cp newreq.pem /etc/openldap/serverkey.pem
[pimp:~/demoCA] root# chmod 600 /etc/openldap/serverkey.pem
- Copy newcert.pem to /etc/openldap, calling it servercert.pem
[pimp:~/demoCA] root# cp newcert.pem /etc/openldap/servercert.pem
- Copy cacert.pem (inside the demoCA folder) to /etc/openldap
[pimp:~/demoCA] root# cp demoCA/cacert.pem /etc/openldap
- Edit /etc/openldap/slapd.conf to include the following three lines (I put them at the end):
TLSCACertificateFile /etc/openldap/cacert.pem
TLSCertificateFile /etc/openldap/servercert.pem
TLSCertificateKeyFile /etc/openldap/serverkey.pem
Also, insert the following line at the top of the file to require authenticated binding:
disallow bind_anon
- Kill the slapd process and restart it in debug mode so that it listens for secure connections in addition to
regular ones.
[pimp:~/demoCA] root# ps auxww | grep slap
root 1264 0.0 0.1 36820 840 ?? Ss 12:49PM 0:00.30 slapd
root 1815 0.0 0.0 1144 156 std R+ 4:24PM 0:00.00 grep slap
[pimp:~/demoCA] root# kill 1264
[pimp:~/demoCA] root# /usr/libexec/slapd -d1 -h "ldap:/// ldaps:///"
-d1 produces quite a bit of output, most of which is largly unintelligable to me :) You should see
'slapd starting' at the very bottom - this is a good sign. We'll leave it running in debug mode for now.
On the client:
- Copy the cacert.pem file from the server, and place it in /etc/openldap
andre@bish[~]sudo scp admin@pimp:/etc/openldap/cacert.pem /etc/openldap
Password:
admin@pimp's password:
cacert.pem 100% |************************************************************| 1289 00:00
- Edit /etc/openldap/ldap.conf to add the following:
TLS_CACERT /etc/openldap/cacert.pem
- Launch Directory Access again, and configure the LDAPv3 plugin
- Check the SSL checkbox for the LDAP configuration we created previously
That should do it :) Reboot the client and log in as the network user. You should see
a whole bunch of scrolling debug output from slapd as the login occurs. If you see any errors, that might be okay.. I have noticed
some lines which are apparently non-fatal errors. I've included a dump of the debug output from a functional
LDAP / ssl login, so that you may compare to mine (865 KB).
The last thing to do is edit the LDAP startup item so that it starts up able to service ldaps requests. This is
accomplished by editing the LDAP startup item, in /System/Library/StartupItems/LDAP. In the LDAP script, below
the line that contains "Startup LDAP Server", change slapd to slapd -h "ldap:/// ldaps:///". The StartService
block should appear as follows:
StartService ()
{
##
# Start up LDAP server
##
if [ "${LDAPSERVER:=-NO-}" = "-YES-" ]; then
if ! pid=$(GetPID slapd); then
ConsoleMessage "Starting LDAP server"
slapd -h "ldap:/// ldaps:///"
fi
fi
}
If you want to force SSL binding, then it should be slapd -h "ldaps:///"
Shutdown the client, reboot the server, boot the client, and log in as the network user to double-check everything.
That's it!
Footnotes
I should mention that I really don't know a whole lot about the inner workings of either LDAP or SSL (or cryptography
for that matter). These steps have been carefully crafted from my experience delivering Apple's
Mac OS X Server Administration & Integration course, and also from information I gathered about creating a certificate
authority. Anybody looking to incorporate this kind of stuff into a production environment would do well to test it heavily first. My testing setup is:
- Powermac G4 Dual 800 running Mac OS X Server, developed and tested in 10.2.4, tested from scratch in 10.2.6
- iBook G3 500, running Mac OS X 10.2.6
- Airport networking for the iBook
Some highly unscientific numbers: it takes around 30 seconds to log in as a network user from the iBook for the first time after a boot (the time from pressing return at the login screen
until the finder is finished loading). Subsequent logins in the same boot session take a little over 10 seconds. I'd like to say this might be faster
if the iBook were hardwired instead of on Airport, but when watching server bandwidth during login, the highest burst seems to be only about 8 KB/s...
(it's just challenge / response type stuff, so there shouldn't be a heavy network hit).
References:
http://www.bayour.com/LDAPv3-HOWTO.html
http://www.post1.com/home/ngps/m2/howto.ca.html
Comments or questions can be sent to me at dre@mac.com.
|