Jamf Pro in a Virtual Box

Jamf Pro in a Virtual Box


Jamf Pro server can be a funny and fickle beast. When testing different policies that are unique or upgrading to a new version of Jamf Pro, it’s best not to try it on the production server first. Sometimes the process of testing a new release or beta can easily break, and having an automated process to quickly rebuild a macOS test environment can save you tons of time and frustration. These instructions are built using macOS but the methodology might be able to be applied to other operating systems.


To get started there is a few tools that are needed for the process.

AutoDMG and CreateUserPkg are tools developed by Per Olofsson. AutoDMG builds a never-booted disk image that can be used to image Macs. To build the image it uses the latest macOS installer to find any updates that need to be applied and any custom packages. CreateUserPkg creates packages to deploy macOS user accounts.

vfuse is a open source command line tool developed by Joseph Chilcote. vfuse takes a disk image and converts it to a virtual machine for use in VMware Fusion.

Configure Jamf Pro is a script that I wrote that to mimic the Jamf Pro installer process, but without all the prompts. The script will configure and start both MySQL and Tomcat. To configure MySQL, I needed to know what the admin password was without prompting the user. I found that when I removed /usr/local/mysql/data/mysql/db.frm and ran the initialize command again, MySQL would create a new password and return it. With the password in hand I can set the root password for MySQL and configure the database to the specifications of Jamf Pro. For Tomcat, I had to create the self-signed certificate that the computer uses to authenticate to the Jamf Pro server. Tomcat also needed some specific logging directories to be created before it would start.

Building Jamf Pro in a Virtual Box

Step 1: Download and create packages

Before we can build an image we will need to download and create a few custom packages:

Most of these packages you can download from the above links. There are a few packages that will need to be created from scratch. Java Cryptography Extension (JCE) & MySQL are packages that will need a custom installer and be recreated with each new release. The MySQL installer calls System Events to display a dialog box of the admin password. The post install script has to be removed, then the contents of the MySQL package need to be recreated. When the Configure Jamf Pro script runs, it recreates the admin password for the MySQL Server. The Java JCE doesn’t need any additional customization, the files just need to be put into a package for installation.

To create a flat package we will be using pkgbuild. pkgbuild is a system utility that you can use to build basic installer packages.

Topher% pkgbuild -h
Usage: pkgbuild [options] --root  [--component-plist ] 
	Build a package from an xcodebuild destination root

Usage: pkgbuild --analyze --root  
	Create template component plist from an xcodebuild destination root

Usage: pkgbuild [options] {--component } 
	Build a package from one or more previously-built bundles

See pkgbuild(1) for details.
  1. Create a directory that will serve as the project directory for this package.
    topher$ mkdir AppleSetupDone_Package
  2. Inside of the project directory create another file but this time call it ROOT.
    topher$ mkdir ROOT
  3. Build out the directory structure to match where the files will go when installed.
    topher$ mkdir -p AppleSetupDone_Package/var/db
  4. Place the files that need to be installed into the directories.
    topher$ touch .AppleSetupDone
    topher$ ls -al
    total 0
    drwxr-xr-x  3 root  wheel  102 Jan 18  2017 .
    drwxr-xr-x  4 root  wheel  136 Jan 18  2017 ..
    -rw-r--r--  1 root  wheel    0 Jan 18  2017 .AppleSetupDone
  5. Include any pre- and post-flight install scripts that need to be executed during installation. However, we won’t need any for this package.
  6. Change the permissions on the ROOT  folder inside of the project folder to be owned by the root user.
    topher$ chown -R root:wheel ROOT/
    topher$ ls -al
    total 32
    drwxr-xr-x   5 u0495452  staff   170 Aug  8 15:31 .
    drwxr-xr-x  44 u0495452  staff  1496 Aug 11 15:22 ..
    drwxr-xr-x   4 root      wheel   136 Jan 18  2017 ROOT
  7. Build the package using this command:
    pkgbuild –root ROOT –identifier com.your.domain.applesetupdone –version xx AppleSetupDone.pkg

    topher$ pkgbuild --root ROOT --identifier edu.utah.applesetupdone --version 1.0 AppleSetupDone.pkg
    pkgbuild: Inferring bundle components from contents of ROOT
    pkgbuild: Wrote package to AppleSetupDone.pkg
  8. The package will be located in the project folder.

Now it’s ready to be installed on a computer to prevent the Apple Setup dialog boxes displaying when starting up the computer for the first time. MySQL, Java JCE and any other custom installers that need to be included can be built using the same process.

Step 2: Creating a never-booted disk image using AutoDMG

AutoDMG is a powerful tool for never-booted disk image creation. Leveraging the image creation of AutoDMG, we can create a never-booted disk image that can be passed to vfuse to convert to a virtual machine. AutoDMG has two sections of packages, the first section is for OS Updates that are pulled down by AutoDMG using the latest base installer. The second section is for custom packages. We will be putting all the packages that we just downloaded or created into that section.

To create a development macOS Jamf Pro server image:

  1. Open AutoDMG.
  2. Drop the OS X Installer into the top panel.
  3. Download updates when available.
  4. Add all the downloaded and created packages that were built in Section 1.
    • Custom MySQL
    • Jamf Pro Installer
    • JDK 8
    • Custom Java JCE
    • Configure Jamf Pro
    • CreateUserPkg
    • Disable Apple iCloud Diagnostic and Siri Pop-Ups
    • AppleSetupDone
  5. Start the image build process by clicking on “Build” and selecting a place to store the image. The process will take about 30 to 45 minutes to complete.

When finished, the never-booted disk image is a ready Jamf Pro development server. The disk image can be use to create virtual machines in VMware or image physical systems for testing and development work.

Step 3: Creating a virtual machine using a disk image

vfuse is a command line tool that interfaces with virtual machines. It has many features including monitoring, naming, creating a virtual machine from a disk image and other customizations can be made to the virtual machine.

Using the disk image we built with AutoDMG , we can input it into vfuse to build a virtual Jamf Pro development server for testing.

Topher% /usr/local/vfuse/vfuse -h
usage: vfuse [-h] [-i INPUT] [-o OUTPUT] [-n NAME] [-w HW_VERSION]
             [-m MEM_SIZE] [-s [SERIAL]] [-t TEMPLATE] [-e] [-p PACKER]
             [--hw-model HW_MODEL] [--start [START]] [--stop STOP]
             [--reset RESET] [--use-qemu]

Create and monitor VM from source DMG.

optional arguments:
  -h, --help            show this help message and exit
  -i INPUT, --input INPUT
  -o OUTPUT, --output OUTPUT
  -n NAME, --name NAME  Use a custom name
  -w HW_VERSION, --hw-version HW_VERSION
                        VMware hardware version
  -m MEM_SIZE, --mem-size MEM_SIZE
                        Memory Size in MB
  -s [SERIAL], --serial [SERIAL]
                        Custom Serial number
  -t TEMPLATE, --template TEMPLATE
                        Use a template
  -e, --esx             Create pre-allocated ESX-type VMDK
  -p PACKER, --packer PACKER
                        Populate a packer template
  --hw-model HW_MODEL   Custom hardware model
  --start [START]       Start monitoring of VM
  --stop STOP           Stop monitoring of VM
  --reset RESET         Reset monitored VM
  --use-qemu            Use qemu-img intead of the Fusion CLI tools

How to use vfuse to build a virtual machine:

  1. In terminal, cd to the directory that the virtual machine will be saved to.
  2. Run /usr/local/vfuse/vfuse -n devJSS_version -i /path/to/disk_image
    /usr/local/vfuse/vfuse -n devJSS_9.100 -i ~/osx_custom_170814-10.12.6-16G29.hfs.dmg 
    Mounting ~/osx_custom_170814-10.12.6-16G29.hfs.dmg
    macOS version is 10.12.6
    Using VMware Fusion path: /Applications/Virtual Machines/VMware Fusion.app
    Converting DMG to VMDK
    Hiding file extension
    Populating VMX file
    Unmounting Base OS DMG
    VMware Fusion VM created at ~/devJamfPro_9.100.vmwarevm
  3. Boot the virtual machine.

Step 4: Initial start of the Jamf Pro server

The virtual machine will autologin to the user that you created using the CreateUserPkg tool. Once logged in, Safari will open the startup page for the Jamf Pro server. The virtual machine uses a self-signed certificate, accept it to continue to load the setup Jamf Pro server page. The first setup page is a license agreement. Read through and accept the license agreement.

Next, it is time to enter in the development activation code. To find your development Jamf Pro activation go to Jamf Nation, login in and select “My Assets”.

Select “Activation Code” on the Assets page.

On this page there will be two activation codes. One is for your production Jamf Pro Server and the other is for “Customer Test and Development”. We will use that code for the development Jamf Pro server. First, enter your organization name as it is listed on Jamf Nation. Now, enter the “Customer Test and Development” activation number.

Create a user to login to your Jamf Pro server with. You can always change it or connect to an LDAP server later.

Create a Jamf Pro server URL for your development server this will help avoid issues with the certificates using a fully-qualified domain name (FQDN). An FQDN is the complete domain name for a specific computer, or host. The FQDN consists of two parts: the hostname and the domain name.

An example of an FQDN would be https://dev-jamfpro.myschool.edu:8443/

The setup is now finished! Go out there and do some testing on your new development Jamf Pro server. Here is a short video of the whole process. It has been sped up from an hour to a minute and a half.



Importing a Production Server into the Development Jamf Pro Server

It may be useful to test with a clone of your production server, instead of a blank environment. Here is how you would go about making a copy of the production Jamf Pro server.

  1. Export the production server.
    • Open the JSS Database Utility by running: /Library/JSS/bin/JSSDatabaseUtil.jar
    • Click “Save Backup now”.
    • Backups can also be saved through the terminal.
      • sudo java -jar /Library/JSS/bin/JSSDatabaseUtil.jar backup -saveBackupTo /save/to/path
  2. Import the database into the development Jamf Pro server.
    • Open the JSS Database Utility by running: /Library/JSS/bin/JSSDatabaseUtil.jar
    • Click “Restore Backup Now” and select the .sql.gz  backup file. Depending on the size of Jamf Pro database the restore process will take about an hour.

Enrolling Clients to the Development Jamf Pro Server

When preforming some testing with the development Jamf Pro server, clients need to be enrolled to the development server and not to the production. Here are some steps to move your client from the production server to the development server.

  1. Install the Casper Suite Applications.
    • The Casper Suite should be located in “My Assets” on the Jamf Nation website
    • Open the disk image containing the Casper Suite Application and place them into Applications.
  2. Modify /Library/Preferences/com.jamfsoftware.jamf.plist
    • Change the JSS_URL string to the URL of the development Jamf Pro server. The computer is very loyal to the production Jamf Pro server.
  3. Changing the Jamf Pro Address.
    • In Recon, change the Jamf Pro Address to the URL of the development Jamf Pro server.
    • A window will come up stating that the Jamf Pro server address has been changed.
  4. Creating a QuickAdd Package
    • Recon will now connect to the development Jamf Pro server. This is the main screen, it displays the information about the computer Recon is currently running on. To begin testing with the development server, we will need to enroll the test computers. To do this we will need to create a QuickAdd Package.
    • Select QuickAdd Package
    • Fill out the information:
      • Username: [LOCAL ADMIN ACCOUNT]
      • Password: [LOCAL ADMIN PASSWORD]
    • Name the QuickAdd Package with the version of Jamf Pro that it is built for.
    • As a final check before using the QuickAdd Package for testing, open the package and look to make sure that the post install script has the development Jamf Pro server URL listed.
  5. Test the QuickAdd Package on a test computer.
    • Before enrolling the test computer to the development Jamf Pro, run jamf removeFramework. The command will remove all Jamf frameworks and preferences from the computer.
      Topher# jamf removeFramework
      Removing scheduled tasks...
      Removing self service...
      Removing JAMF Preferences file...
      Removing JAMF Daemon Log files...
    • Install the QuickAdd package.
      • There are conditions where the package can fail to install if enrollment scripts encounter errors. Check the installer log or /var/log/jamf.log for messages.
    • Check the Jamf Pro binary by running jamf version to check it’s version. Make sure that the correct version is displayed.
      Topher% jamf version
    • Check the Jamf Pro Server URL by running jamf checkjssconnection  that it is pointing to the correct server.
      Topher% jamf checkjssconnection
      Checking availability of https://dev-jamfpro.myschool.edu:8443/...
      The JSS is available.
  6. Run example policies on the test computer.

Future Updates

This is the initial release of Jamf Pro in a Virtual Box. I have many features that I am considering:

  • Reduce manual interaction with the script.
  • Implement AutoDMG command line tool for image & VM creation.
  • Move Jamf Pro server URL, user info and activation code into configuration file.
  • Automate adding self-signed certificate to the Keychain.

If there are any features that you would like, please comment below or create an issue on the GitHub page.

  • Steven
    Posted at 13:24h, 08 September Reply

    Excellent work. Having my entire jamfPro environment running Ubuntu 16LTS in HyperV I only ever spun up similiar dev VMs. I like the idea of just throwing them together quickly like this and running them local on my MacPro on my desk that has plenty of CPU and memory to spare. Also great for training fellow SysAdmins and letting them break their own jamfPro environments.

    • Richard Glaser
      Posted at 16:25h, 08 September Reply

      Thanks, glad you found the blog useful. Let us know if you have any suggestions to make it better.

Leave a Reply