Thursday 27 March 2014

DHCP Option Code Utility 1.1

I finally updated my DHCP Option Code Utility to make it compatible with Mountain Lion. This gets round a change Apple introduced (it had worked fine with Tiger, Leopard, Snow Leopard and Lion).

DHCP Option Code Utility makes it easy for mere mortals to generate the encoded values needed to define DHCP Option Codes for use with Apple's DHCP server. The most common uses of DHCP Option Codes are to define extra fields of information to advertise things like a VoIP phone system or a PXE Boot Server.

I also took the opportunity to add the ability to define 'null-terminate strings' as well as normal strings.

More details along with a download link can be found here.

http://jelockwood.blogspot.co.uk/2013/06/dhcp-server-on-os-x-server.html

[As a belated update to this post - I did sometime ago confirm that version 1.1 also works fine running in Mavericks, and that the DHCP server in Mavericks Server.app still accepts the same encoded values. Version 1.1 can therefore run on 10.4 all the way up to (currently) 10.9.2 and the values work with 10.5 Server through to Mavericks Server.app]

Sunday 16 March 2014

How to do VPN on Demand for iOS at zero cost despite Apple's best efforts to prevent this

Apple support a feature called 'VPN on Demand' despite the best efforts of both Apple and VirnetX to sabotage this. There are three main requirements in order to implement this.
  1. You need to use a supported VPN client which can either be the built-in Cisco IPSec client or a supported SSL VPN client
  2. You need to use certificates for authentication instead of a pre-shared-key
  3. You need to use a MDM (Mobile Device Management) solution to configure and push the settings to the client device (iOS or Mac) including the VPN on Demand settings
With regards to the VPN client it would seem you can therefore use the built-in Cisco IPSec VPN client on your iOS or Mac client, however as we shall see Apple have made this as difficult as possible to achieve. While some techies may prefer an SSL solution and it is certainly the case that Apple's built-in IPSec client is falling behind with regards to newer security standards e.g. IKEv2, I prefer using the built-in client as there is no extra cost for it, nothing extra needs to be installed and in theory being from Apple themselves it will always be compatible with the current OS version.

Before I go on to how to get this working despite Apple's best efforts, why do we want VPN on Demand? This can be for one of two reasons.
  1. To give access to an internal system that is not directly visible on the Internet and to do so in a way that is as seamless and automatic as possible in order to make things as easy as possible for users
  2. or to have a mobile device always route all traffic via a VPN connection so that its traffic is always protected even when using public WiFi hot-spots. By automating and enforcing this you avoid users forgetting to manually establish a VPN connection
The later reason is becoming more and more important these days with not only the threat of cyber-criminals but also Governments snooping on your traffic. So the goal is to have a compatible VPN server, a compatible VPN client and to configure things so that the VPN connection routes all traffic via it, and for the connection to be established completely automatically.

I could have bought a commercial VPN server from Cisco, Juniper, SonicWall, F5, Aruba or CheckPoint but this would have been very expensive. It is not possible to use Apple's own VPN server solution as it only supports PPTP or L2TP, this is despite the fact that Apple use the open-source Racoon software which does support using Cisco IPSec. I initially looked at compiling and installing the standard unmodified Racoon software in OS X but this would risk causing incompatibilities with Apple's own software so my first effort was to install and configure Racoon in an Ubuntu Linux virtual machine using Virtualbox. Total cost £0

I initially and successfully did so with a pre-shared-key (henceforth referred to as PSK) and then added authentication via LDAP to OpenDirectory running on a Mac server. Total cost so far £0

I then setup a self-signed rootCA and server certificate and client certificate using XCA. Total cost so far £0

Note: Apple's built-in VPN client requires that server certificates have the server name also in a subject alternative name field (SAN). While it is possible to do this using the command line openssl tool or Certificate Assistant in Keychain Access, life is made much easier with XCA.

I reconfigured Racoon to use certificates instead of a PSK and likewise the test iPhone I was using initially running iOS 7.0.4. I then hit the first Apple bug. If you modify a VPN configuration on the iOS device changing it from using IPSec with a PSK to IPSec with a certificate, even though all the details are correctly filled in it will fail to connect. This is because even though you have switched from PSK mode to certificate mode which hides the Cisco 'Group' field, it will still try and use the Cisco 'Group' field. As this is irrelevant for a certificate authenticated connection the VPN server will reject the connection due to being very confused. Nothing on the iPhone will give you a clue about this so I had to dig through debug logs on the Linux server to track this down. To work around this you must delete the old VPN configuration and create a fresh one. Once I had cracked this I was able to successfully get the iPhone to connect and use a certificate and username/password to connect. Total cost so far £0 plus a lot of my hair being pulled out.

At this stage we now have a Cisco IPSec compatible VPN server using a certificate, and the iOS device also using a certificate and the username/password being authenticated via OpenDirectory. In theory we are now ready to setup the MDM system. At this point as a diversion I also got StrongSwan working in another Ubuntu Linux virtual machine using the same certificates as another alternative Cisco IPSec compatible server. I did not get it working with LDAP to OpenDirectory at this point because the standard version 4.5.2 of StrongSwan for Ubuntu 12.04 is too old to enable this, but I did get it working with manually defined username/password details. StrongSwan 5 or later would be able to use LDAP authentication.

I already had a copy of Server.app and hence Apple's ProfileManager so I set it up and was able to successfully enrol my test iPhone and push profiles over the air to it. I was using the same self-signed rootCA, plus an additional server certificate but the same client certificate. So far however I am unable to get ProfileManager to push this certificate to the iPhone. As far as I am concerned there is nothing wrong with the certificates as the same client certificate works when emailed to the iPhone directly, and works for the VPN connection from the iPhone, and what's more works when pushed over-the-air from the free Cisco Meraki Systems Manager MDM solution. I therefore gave up on ProfileManager and switched to the free Cisco Meraki Systems Manager. I again enrolled the iPhone and created a profile in Systems Manager to push the client certificate to the iPhone and to also push a VPN configuration set to use that client certificate with a Cisco IPSec connection. This worked with a another major issue still to be resolved as we will see. Total cost so far £0 and the loss of some more hair.

Note: This certificate problem with ProfileManager may be a second Apple bug.

Having now successfully got a Cisco IPSec compatible VPN server working with certificates and successfully setup an MDM solution to push the settings to the iPhone I tested manual connections to the VPN server. This worked and I was able to enter and save and use the same OpenDirectory user credentials. However when I turned on VPN on Demand as part of the profile being pushed to the iPhone I discovered that the iPhone would not save the password, it would not let me edit the VPN configuration, there was also no way in the profile to define the password. As a result every time the VPN connection was told to connect I was asked again to re-enter the password. It turns out this is how currently it is 'supposed' to work. This makes it in not only my but many other peoples opinions an unusable solution for VPN on Demand. I personally consider this to be yet another Apple bug. (In Microsoft speak this would be described as a feature.)

Note: My Ubuntu Racoon VPN server had been configured to allow clients to save passwords and this had already been proven to work with manually configured VPN settings on the same iPhone.

I tried various options like an account with an empty password, not entering a username or %short name% in the VPN profile, even creating and manually editing a mobileconfig file with Xauth disabled. None of these options worked. It was beginning to look like I would have no choice but to pay for a commercial SSL VPN server.

I had when initially investigating this from the angle of 'how to do you save the password' found some discussions from other equally annoyed and frustrated Apple customers regarding this but none of these had listed a solution. By now I had gone as far as asking for a quote for an SSL VPN solution, however I did then find mention of something called Xauth-noauth for StrongSwan.

See http://serverfault.com/questions/476033/strongswan-without-password-on-ios

I found this when I switched to searching for how to connect without a username and password. As you can see other people have hit the same problem as I had. Fortunately someone (ecdsa) had come up with a solution which was to write a special Xauth module for use with StrongSwan which effectively ignores the Xauth details leaving just the certificate authentication active. With this the iPhone no longer asks for a password as it has not been asked by StrongSwan for one.

Note: There are normally two stages to authenticating a VPN connection, the first stage is either via a PSK or by exchanging and verifying SSL certificates, the second stage is eXtended AUTHentication or Xauth and is where the username and password are normally exchanged and verified.

I therefore dusted off my StrongSwan configured virtual machine. Unfortunately this Xauth-noauth module is only for StrongSwan 5.0.2 or later and as previously mentioned the standard version of StrongSwan for Ubuntu 12.04 is the much older and substantially different 4.5.2. As a pre-built StrongSwan 5 or later was not available for Ubuntu 12.04 I had to download the source code for StrongSwan 5.1.2 and build it myself along with all its dependencies. I was however able to do this and install it and thankfully it did exactly what was wanted and no longer asked the iPhone for a username and password. I was therefore able to use the VPN profile from the Systems Manager MDM with VPN on Demand enabled and the iPhone was now able to repeatedly connect without nagging me each time for the password! Yippee! Total cost so far - drum roll please - £0

Building StrongSwan 5.1.2 from scratch

First install dependencies

sudo apt-get install libpam0g-dev
sudo apt-get install libcurl4-openssl-dev
sudo apt-get install libcurl4-nss-dev
sudo apt-get install libldap2-dev
sudo apt-get install libgmp3-dev

Then download and uncompress source code

wget http://download.strongswan.org/strongswan-5.1.2.tar.bz2
tar -xjvf strongswan-5.1.2.tar.bz2

Then configure what modules to enable and compile and install (the configure command is all on a single line)

cd strongswan-5.1.2

./configure --prefix=/usr --sysconfdir=/etc --enable-curl --enable-ldap --enable-pkcs11 --enable-md4 --enable-openssl --enable-ccm --enable-gcm --enable-farp --enable-eap-identity --enable-eap-aka --enable-eap-aka-3gpp2 --enable-eap-md5 --enable-eap-gtc --enable-eap-mschapv2 --enable-eap-dynamic --enable-eap-radius --enable-eap-tls --enable-eap-ttls --enable-eap-peap --enable-eap-tnc --enable-xauth-eap --enable-dhcp --enable-charon --enable-xauth-pam --enable-xauth-noauth

sudo make
sudo make install

Here is the /etc/ipsec.conf I used for StrongSwan 5

# basic configuration

config setup
uniqueids=never

# Add connections here.

conn %default
authby=rsasig
leftrsasigkey=%cert
rightrsasigkey=%cert
keyingtries=1
keylife=60m
ikelifetime=240m

conn ios
keyexchange=ikev1
left=%defaultroute
leftsubnet=0.0.0.0/0
leftfirewall=yes
leftcert=serverCert.pem
right=%any
rightsubnet=10.0.1.0/24
rightsourceip=10.0.1.0/24
leftauth=rsa
rightauth=rsa
rightauth2=xauth-noauth
ike=aes128-sha1-modp2048,3des-sha1-modp1536
esp=aes128-sha1-modp2048,3des-sha1-modp1536
rekey=no
reauth=no
dpddelay=10
dpdtimeout=30
dpdaction=clear
auto=add

Update - 2014-09-13
After successfully running this StrongSwan VPN solution for several months with iPhone and iPad devices I discovered that users were unable to successfully connect over O2 cellular data connections, they were still able to connect over EE data, or WiFi connections. Narrowing down the circumstances was made more difficult by eliminating things like poor data connections, running out of data allowance, international roaming, confirming whether they  they were using WiFi or not. Clearly there was something different about the O2 network upsetting things as the EE and WiFi connections used the same settings and even the same devices. After spending sometime investigating this it would seem that the O2 data network has problems with the size of packets used. For example if you connect using a pre-shared-key (which works) this will be a fairly small packet as the pre-shared-key is a straight forward password, however when you connect using certificates a copy of the certificate has to be sent and this is much bigger and did not work. Fortunately this has been easy to fix, StrongSwan has a command called fragmentation that enables handling splitting larger packets in to smaller ones and this has solved this problem. To use this you need to add the following line to the /etc/ipsec.conf file as shown above.

fragmentation=yes

The last step was tweaking the rules for VPN on Demand. Both Apple's ProfileManager and Cisco Meraki System Manager have very limited options for VPN on Demand that can be configured in their GUI interfaces. In fact they are so limited that effectively they can only accomplish option 1 I listed at the beginning which is to automate providing access to an internal server, and not to automate connecting via VPN all the time for all traffic. Fortunately Apple do document how to manually configure this. Yes I know it is a big shock but Apple does still provide some useful documentation sometimes.

See page 40 https://developer.apple.com/library/ios/featuredarticles/iPhoneConfigurationProfileRef/iPhoneConfigurationProfileRef.pdf

Update 2017-01-11 it has been brought to my attention that the above link no longer works, that is Apple have removed that page. The nearest equivalent currently working link I can find is https://developer.apple.com/library/content/featuredarticles/iPhoneConfigurationProfileRef/Introduction/Introduction.html#//apple_ref/doc/uid/TP40010206-CH1-SW27

I therefore used iPhone Configuration Utility to build a mobileconfig profile containing the client certificate and the VPN settings, I then exported it and edited this as per Apple's documentation above to use the URLStringProbe option to check for the ability to access a URL on my VPN server and if found to be true to trigger a VPN connection. This might be opposite of what you would expect but it is the correct choice to force a connection always to happen and by doing it this way if my server is down the URL test will fail and VPN on Demand will not be activated and the device will still be usable although not protected by a VPN connection. You therefore need to use a URL that is accessible without a VPN connection. I then pushed this out to the iPhone using Systems Manager. With this installed my iPhone now as soon as it gets an Internet connection will automatically trigger a VPN connection which will route all traffic over it and all without any user interaction being needed. Grand total cost a massive £0!

As a final aside, all the above should apply equally to using Mac clients, testing this shall be my next project.

Links to Resources

VirtualBox or ESXi 5.1
Ubuntu 12.04 Server
StrongSwan 5.1.2
Cisco Meraki Systems Manager
XCA
iPhone Configuration Utility 3.5 for Mac

Saturday 15 March 2014

Deploying Sophos Anti-Virus on a Mac network

Sophos have provided a Mac version of their Anti-Virus software for a long time and uniquely also used to provide a Mac tool for providing an internal corporate deployment and update service for this.

This tool was called 'Sophos Update Manager' (SUM) it did two things. Firstly it let you build a pre-configured installer package which would include the settings telling Mac clients how to get updates, and secondly it would automatically update this install and folder, it would also put in this folder new anti-virus definitions.

You would therefore normally have this folder on a Mac file server and have the installer package and hence client Macs configured to get updates from this folder. You could also define Sophos' own servers as the backup - secondary source for updates.

This solution was therefore comparable with Sophos' own Windows tools of in the past Sophos Library Manager and now Sophos Enterprise Console, and also comparable with equivalent Windows only tools from McAfee and Symantec. The big difference being that no-one else makes a similar Mac tool for Mac only environments.

In more recent times Sophos have failed to update SUM and officially it only runs on OS X 10.7 (Lion) or older, it did however continue to be able to distribute updates for Sophos Anti-Virus 8 for Macs even if client Macs were running Mountain Lion. However not only does SAV8 not officially support running on OS X 10.9 (Mavericks) SAV8 is also due to be discontinued in April 2014.

 It is therefore necessary to move all Macs to SAV9 by April 2014.

SUM does not support SAV9 and so far Sophos have shown no interest in providing an updated version. Sophos do provide a standalone installer for SAV9 which will automatically if needed uninstall SAV8 and replace it with SAV9, and this installer can be pre-configured with the credentials needed to get updates directly from Sophos' servers.

See http://www.sophos.com/en-us/support/knowledgebase/119744.aspx

You might think therefore that all one needs to do is download the standalone SAV9 installer, pre-configure it as per the above article and then deploy it to all your Macs. Unfortunately the standalone SAV9 installer is not a standard Apple installer type package, it is an application that itself does the installation. This means it cannot be deployed using standard Apple administration tools like Apple Remote Desktop, Casper, or Munki. All these tools will merely see it as an application and at best just copy it to a client Macs Applications folder where it will just sit and do nothing.

As a reminder, the SAV8 installer was a standard installer package and after being configured using SUM could be deployed using standard Mac tools.

What was really annoying is that as someone who has also managed both Windows only and mixed environments with Sophos I happen to know that SAV9 when managed by Sophos Enterprise Console on a Windows server does still come as a standard Apple installer package.

Sophos technical support were not a lot of help regarding this and frankly seem pretty clueless about how Mac software is deployed in an enterprise environment. They suggested switching to Sophos Cloud. Sophos Cloud can be thought of as being a cloud based version of Sophos Enterprise Console in that it lets you manage settings and view the status of the client computers running Sophos Anti-Virus, and unlike the Sophos Enterprise Console can be accessed via a web-browser on a Mac. However the client installer used with Sophos Cloud for Mac is still the same custom application and not a standard Apple installer package, as such it still cannot be deployed using standard Mac administration tools.

As an aside the free home edition of Sophos Anti-Virus for Mac is also based on the same custom application.

So at this point the only official options were to buy a Windows Server just so you could run Sophos Enterprise Console, something that would have cost a fortune even if you run it in a virtual machine as you not only would have to buy Windows Server but also all the Client Access Licenses for all your Macs, or you would have to go round each and every Mac client and manually run the standalone installer application with the huge administrative overhead this entails and the often frequent difficulty to get access to machines.

Clearly this had moved Sophos from being by far the most friendly Mac solution thanks to SUM, to being actually worse than most since at least McAfee with their ePO system use standard Apple installer packages.

I raised this issue in some user forums including here https://jamfnation.jamfsoftware.com/discussion.html?id=9785 and also pursued this matter directly with another contact I had at Sophos. Via that contact I was able to find out that hidden inside the Sophos standalone installer application was a command line tool called InstallationDeployer and that this tool could be scripted and run via a standard Unix shell script. With this information which is still not on the Sophos website now listed at http://www.sophos.com/en-us/support/knowledgebase/14179.aspx, it then immediately became obvious that it would be possible to build an Apple installer package containing the Sophos standalone installer application and a post-install script which would automate running the Sophos standalone installer.

After updating the above forum with this information I had started building such an installer package but Richard Trouton beat me to it and to be honest his solution is cleaner than the one I was building. Richard has written this up here http://derflounder.wordpress.com/2014/02/20/deploying-sophos-anti-virus-for-mac-os-x-9-x/ however Richard's script only works with the free home edition of Sophos Anti-Virus for Mac which would have been the only version he had access to. I have therefore taken his script and enhanced it so that it works for both the free home edition and also the paid-for official SAV9 standalone installer.

Update - SAV 9.2.x now stores the auto-update credentials outside the Sophos installer application in a separate folder. This means I had to modify my script to copy both the installer application and this folder, I did this by putting both the Sophos installer and their settings folder inside another folder. This folder (of both items) gets copied to the client Mac and my scripts looks inside the folder and then inside the Sophos installer to find and run the Sophos commandline tool to do the actual installation. If you look at my further updated script you will see the name of the folder that you must use or otherwise you need to modify my script to the name of the folder you have chosen.

My updated version of the script can be accessed here http://pastebin.com/uRT2VMw9
My further updated version of the script which now supports SAV 9.2.x is here http://pastebin.com/0EYi7V4c

Note: The free home edition is not authorised for business use, only for home use.

So if you have no Windows server and need to mass deploy Sophos Anti-Virus 9 for Mac the best solution is as follows.
  1. Download the SAV9 standalone installer
  2. Pre-configure it with your Sophos update credentials as per the Sophos article
  3. Convert it to an Apple installer package as per Richard's article but with my version of his script
  4. Deploy it using your favourite tool - ARD, Casper, Munki, or other
You don't need to keep building new versions of the installer as once installed the client Macs will then update themselves directly from the Sophos servers.