Packaging & Deploying FortiClient EMS with Jamf

Packaging & Deploying FortiClient EMS with Jamf

If you've read my previous post on FortiClient, you'll already be aware that I'm a great fan of their top-tier methods for deploying this particular application …

Well, it was only a matter of time before we had to delve deeper in to this topic. Yes, that's right, EMS. Here's to another can of rotting worms.

In this episode of how to rapidly lose more hair, we'll go through packaging and deploying FortiClient EMS 7.x with Jamf Pro.


Create the Installation Package

First up, you're going to need a generated package from your EMS service, which will come as a .dmg.

After finding hidden config files in another application I was packaging, I've learned the hard way to double-check this mounted volume. What do we have?

10244  3 Jun 17:48 .DS_Store
2048  3 Jun 17:48 .fseventsd
266257984  3 Jun 17:48 Install.mpkg
258  3 Jun 17:48 Technical Documentation.webloc
2048  3 Jun 17:48 Uninstall.app
16485  3 Jun 17:48 background.jpg
2048  3 Jun 17:48 fctdata

Looks like we've got a hidden folder in here with a load of executables, so we'll need to include that in the re-package, otherwise I'm sure something will break.

Under fctdata, it looks like we've got our configuration files, so we'll certainly need to include them, too.

All in all, I think it's best we re-package this whole thing to ensure we don't miss anything at all. There are a few ways we can do this, but I'll stick with Composer, as we'll be pushing with Jamf.

As we need to grab some hidden files, we can't just drag and drop, so create a folder within the /tmp/ folder.

sudo mkdir /tmp/forticlient-ems

Now, copy the contents of the mounted DMG over to our tmp directory.

sudo cp -r /Volumes/FortiClient /tmp/forticlient-ems
sudo cp -r /Volumes/FortiClient/.fseventsd /tmp/forticlient-ems
/tmp/forticlient-ems

.fseventsd
Install.mpkg
Technical Documentation.webloc
Uninstall.app
background.jpg
fctdata

Fantastic, that's the contents of the file in the temporary directory. Open this location in finder, and fire up Composer. We can then drag that in to the window in readiness to create a pkg.

We'll also create a postinstall script to run the .mpkg installer.

sudo installer -pkg /tmp/forticlient-ems/Install.mpkg -target /

With that done, we can Build as PKG. Then we need to test it and make sure it installs the application as expected as if we were installing it as the end user.

Testing the Custom Package

For this first bit, we'll keep it simple, sign in to our VM as a standard user, and enter some admin credentials when prompted to install the PKG.

Yep, that worked!

As you can see, it comes with an absolute barrage of pop-ups that a non-admin user is never going to be able to resolve, and the FortiClient tray icon is present.

If we check our FortiClient Console, we can see that it's connected and managed by FortiClient Cloud, and also has our remote access details pre-filled, and is just waiting for our login. Fantastic, that means all the custom settings have worked, too.

That's the easy part, complete. Time to revert the snapshot to our clean working base, and work through the next part. Hiding those pop-ups and pre-approving the bits we need to.


Configuration Profile

With the application installing, let's work on hiding all these pop-ups and allowing permissions to things.

The first helpful link in this section:

Re: “FortiTray” would like to add VPN configurations
Heya, sorry for the late reply, I finally figured this out. To avoid the VPN popup configuration, we set a dummy VPN configuration that will be used by Forticlient on runtime : Nothing else is checked, make sure that the Identifier and Provider Bundle Identifier are set to “com.fortinet.forticlient…

So, first up is removing that "Permission required for VPN" pop up. This requires a VPN configuration profile. Let's create a new Configuration Profile, and set a VPN payload.

Jamf Pro - Configuration Profile - VPN Payload

Scope it, test it. This removes the VPN pop-up. One down, three more to go. Let's tackle the System Extension warning next.

System Extension

We need to get information about that system extension. The easiest way to do this is to check what extensions are active before, and after manually approving the extension. Don't forget to roll your snapshot back again once you've checked ;)!

systemextensionsctl list
1 extension(s)
--- com.apple.system_extension.network_extension
enabled	active	teamID	bundleID (version)	name	[state]
*	*	AH4XFXJ7DK	com.fortinet.forticlient.macos.vpn.nwextension (1.5.0/B20220228)	vpnprovider	[activated enabled]

Great, now we know what system extension we're approving. Let's add a new payload to our configuration profile.

Jamf Pro - Configuration Profile - System Extension Payload

With that tested, we no longer get the "FortiTray would like permission to create VPN profiles". What's next? Well, all sorts.

Security & Privacy Permissions

Trawling through the Fortinet documentation, I finally found a "Special Notices" section, which provides a list of services that need permissions allowing.

http://docs.fortinet.com/document/forticlient/7.0.5/macos-release-notes/223986/special-notices

Right then, let's get started.

We need to sign our life away for the following components:

  • fcaptmon
  • fctservctl
  • fctservctl2
  • fmon
  • fmon2
  • FortiClient
  • FortiGuardAgent

Time to add a new PPPC payload to our configuration profile:

Jamf Pro - Configuration Profile - PPPC Payload

Phew, that was a long one! Here's all of that in a way you can copy.

/Library/Application\ Support/Fortinet/FortiClient/bin/fcaptmon

identifier fcaptmon and anchor apple generic and certificate 1[field.1.2.840.113635.100.6.2.6] /* exists */ and certificate leaf[field.1.2.840.113635.100.6.1.13] /* exists */ and certificate leaf[subject.OU] = AH4XFXJ7DK


//

/Library/Application Support/Fortinet/FortiClient/bin/fctservctl2

identifier fctservctl2 and anchor apple generic and certificate 1[field.1.2.840.113635.100.6.2.6] /* exists */ and certificate leaf[field.1.2.840.113635.100.6.1.13] /* exists */ and certificate leaf[subject.OU] = AH4XFXJ7DK

//

/Library/Application\ Support/Fortinet/FortiClient/bin/fmon

identifier fmon and anchor apple generic and certificate 1[field.1.2.840.113635.100.6.2.6] /* exists */ and certificate leaf[field.1.2.840.113635.100.6.1.13] /* exists */ and certificate leaf[subject.OU] = AH4XFXJ7DK

//

com.fortinet.forticlient.macos.antivirus

anchor apple generic and identifier "com.fortinet.forticlient.macos.antivirus" and (certificate leaf[field.1.2.840.113635.100.6.1.9] /* exists */ or certificate 1[field.1.2.840.113635.100.6.2.6] /* exists */ and certificate leaf[field.1.2.840.113635.100.6.1.13] /* exists */ and certificate leaf[subject.OU] = AH4XFXJ7DK)

//

com.fortinet.FortiClient

identifier "com.fortinet.FortiClient" and anchor apple generic and certificate 1[field.1.2.840.113635.100.6.2.6] /* exists */ and certificate leaf[field.1.2.840.113635.100.6.1.13] /* exists */ and certificate leaf[subject.OU] = AH4XFXJ7DK

You'll notice that fmon2 is missing from this list. Well, it's not. No matter how many times I tried to get fmon2 approved, I received warnings about needing to allow access. Turns out that I actually needed to approve com.fortinet.forticlient.macos.antivirus - not fmon2. Thanks for wasting a week there, Fortinet!

That's our VPN, PPPC, and System Extension pop-ups dealt with. Let's try to tackle that certificate warning.

Certificates

This had me boggled for a few days, until a moment of clarity in the shower (it's where my best thinking happens). Honestly, not sure why it took me this long.

I approved the certificate prompt on the test VM, then exported them from the Keychain.

I found we needed two certificates from here. support.cer, and fortinet-ca2.cer.

Keychain Access showing the Forticlient Certificates

As this contains certificates which could be revoked, or need to be changed at different intervals to the other settings, I created a new profile with a Certificate payload.

Jamf Pro - Configuration Profile - Certificate Payload

After testing this, I found I had to restart the machine for the certificate trust to be in place. I added a restart option to the installation policy, and no more pop-ups!

That's two configuration profiles, with a total of 4 payloads between them.

Wrap-up

After endless testing with the VM, I deployed it to a few different machines, across a couple of different macOS versions, to ensure that it behaved as expected.

I HATE anything to do with FortiClient. It's always such a pain.

Let's see what we have for this.

  1. A custom package with the contents from the pre-packaged DMG

2.  A computer policy to install the package - scoped to staff machines, and made available in Self Service (don't want to be pushing this out with an enforced restart).

3.  Two Configuration Profiles, scoped to our staff machines.

We can finally move this out of test, and close the job off!

I hope this helped some of you out there.

--

Photo by Shubham Dhage on Unsplash

Show Comments