I recently installed a fresh version of Lion Server after attempting to fix a broken upgrade. With some help from others, I've managed to get all the new features working and have kept notes, having found that many or most of the necessary installation steps for both the OS and its services are almost entirely undocumented. When you get them working, they work great, but the entire process is very fragile, with simple setup steps causing breaks or even malicious behaviors. In case this is useful to others, here are my notes.
Start with an erased, virgin, single guid partitioned drive. Not an upgrade. Not simply a repartitioned drive. Erased. Clean. Anything else can and probably will break the Lion Server install, as I discovered myself more than once. Before erasing my drive, I already had Lion and made a Lion install DVD from instructions widely available on the web. I suppose you could also boot into the Lion recovery partition and use disk utility to erase the OS X partition then install a new partition, but I cut a DVD. The bottom line is to erase any old OS partitions. And of course to have multiple, independent backups: I use both Time Machine with a modified StdExclusions.plist and Carbon Copy Cloner.
Also, if you will be running your own personal cloud, you will want to know your domain name ahead of time, as this will be propagated everywhere throughout server, and changing anything related to SSL on Lion Server is a nightmare that I haven't figured out. If you don't yet have a domain name, go drop ten dollars at namecheap.com or wherever and reserve one before you start. Soemday someone will document how to change this stuff without breaking Lion Server, but we're not there yet. I'll assume the top-level domain name "domain.com" here.
Given good backups, a Lion Install DVD (or Recovery Partition), and a domain name, here are the steps, apparently all of which must be more-or-less strictly followed in this order.
- DVD>Disk Utility>Erase Disk [or Recovery Partition>Disk Utility>Erase Partition]
- DVD>Install Lion
- Reboot, hopefully Lion install kicks in
- Update, update, update Lion (NOT Lion Server yet) until no more updates
- System Preferences>Network>Static IP on the LAN (say 10.0.1.2) and Computer name ("server" is a good standbye)
- Terminal>$ sudo scutil --set HostName server.domain.com
- App Store>Install Lion Server and run through the Setup
- Download install Server Admin Tools, then update, update, update until no more updates
- Server Admin>DNS>Zones [IF THIS WASN'T AUTOMAGICALLY CREATED (mine wasn't): Add zone domain.com with Nameserver "server.domain.com." (that's a FQDN terminated with a period) and a Mail Exchanger (MX record) "server.domain.com." with priority 10. Add Record>Add Machine (A record) server.domain.com pointing to the server's static IP. You can add fancier DNS aliases and a simpler MX record below after you get through the crucial steps.]
- System Prefs>Network>Advanced>Set your DNS server to 127.0.0.1
- A few DNS set-up steps and these most important steps:
- A. Check that the Unix command "hostname" returns the correct hostname and you can see this hostname in Server.app>Hardware>Network
- B. Check that DNS works: the unix commands "host server.domain.com" and "host 10.0.1.2" (assuming that that's your static IP) should point to each other. Do not proceed until DNS works.
- C. Get Apple Push Notification Services CA via Server.app>Hardware>Settings><Click toggle, Edit... get a new cert ...>
- D. Server.app>Profile Manager>Configure... [Magic script should create OD Master, signed SSL cert]
- E. Server.app>Hardware>Settings>SSL Certificate> [Check to make sure it's set to the one just created]
- F. Using Server.app, turn on the web, then Server.app>Profile Manager> [Click on hyperlink to get to web page, e.g. server.domain.com/profilemanager] Upper RHS pull-down, install Trust Profile
- G. Keychain Access>System>Certificates [Find the automatically generated cert "Domain", the one that is a "Root certificate authority", Highlight and Export as .cer, email to all iOS devices, and click on the authority on the device. It should be entered as a trusted CA on all iOS devices. While you're at it, highlight and Export... as a .cer the certificate "IntermediateCA_SERVER.DOMAIN.COM_1", which is listed an an "Intermediate CA" -- you will use this to establish secure SSL connections with remote browsers hitting your server.]
- H. iOS on LAN: browse to server.domain.com/mydevices> [click on LHS Install trust cert, then RHS Enroll device.
- I. Test from web browser server.domain.com/mydevices: Lock Device to test
- J. ??? Profit
You are now ready to begin turning on your services. Here are a few important details and gotchas setting up cloud services.
Server Admin>Firewall>Services> Open up all ports needed by whichever services you want to run and set up your router (assuming that your server sits behind a router) to port forward these ports to your router's LAN IP. This is most a straightforward exercise in grepping for the correct ports on this page, but there are several jaw-droppingly undocumented omissions of crucial ports for Push Services and Device Enrollment. If you want to enroll your iOS devices, make sure port 1640 is open. If you want Push Notifications to work (you do), then ports 2195, 2196, 5218, and 5223 must be open. The Unix commands "lsof -i :5218" and "nmap -p 5218 server.domain.com" (nmap available from Macports after installing Xcode from the App Store) help show which ports are open.
Do this with strong security. Server.app to turn on remote logins (open port 22), but edit /etc/sshd_config to turn off root and password logins.
I'm note sure if toggling the Allow remote logins will load this config file or, run "sudo launchctl unload -w /System/Library/LaunchAgents/org.openbsd.ssh-agent.plist ; sudo launchctl load -w /System/Library/LaunchAgents/org.openbsd.ssh-agent.plist" to restart the server's ssh daemon.
Then use ssh-keygen on remote client to generate public/private keys that can be used to remotely login to the server.
client$ ssh-keygen -t rsa -b 2048 -C client_name
[Securely copy ~/.ssh/id_rsa.pub from client to server.]
server$ cat id_rsa.pub > ~/.ssh/known_hosts
I also like DenyHosts, which emails detected ssh attacks to firstname.lastname@example.org. It's amazing how many ssh attacks there are on any open port 22. Not really an added security feature if you've turned off password logins, but good to monitor. Here's a Lion Server diff for the config file /usr/share/denyhosts:
$ diff denyhosts.cfg-dist denyhosts.cfg
< SECURE_LOG = /var/log/secure
> #SECURE_LOG = /var/log/secure
> SECURE_LOG = /var/log/secure.log
< HOSTS_DENY = /etc/hosts.deny
> #HOSTS_DENY = /etc/hosts.deny
> # Mac OS X Lion Server
> HOSTS_DENY = /private/etc/hosts.deny
< LOCK_FILE = /var/lock/subsys/denyhosts
> #LOCK_FILE = /var/lock/subsys/denyhosts
> LOCK_FILE = /var/denyhosts/denyhosts.pid
< ADMIN_EMAIL =
> ADMIN_EMAIL = email@example.com
User Server.app to create your network accounts; do not use Workgroup Manager. If you use Workgroup Manager, as I did, then your accounts will not have email addresses specified and iCal Server WILL NOT COMPLETELY WORK. Well, at least collaboration through network accounts will be handled clunkily through email, not automatically as they should. If you create a network account using Workgroup Manager, then edit that account using Server.app to specify the email to which iCal invitations may be sent. Server.app doesn't say anything about this, but that's one thing that email address entry is used for. This still isn't quite solid on Lion Server, as my Open Directory logs on a freshly installed Lion Server are filled with errors that read:
2011-12-12 15:05:52.425 EST - Module: SystemCache - Misconfiguration detected in hash 'Kerberos':
User 'uname' (/LDAPv3/127.0.0.1) - ID 1031 - UUID 98B4DF30-09CF-42F1-6C31-9D55FE4A0812 - SID S-0-8-83-8930552043-0845248631-7065481045-9092
Email aliases are handled with the file /private/etc/postfix/aliases. Do something like this
Then run "sudo newaliases". If your ISP is Comcast or some other large provider, you probably must proxy your outgoing mail through their SMTP servers to avoid being blocked as a spammer (a lot of SMTP servers will block email from Comcast/whatever IP addresses that isn't sent by Comcast). Use Server.app>Mail to enter your account information. Even then, the Lion Server default setup may fail using this proxy. I had to do this with the file /private/etc/postfix/main.cf:
sudo cp ./main.cf ./main.cf.no_smtp_sasl_security_options
sudo echo 'smtp_sasl_security_options = noanonymous' >> ./main.cf
sudo serveradmin stop mail
sudo serveradmin start mail
Finally, make sure that you're running a blacklisting srevice yourself! Server Admin>Mail>Filter> Use spamhaus.org as a blacklister. Finally, set up mail to use strong Kerberos/MD5 settings under on Server Admin>Mail>Advanced. Turn off password and clear logins. The settings should be set to "Use" your SSL cert, NOT "Require". "Require" consistently breaks things for me.
If you already installed the server's Trust Certificate as described above (and opened up the correct ports), email to your account should be pushed out to all clients.
Server.app>Calendar>Turn ON and Allow Email Invitations, Edit... . Whatever you do, do NOT enter your own email account information in this GUI. You must enter the account information for local user com.apple.calendarserver, and the password for this account, which is stored in the System keychain: Keychain Access>System> Item com.apple.servermgr_calendar. Double-click and Show Password, copy and paste into Server.app dialog. This is all described in depth here. If you enter your own account information here (DO NOT!), the iCal Server will delete all Emails in your Inbox just as soon as it reads them, exactly like it works for user com.apple.calendarserver. Believe me, you don't want to discover this "feature", which I expect will be more tightly controlled in some future update.
The functionality of Server.app's Web management is pretty limited and awful, but a few changes to the file /etc/apache2/httpd.conf will give you a pretty capable and flexible web server, just one that you must manage by hand. Here's a diff for httpd.conf:
$ diff httpd.conf.default httpd.conf
< #LoadModule ssl_module libexec/apache2/mod_ssl.so
> LoadModule ssl_module libexec/apache2/mod_ssl.so
< #LoadModule php5_module libexec/apache2/libphp5.so
> LoadModule php5_module libexec/apache2/libphp5.so
< #LoadModule auth_digest_apple_module libexec/apache2/mod_auth_digest_apple.so
< #LoadModule encoding_module libexec/apache2/mod_encoding.so
> LoadModule auth_digest_apple_module libexec/apache2/mod_auth_digest_apple.so
> LoadModule encoding_module libexec/apache2/mod_encoding.so
< #LoadModule xsendfile_module libexec/apache2/mod_xsendfile.so
> LoadModule xsendfile_module libexec/apache2/mod_xsendfile.so
< ServerAdmin firstname.lastname@example.org
> ServerAdmin email@example.com
< #ServerName www.example.com:80
> ServerName domain.com:443
> # Server-specific configuration
> # sudo apachectl -D WEBSERVICE_ON -D MACOSXSERVER -k restart
> Include /etc/apache2/mydomain/*.conf
I did "sudo mkdir /etc/apache2/mydomain" and add specific config files for various web pages to host. For example, here's a config file that will host the entire contents of an EyeTV DVR, all password controlled with htdigest ("htdigest ~uname/.htdigest EyeTV uname"). Browsing to https://server.domain.com/eyetv points to /Users/uname/Sites/EyeTV, in which there's an index.php script that can read and display the EyeTV archive at https://server.domain.com/eyetv_archive. If you want Apache username accounts with twiddles as in https://server.domain.com/~uname, specify "UserDir Sites" in the configuration file.
Alias /eyetv /Users/uname/Sites/EyeTV
Require user uname
Options Indexes MultiViews
Allow from all
Alias /eyetv_archive "/Volumes/Macintosh HD2/Documents/EyeTV Archive"
<Directory "/Volumes/Macintosh HD2/Documents/EyeTV Archive">
Require user uname
Options Indexes MultiViews
Allow from all
I think you can turn Web off/on in Server.app to relaunch apached, or simply "sudo apachectl -D WEBSERVICE_ON -D MACOSXSERVER -k restart".
Securely copy to all desired remote clients the file IntermediateCA_SERVER.DOMAIN.COM_1.cer, which you exported from System Keychain above. Add this certificate to your remote keychain and trust it, allowing secure connections between remote clients and your server. Also on remote clients: Firefox>Advanced>Encryption>View Certificates>Authorities>Import...> Import this certificate into your browser. Now there should be a secure connection to https://server.domain.com without any SSL warnings.
One caveat is that there should be a nice way to establish secure SSL to https://domain.com and https://www.domain.com, but the automagically created SSL certificate only knows about server.domain.com. I attempted to follow this advice when I originally created the cert and add these additional domains (under "Subject Alternate Name Extension"), but the cert creation UI failed when I did this, so I just gave up. I hope that by the time these certs expire, someone posts some documentation on how to manage and change Lion Server SSL scripts AFTER the server has been promoted to an Open Directory Master. In the meantime, it would be much appreciated if anyone can post either how to add these additional domain names to the existing cert, or generate and/or sign a cert with a self-created Keychain Access root certificate authority. In my experience, any attempt to mess with the SSL certs automatically generated just breaks Lion Server.
Finally, if you don't want a little Apple logo as your web page icon, create your own 16×16 PNG and copy it to the file /Library/Server/Web/Data/Sites/Default/favicon.ico. And request that all web-crawling robots go away with the file /Library/Server/Web/Data/Sites/Default/robots.txt:
VNC easily works with iOS devices -- use a good passphrase. Edit /System/Library/LaunchDaemons/org.postgresql.postgres.plist and set "listen_addresses=127.0.0.1" to allow PostgreSQL connections over localhost. I've also downloaded snort/base/swatch to build an intrusion detection system, and used Macports's squid+privoxy to build a privacy-enhanced ad-blocking proxy server.