How To Allow MacOS X 10.4, 10.5, and 10.6 Client Computers To Update Against a MacOS X 10.6 Sofware Update Server Using a Single Common URL

UPDATE: There is an Apple support doc that covers this subject. The document covers a few other different techniques of doing this: http://support.apple.com/kb/HT4069

————

UPDATE 2: The Apple support doc mentioned above lists a solution using Apache mod_rewrite. That was the solution I needed to work since it allows for this change to be completely server-side and I wouldn’t need to touch my clients. Unfortunately after making the suggested changes mentioned in the support doc, upon restart of my Software Update Service, all those changes were automatically deleted by the service. The service appears to automatically delete any customized changes you make outside of the GUI interface. This is similar to behavior I have noticed with the web service and trying to make direct changes to its Apache conf files instead of using the Server Admin app.

————

Update 3: To make the Apple support doc recommended Apache mod_rewrite changes stick, you need to also add the lines to the “template” swupd.conf file located at /System/Library/PrivateFrameworks/SUServer.framework/Versions/A/Resources/swupd.conf

Problem Description

In an Open Directory setup that supports multiple different versions of MacOS X and where you are pointing the client computers to a local MacOS X 10.6 Software Update server, according to Apple you need to specify a different update server URL for MacOS X 10.4, 10.5, and 10.6 clients. This poses a problem because if all of the other Open Directory preferences that you are pushing out to clients are the same, the unique Software Update Server URL requirement will require you to create a separate computer group for computers of each MacOS X version. This will result in you having to triple all of your computer groups and preference settings on those groups just for this one setting. Very inefficient.

Solution

Each of the unique MacOS X software update URLs you are supposed to use loads a unique XML file containing the list of updates for the version of MacOS X the XML file is for. So you need to create a single URL that can return the correct XML file based on the version of MacOS X on the client computer that loads the URL. This can be accomplished by creating a PHP script that detects the MacOS X version of the client computer loading the URL and return the contents of the correct XML file that is needed.

The Software Update agent on MacOS X computers is basically just a web client that accesses the Software Update Service URL using standard HTTP protocols. If you look at the Software Update Service access logs, you can see the information that clients send to the server in the request headers. One of those pieces of information sent to the Software Update Service is the operating system version. So once you know this, you just need a PHP script that parses out the Software Update agent request header looking for the operating system version. Then the PHP script returns the correct XML file for the client operating system. Here is a sample of what a MacOS X 10.6 client computer’s software update agent header file looks like in the Max OS X 10.6 server access log file:

softwareupdate.mydomain.com 192.168.1.234 - - [02/Apr/2010:16:23:25 -0400] "GET /index-leopard-snowleopard.merged-1.sucatalog HTTP/1.1" 200 1238893 "-" "Software%20Update/254 CFNetwork/454.4 Darwin/10.0.0 (i386) (MacBook2%2C1)"

The operating system information from that log entry is:

Darwin/10.0.0

Here are the steps to set this up:

1. Enable the web service on the MacOS X 10.6 Software Update Server. You can leave the default website running on the default service port (TCP 80), but it would be better, security-wise, to change it to something else like TCP 8089.

2. Enable the PHP module in the website so that you can run PHP scripts.

3. Delete the default web service web content files in the directory /Library/WebServer/Documents/

4. Create the PHP file at this location and with the following contents /Library/WebServer/Documents/update.php (hopefully WordPress doesn’t mangle the code below):

<?php
$userAgent =  $_SERVER['HTTP_USER_AGENT'];
 
// MacOS X 10.6
$osSubstringSnowLeopard = 'Darwin/10.';
$fileSnowLeopard = "/var/db/swupd/html/content/catalogs/others/index-leopard-snowleopard.merged-1.sucatalog";
 
// MacOS X 10.5
$osSubstringLeopard = 'Darwin/9.';
$fileLeopard = "/var/db/swupd/html/content/catalogs/others/index-leopard.merged-1.sucatalog";
 
// NonLeopard (10.4-)
$filePreLeopard = "/var/db/swupd/html/content/catalogs/index.sucatalog";
 
if( strrpos( $userAgent, $osSubstringSnowLeopard ) )
  $contents = file($fileSnowLeopard);
elseif ( strrpos( $userAgent, $osSubstringLeopard ) )
  $contents = file($fileLeopard);
else
  $contents = file($filePreLeopard);
 
$string = implode($contents);
echo $string;
?>

5. Configure the Software Update Server URL in your Open Directory preferences for your client computers to be:

http://softwareupdate.mydomain.com:8089/update.php

6. Done.

How to Install an ipsCA SSL Certificate in OS X

ipsCA is a company that sells SSL certificates. Their SSL certificates are recognized by all the major browsers so you don’t need to worry about manually installing additional Certificate Authority (CA) certificates into your users’ web browsers like you have to do with CA companies whose certificates are not included by default in the major web browsers. What is great about ipsCA is that they offer free 2 year SSL certificates for educational institutions such as Universities. If your domain ends in .edu then you qualify for a free 2 year SSL certificate.

ipsCA certificates are a little unusual in that you need to install two certificates onto your server before it will work. I couldn’t find a documented set of procedures for installing ipsCA certificates on a MacOS X 10.4 server so I wrote some up:

Installing an ipsCA SSL Certificate in OS X 10.4

Generate the CSR

  1. In Server Admin, select the server you would like to secure.
  2. Click “Settings” > “Certificates” tab > “Add(+)” button.
  3. A dialog box will appear to enter your certificate information. Please refer to vs7313 for detailed CSR requirements.
  4. Enter starting and ending validity dates.
  5. Select private key bit length size (1024 is recommended and required for three year certificates)
  6. Enter a passphrase (“password”) for your private key.
    • Apple recommends “use at least 20 characters, include mixed case, numbers and/or punctuation, have no characters repeat, and having no dictionary terms.”
  7. Click “Save”. Now, “Request Signed Certificate From CA” can be selected.
  8. A dialog box will appear. Drag the certificate icon onto your desktop. This will create your CSR file.
  9. copy and paste the text of the CSR file into the certificate request form on the ipsCA website.
  10. Submit the request and wait for ipsCA’s email response.

Import the Signed Certificate

  1. In Server Admin, select the server the certificate needs to go on.
  2. Click “Settings” > “Certificates” tab
  3. Highlight the certificate the signed certificate corresponds to.
  4. Click the “edit” icon.
  5. Click the “Add Signed Certificate…” button.
  6. Paste the contents of the signed certificate text file you received from ipsCA into the text box that appears. Press OK to import the signed certificate.
  7. Quit and restart the Server Admin app to make sure it refreshes the status of the signed certificate.
  8. When you try to edit the certificate all the fields should be greyed out to indicate the certificate is signed and the import was successful.
  9. You may need to redesignate the newly signed certificate in the web server and/or restart it before Apache will start using the newly signed certificate.

Install the ipsCA Intermediate Certificates

1. Copy the ipsCA intermediate certificates bundle file into the /etc/certificates/ directory on the web server. At the time of this writing this file was named “IPS-IPSCABUNDLE.crt. The file is available on the ipsCA website.

2. Change the permissions on the certificate bundle to “640”.

  • cd /etc/certificates
  • sudo chmod 640 IPS-IPSCABUNDLE.crt

3. Navigate to the folder /etc/httpd/sites/ and locate the .conf file that corresponds to the the SSL virtual host that the certificate belongs to. Usually the filename of the .conf file will be named in the format “someNumber_IPAddress_443_fullyQualifiedHostName.conf”

4. Once you locate the file, open it in a text editor at locate the part of the virtual host section that covers the SSL certificate settings. The section you are looking for will look something like this:

SSLEngine On
SSLLog "/var/log/httpd/ssl_engine_log"
SSLCertificateFile "/etc/certificates/www.foo.com.crt"
SSLCertificateKeyFile "/etc/certificates/www.foo.com.$
SSLCipherSuite "ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:+LOW:!SSLv2:+EXP$

5. Add the following setting in between the “SSLCertificateKeyFile” and “SSLCipherSuite” setting:

SSLCertificateChainFile /etc/certificates/IPS-IPSCABUNDLE.crt
  • When you are done the certificate section should looking something like this:
SSLEngine On
SSLLog "/var/log/httpd/ssl_engine_log"
SSLCertificateFile "/etc/certificates/www.foo.com.crt"
SSLCertificateKeyFile "/etc/certificates/www.foo.com.$
SSLCertificateChainFile /etc/certificates/IPS-IPSCABUNDLE.crt
SSLCipherSuite "ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:+LOW:!SSLv2:+EXP$

6. Save your changes and restart the web service. You should now be able to navigate to your SSL website and receive no “invalid” certificate errors. You can test your web server by using the ipsCA test website at: http://certs.ipsca.com/checkserver/

SSL Certificate