Skip to content
This repository has been archived by the owner on Feb 13, 2019. It is now read-only.

DesignDocument

Justin McWilliams edited this page Oct 17, 2014 · 2 revisions

(TODO: Add table of contents.)

Objective

The aim of Simian is to simplify management of third-party software on an enterprise Mac fleet.

Goals:

  • push new software packages.
  • patch preexisting software packages that may be out-of-date or vulnerable.
  • provide a self-service system for installing free and commercial third-party software on demand for Mac OS X.
  • replace the Apple Software Update Service for installing Apple provided patches for Mac OS X.
  • do all of the above for Macs that are not residing on the internal/corporate network and not connected via VPN.

Overview

The Simian system is used to install and patch software packages on Mac client machines. Client machines regularly check into the Simian server and request a manifest. The manifest tells which software to install, update or uninstall on the client machine.

Simian server runs on Google App Engine and uses Blobstore to serve software packages. This allows for client machines external to the internal/corporate network to be managed as long as they are connected to the Internet.


Simian Server / Google App Engine

The Simian server is the central component in the Simian solution, which runs on Google App Engine. The server is used for package deployment administration, reporting, and Simian client interaction (manifest, catalog, package, etc, downloading).

Scalability

App Engine provides a highly scalable environment for tens of thousands of Mac OS X machines. Load testing with 50,000 virtual Simian clients connecting hourly has revealed no issues. For substantially larger deployments, Simian client executions can be set to run less frequently, say every 2-3 hours, to reduce server load.

Redundancy & Reliability

App Engine has multi-homed front-end and back-end servers for maximum uptime. Google App Engine for Business has a 99.9% uptime service level agreement.

Furthermore, the new High Replication Datastore launched in early 2011 provides even higher Datastore uptime, including the elimination of scheduled read-only maintenance downtime. Simian will run on either the standard Datastore or High Replication Datastore, but HR is highly recommended.

Software Package Distribution

Initially, Simian only supports App Engine Blobstore for package storage since it is currently the best solution that fits desired needs, which can be accessed without being connected to an internal/corporate network. In a future iteration support for a secondary internal/corporate storage system may be added, permitting distribution of very large software packages in a bandwidth efficient manner when client machines reside to the internal/corporate network.

Blobstore

  • Access is directly from App Engine, so available from most Internet connections.
  • As a result of contents being served from App Engine, authentication is also under our control and avoids requesting/managing tokens between the Simian App Engine backend and other services.
  • Reasonable starting file size limits (2GB).

Munki Service URLs

This is where the Simian server differs greatly from a typical Munki server. Munki is designed to have static files hosted in expected paths on the server, where Simian dynamically generates many of these files - often on the fly - using Python.

If defined, the Munki client uses its configuration option SoftwareRepoURL as the base URL and appends /manifests/, /catalogs/, /pkgs/, etc.

URL Munki Config Method Client Use
/pkgsinfo/package-name N/A GET CLI Dupe verification, etc.
/pkgsinfo/package-name N/A PUT CLI Upload/update pkginfo plists. This will auto-generate catalogs. Will not complete if the package does not already exist.
/uploadpkg/ NA GET CLI Obtain the URL that software packages must be uploaded to.
/uploadpkg/ N/A POST CLI Upload a package and package info in one request.
/pkgs/package-name PackageURL GET Munki Fetch a package.
/manifests/manifest-name ManifestURL GET Munki Fetch manifests.
/manifests/manifest-name ManifestURL PUT CLI Upload/update manifests manually.
/catalogs/catalog-name CatalogURL GET Munki Fetch catalogs

Simian Client / Munki

As a basis for the client side of Simian, the open source tool Munki is used. Munki is written in Python/Py-Obj-C, which ships with Mac OS X, and has a fairly mature community of Mac admin consumers and open-source contributors.

Munki needs three important server side resources, which must be available through the HTTP protocol.

  • The catalog file contains a list of available software package and their meta information, like the name, the version numbers or the package size.
  • The manifest file which contains the names (without the version numbers) of the software packages which should be installed. The name of the manifest that should be used is stored client side in the Munki configuration plist.
  • The actual software packages. Not all installation packages can be used by Munki since vendors sometimes ignore Apples software distribution standards. Various workarounds exist to still make these packages compatible with Munki, such as repackaging.

Repackaging Software

There are cases where either software installation or version matching (for updates) fails due to issues with the software package provided by the vendor. One example of this is when vendors use nonstandard version schemes; for example where the version is set to "0.0.0.0" or "Build ###". Such packages will need to be repackaged for smooth use in Simian.

SSL Certificate Verification

Munki currently connects to any kind of HTTP/HTTPS server, and supports the ability to verify both the client and server certificate used during the SSL handshake.

However, given that Simian is to be deployed on App Engine, all likely Simian domains will be hosted at x.appspot.com and therefore use the same server certificate. The client can then not differentiate between YOURLEGITAPP.appspot.com and HACKER.appspot.com, should that attack arise. Therefore Simian includes a custom authentication protocol, on top of the already negotiated HTTPS connection, to fully authenticate the client and server.


Custom Authentication

  1. Client creates a client nonce (Cn; 128-bit random number) using a cryptographically secure random generator.
  2. Client requests access to Simian via HTTPS and sends the client nonce (Cn) with it.
  3. Server creates a server nonce (Sn; 128-bit random number) using a cryptographically secure random generator.
  4. Server concatenates the client and the server nonce and digitally signs it with its private key.
  5. Server sends the signature, the client and the server nonce as a response to the initial request to the client.
  6. Client verifies the client nonce and the signature with the known public key for the server.
  7. Client assembles a message containing the the expected machine certificate, the client and server nonce. It signs the message with the machine certificate.
  8. Client sends the message and the signature to the server.
  9. Server validates that the client certificate included in the message is signed with the expected CA’s key. If it is, it next verifies that the entire message was signed with that verified expected client certificate.
  10. Upon successful validation, server sends the client a cookie with X minute expiration, which will be used for subsequent requests in the near future.

Authentication URLs:

Server URL POST Input from Simian/Munki client Output from Simian Server
/auth n=Cn Sn + B64(SIGN(Cn + Sn))
/auth m=B64(cert + Cn + Sn)&s=B64(SIGN(m)) Set-Cookie: auth-token