PaloAlto GlobalProtect v6 Deployment via Jamf Pro

sintichn
New Contributor III

Hi Folks,

I'm putting this here to try to be a little helpful. We just moved from v5 to v6 for GlobalProtect, and basically, the setup that we had that, installed the stock pkg from paloalto and relied on a config profile to set our default portal stopped working. I also couldn't get the app to stop an endless "connecting" loop. 

So for anyone who is having the same issue, I hope this is helpful. Long story short, you need to package an XML file that installs the system extension with the app pkg and then run a script to install both.

The GP release notes for 6.0.1 speak of a new Simplified and Seamless macOS GP app deployment Using Jamf MDM integration feature. The documentation is helpful but not comprehensive so I'll put it together here.

 

Sources: https://docs.paloaltonetworks.com/globalprotect/10-1/globalprotect-admin/mobile-endpoint-management/...

https://docs.paloaltonetworks.com/globalprotect/10-1/globalprotect-admin/mobile-endpoint-management/...

https://docs.paloaltonetworks.com/globalprotect/10-1/globalprotect-admin/mobile-endpoint-management/...

 

  1. Download the pkg and create the script that sets the preferred portal. You can find the script in step 3 of this page. (of course you'll need to change the your.portalhere.com stuff)
  2. Upload script to jamf pro, don't upload the pkg yet.
  3. Follow step 1 and 2 in this article to create a config profile to allow the system extension.
  4. Create an XML file called install_system_extensions.xml with the XML in step 3 of this article
  5. Make the XML file executable.

 

sudo chmod +x /path/to/file/​

 

  • Pick a temporary location to install the stock pkg and XML file... for example /usr/local/ works.
  • Create a directory in that area and name it something like GP, drop the pkg and the XML file in that folder.
  • Open Composer and drag the GP folder in the left side, rename your folder on the left side of composer. (so that the pkg name that you create is something more useful than just "GP")
  • Change the owner and group of the pkg and XML file so it's root:wheel and apply to all contents on both the pkg and XML file.
  • Create the pkg.
  • Upload the pkg to jamf pro.
  • Create a script that will install GlobalProtect and the SystemExtension, then deletes the directory that jamf installs from the package that you created. Upload this to jamf pro. #2 in Step 3 of this page has the install command... or I threw it in the script below.

 

#!/bin/bash

#install pkg with system extension
sudo installer -pkg /path/to/globalprotectapppkg -applyChoiceChangesXML /path/to/xml/file -target /

#Delete directory
rm -rf /path/to/directory/that/was/installed

exit 0

 

  • Create a jamf policy and do the following...
    1. Add the package that you compiled in composer and set it to install.
    2. Add the script that sets the portal address to run before the pkg install.
    3. Add the script that does the installation of both the pkg and system extension to run after the pkg install.

This should do the trick! Again hopefully this is helpful! Good Luck!

1 ACCEPTED SOLUTION

jamf_wroblewski
New Contributor II

I FIGURED IT OUT!

Config profile for SystemExtension wasn't set as "Install Automatically" but "Make available in self service", therefore, it didn't work. After change - works like a charm! Thanks for help @sintichn 

View solution in original post

17 REPLIES 17

Anonymous
Not applicable

Fantastic article! Works like a charm. Thank you very much for creating this article. 👍

jamf_wroblewski
New Contributor II

Hey!

I'm following your steps, but global protect still prompt a window with "System Extesion Blocked". Any ideas what could go wrong? I tried everything I found but got stuck on that step...

sintichn
New Contributor III

@jamf_wroblewski Let's see, I'm trying to think of all the things that could go wrong with a config profile so I spit them all about below.

I would verify that in your config profile in the system extension payload, the teamid is there and correct: PXPZ95SK77 but also that you have 

com.paloaltonetworks.GlobalProtect.client.extension

 in the allowed system extensions area under the team ID... after you enter that info you need to click the small save button that is to the right of that area before you click the big save button to save the config profile itself... Also, make sure that the config profile exists on the computer that you're testing this with. if it's still not working post a screenshot and I'll take a look!

jamf_wroblewski
New Contributor II

jamf_wroblewski_1-1674571785415.png

Yes, it is done.
I created xml file with content you used for deployment. I put it in the same directory as GlobalProtect.pkg via Jamf Composer. When I try to run it manually, everything goes fine. Even when I check the policy logs:

jamf_wroblewski_2-1674571972912.png

It seems like xml file does nothing. I checked ownership and permissions (root:wheel, chmod +x). And still - nothing has changed.



 

jamf_wroblewski
New Contributor II

I FIGURED IT OUT!

Config profile for SystemExtension wasn't set as "Install Automatically" but "Make available in self service", therefore, it didn't work. After change - works like a charm! Thanks for help @sintichn 

sintichn
New Contributor III

Oh my goodness, so happy that you figured it out @jamf_wroblewski. I feel like I always run into weird gremlins that put the kibosh on the end result all the time!

n123
New Contributor

Hi guys!

Faced the same endless connection.

Tested it with Ventura 13.2.1, GP 6.0.4-26 without system extensions and it works.

So PKG + script (without sysext xml) was enough for me.

 

root# systemextensionsctl list
1 extension(s)
--- com.apple.system_extension.endpoint_security
enabled	active	teamID	bundleID (version)	name	[state]
*	*	483DWKW443	com.jamf.protect.security-extension (4.0.0/764)Jamf Protect Endpoint Security Extension	[activated enabled]

 

n123_0-1680003683615.png

 

n123
New Contributor

upd: had to switch to subj package + conf profile + script instead :/

mateow
New Contributor

does anyone know why is this SysEXt needed to be installed VIA script and not MDM? seems counter intuitive.  

mikegetchell
New Contributor III

I deploy script via MDM and it works correctly.  I just followed the setup here and didn't have any issues.  Deployed the config profile ahead of the install package.  Only needed a restart before GP would connect correctly.

If add the System Extension via Config Profile in step 1 and 2 in the article, do we even need to create the System Extension XML file in step 3 in the same article?

I tested it and looks like I don't need the XML file if I have the System Extension setup as a Config Profile in Jamf.

I recently found I'm not actually installing the system extension. Because of the way I have things setup, that command doesn't function because the package has already been installed and removed. The config profile only approves the extension to run, it doesn't install it. I'm guessing you aren't using functionality of GP that depends on the extension.

That said, I think I have an easier way to do this than all of than the OP uses, I need to test it first though.

Ok, so I kinda forgot about this, but here's how I install GP...

Create a configuration file giving the system extension access by following the guide you linked to.

Then you'll create two scripts:

  1. The first handles the actual installation and was created by @talkingmoose. It will handle the installation and also create the XML in step 3 of the guide you referred to. The XML essentially checks the boxes you would encounter if installing through the GUI, so the system extension won't actually install without it. The original script is here: https://gist.github.com/talkingmoose/3926e86332e32eb7d05a161c3f7e8f69
    This is what mine looks like (I chopped the beginning off just for the sake of shortening the post):

 

#!/bin/zsh

# ABOUT_THIS_SCRIPT

# provide the name of an Apple Installer package file that supports Choices XML
installerPackage="$4"

# modify the choiceIdentifier string with the app identifier (CFBundleIdentifier) to exclude from installation
# duplicate the full dictionary to include additional apps
choicesXML='<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<array>
           <dict>
                  <key>attributeSetting</key>
                  <integer>1</integer>
                  <key>choiceAttribute</key>
                  <string>selected</string>
                  <key>choiceIdentifier</key>
                  <string>third</string>
           </dict>
           <dict>
                  <key>attributeSetting</key>
                  <integer>1</integer>
                  <key>choiceAttribute</key>
                  <string>selected</string>
                  <key>choiceIdentifier</key>
                  <string>com.paloaltonetworks.globalprotect.systemext.pkg</string>
            </dict>
</array>
</plist>'

function logmessage()   {
    if [ $? = 0 ] ; then
        echo "$1"
    else
        echo "$2"
        echo "Aborting script"
        cleanup
        exit 1
    fi
}
 
function cleanup()  {
    /bin/rm -Rf "$tempDirectory"
    logmessage "Removed temporary items." "Failed removing temporary items."
    /bin/rm -f "/Library/Application Support/JAMF/Waiting Room/$installerPackage" && /bin/rm -Rf "/Library/Application Support/JAMF/Waiting Room/$installerPackage.cache.xml"
    logmessage "Removed $5 package and supporting files from Jamf Waiting Room." "Failed Removing $5 package and supporting files from Jamf Waiting Room."
}
 
# create temporary working directory
workDirectory=$( /usr/bin/basename $0 )
tempDirectory=$( /usr/bin/mktemp -d "/private/tmp/$workDirectory.XXXXXX" )
logmessage "Created working directory '$tempDirectory'." "Failed to create working directory '$tempDirectory'."
 
# change directory to temporary working directory
cd "$tempDirectory"
logmessage "Changed directory to working directory '$tempDirectory'." "Failed to change directory to working directory '$tempDirectory'."
 
# create choices.xml (renamed to install_system_extensions.xml for GP)
echo "$choicesXML" > "$tempDirectory/install_system_extensions.xml"
logmessage "Created install_system_extensions.xml file in '$tempDirectory'." "Created install_system_extensions.xml file in '$tempDirectory'."
 
# install GP
/usr/sbin/installer -pkg "/Library/Application Support/JAMF/Waiting Room/$installerPackage" -applyChoiceChangesXML "$tempDirectory/install_system_extensions.xml" -target /
logmessage "Installed $5 package with extension." "Failed to install $5 package with extension."
 
cleanup
 
exit 0​

Note: the original tells you to insert the app name and package name in the script, which I have replaced with Jamf script parameters, you do you.

 

  • The second script is to create a plist that will set the portal and any other preference keys you want to specify. This is mine:

 

#!/bin/zsh
## Description: Checks for global preferences file and populates  
## it with the default portal if needed.
 
# Get current Console user
# active_user=$( stat -f "%Su" /dev/console )
active_user=$( scutil <<< "show State:/Users/ConsoleUser" | awk '/Name :/ && ! /loginwindow/ { print $3 }' )
 
# Global Prefs File
gPrefs=/Library/Preferences/com.paloaltonetworks.GlobalProtect.settings.plist
 
## Logic ##########################################################
 
# Check to see if the global preference file already exists...
# if [[ -e $gPrefs ]]; then
#	echo "Default global portal already exists. Skipping."
# else
if [[ -e $gPrefs ]]; then
  echo "Removing existing GlobalProtect prefs file"
  rm -f ${gPrefs}
fi
	echo "Setting default global portal to: gp-remote.overdrive.com"
     # If it does not already exist, create it and populate the default portal using the echo command
       echo '<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Palo Alto Networks</key>
    <dict>
        <key>GlobalProtect</key>
        <dict> 
            <key>PanSetup</key>
            <dict>
                <key>Portal</key>
                <string>INSERT GP PORTAL HERE</string>
                <key>Prelogon</key>
                <string>0</string>
            </dict>
            <key>Settings</key>
            <dict>
                <key>disable-allowed</key>
                <string>yes</string>
            </dict>
        </dict>
    </dict>
</dict>
</plist>
' > $gPrefs
echo $?
	# Kill the Preference caching daemon to prevent it from overwriting any changes
	killall cfprefsd
	echo $?

# Check exit code.
exit $?​

I'm pretty sure I got part of this from another thread in the Community, but I can't recall who/where.

 

Now create a policy to put everything together:

  1. Add the GP installation package to cache. If you install rather than cache then the first script won't have a package to work with.
  2. Add the scripts to run after everything else. If not obvious, the installation script should run prior to the one for the plist.

Test!

The nicest thing about the fancy installation script is when you need to install a newer version you can just replace the package and update the filename in the script or script parameter (alternatively, you can always rename the package to GlobalProtect.pkg before uploading it to avoid having to update the version number elsewhere).

pueo
Contributor II

I do not have any XML scripts running for the install of GP 6.1-3.  I use configuration profiles. We have very very few issues with the installation and set up of GP.  

It can be done without scripts, it depends on your needs.

Birdseed
New Contributor

I know this is late - but did any of you guys run into issues with Global Protect and Jamf Connect? 

Even with no Pre-logon in place, once GP is installed it prevents access to the network on a Jamf Connect logon screen.

n123
New Contributor

@Birdseed , didn't face that issue. It could be your GP App configuration and Jamf Connect settings conflict. Review both as well as their logs.