Identifying Self Service policies with blank descriptions

As part of setting up Self Service policies in Jamf Pro, it’s nice to include a description for your customers of what they’re getting when they select a particular Self Service policy.

Screen Shot 2019 09 16 at 2 37 05 PM

However, sometimes folks forget to add these descriptions and it can be hard to figure this out later which ones were missed without manually checking each policy.

Screen Shot 2019 09 16 at 2 16 38 PM

To help with situations like this, I have a script which does the following:

  1. Checks all policies on a Jamf Pro server.
  2. Identifies which ones are Self Service policies which do not have descriptions
  3. Displays a list of the relevant policies

For more details, please see below the jump.

The script is named Jamf_Pro_Detect_Self_Service_Policies_Without_Descriptions.sh. For authentication, the script can accept hard-coded values in the script, manual input or values stored in a ~/Library/Preferences/com.github.jamfpro-info.plist file.

The plist file can be created by running the following commands and substituting your own values where appropriate:

To store the Jamf Pro URL in the plist file:

defaults write com.github.jamfpro-info jamfpro_url https://jamf.pro.server.goes.here:port_number_goes_here

To store the account username in the plist file:

defaults write com.github.jamfpro-info jamfpro_user account_username_goes_here

To store the account password in the plist file:

defaults write com.github.jamfpro-info jamfpro_password account_password_goes_here

When the script is run, you should see output similar to that shown below.

Report

The script is available below, and at the following address on GitHub:

https://github.com/rtrouton/rtrouton_scripts/tree/master/rtrouton_scripts/Casper_Scripts/Jamf_Pro_Detect_Self_Service_Policies_Without_Descriptions

Jamf_Pro_Detect_Self_Service_Policies_Without_Descriptions.sh:

Creating macOS configuration profiles with encrypted payloads

Recently, I was asked to create a configuration profile with an encrypted payload. This is a payload where the settings installed by the profile are not readable when you look at the .mobileconfig file. Instead, the payload with the settings is encrypted and are only readable once the payload contents are decrypted using the private key of a certificate which is also installed on the Mac in question.

In researching how to do this, I found that Apple’s documentation on encrypted payloads is very sparse and largely consists of the following (from https://developer.apple.com/documentation/devicemanagement/using_configuration_profiles):

Screen Shot 2019 09 15 at 11 15 41 PM

Example commands for CMS encryption of the property list are not provided in Apple’s documentation, but it is possible to use /usr/libexec/mdmclient to encrypt profile payloads:

https://mosen.github.io/profiledocs/troubleshooting/mdmclient.html#encrypt

To see how this works, let’s go through the process of setting up a certificate which can be used for encrypting a profile followed by using that certificate to encrypt the profile. For more, please see below the jump.

Before we begin creating the certificate, I want to note that the certificate used in this example is going to be a self-signed root certificate. Using a self-signed root certificate is fine for prototyping and testing, but you should use a certificate issued by a trusted certificate authority if you’re using this method in production.

Creating the certificate

1. Run the following commands to generate a private key:

openssl genrsa -des3 -passout pass:x -out encryptprofiles.pass.key 2048
openssl rsa -passin pass:x -in encryptprofiles.pass.key -out encryptprofiles.key

Screen Shot 2019 09 15 at 1 55 35 PM

Screen Shot 2019 09 15 at 1 57 00 PM

Once the encryptprofiles.key file is generated, the encryptprofiles.pass.key file may be removed as it is no longer needed.

2. Run the following command to generate a certificate signing request (CSR):

openssl req -new -key encryptprofiles.key -out encryptprofiles.csr

Screen Shot 2019 09 15 at 1 58 58 PM

You will be asked a number of questions. The one which ultimately matters in this case is the Common Name question, as that is the one which is the name assigned to the certificate. In this case, I am setting encryptprofiles.company.com as the Common Name for the certificate.

Note: The challenge password can be left blank.

3. Once the CSR has been generated, run the following command to create a public key using the private key and CSR:

openssl x509 -req -sha256 -days 365 -in encryptprofiles.csr -signkey encryptprofiles.key -out encryptprofiles.crt

Screen Shot 2019 09 15 at 1 59 51 PM

4. Combine both the private key and public key into one text file named bothprivateandpublickeys.txt by running the following command:

cat encryptprofiles.key encryptprofiles.crt > bothprivateandpublickeys.txt

Screen Shot 2019 09 15 at 2 00 19 PM

5. Run the following command to generate a .p12 file which uses the contents of the bothprivateandpublickeys.txt file to generate a .p12 archive file which contains both the private and public key:

openssl pkcs12 -export -in bothprivateandpublickeys.txt -out bothprivateandpublickeys.p12

Screen Shot 2019 09 15 at 2 00 59 PM

You will be asked to set and verify an export password. You will need this password later, so make a note of it.

In this case, the following password is being used: password123

Creating a certificate profile

My next step was to create a configuration profile using ProfileCreator which included both the bothprivateandpublickeys.p12 file and the export password needed to unlock the .p12 file. This profile will import the .p12 file and use it to deploy the encryptprofiles.company.com certificate as a trusted root certificate.

Screen Shot 2019 09 15 at 5 37 23 PM

Screen Shot 2019 09 15 at 5 37 29 PM

Once built, the profile looks like this:

The final step is to install the profile, so that we can use it to encrypt another configuration profile’s payload. The profile installation can be performed via MDM, using the profiles command line tool or by double-clicking on the profile to install it.

In this case, I’m signing the certificate with my Developer ID Application signing certificate and then double-clicking to install it.

Screen Shot 2019 09 15 at 4 40 41 PM

Screen Shot 2019 09 15 at 2 47 03 PM

Encrypting a profile

Once the certificate profile is installed on a particular Mac, it should appear in the System keychain as a trusted root.

Screen Shot 2019 09 15 at 2 47 25 PM

Once the certificate is showing up in Keychain Access as trusted, it can be used to encrypt profiles. To do this, run a command similar to the one shown below:

/usr/libexec/mdmclient encrypt "certificate_common_name_goes_here" /path/to/profile_to_encrypt_goes_here.mobileconfig

In my case, I’m running the following command to encrypt a configuration profile named Company WiFi.mobileconfig:

Screen Shot 2019-09-15 at 2.08.11 PM

/usr/libexec/mdmclient encrypt "encryptprofiles.company.com" "/Users/username/Desktop/Company WiFi.mobileconfig"

A new profile should appear named Company WiFi.encrypted.mobileconfig.

Screen Shot 2019-09-15 at 2.07.50 PM

The original Company WiFi.mobileconfig profile looks like this, with the profile’s settings listed under PayloadContent:

The new Company WiFi.encrypted.mobileconfig profile looks like this, with the profile’s settings encrypted and listed under EncryptedPayloadContent:

Installing an encrypted profile

Assuming the certificate profile is installed on a particular Mac, the encrypted profile can now be installed. The profile installation can be performed using the profiles command line tool or by double-clicking on the profile to install it.

If the certificate used to decrypt the profile is present and everything is working properly, the encrypted profile should install without a problem.

Screen Shot 2019 09 15 at 5 12 20 PM

If there is a problem with decrypting the profile, the process will error because the Mac won’t be able to read the profile’s encrypted payload.

Notes on this process

  • It is absolutely necessary for the certificate used to encrypt the profile to be deployed to the Mac receiving the encrypted profile and necessary for that certificate to include the private key.
  • It is also necessary for the export password used to protect the .p12 file be provided, either in the profile itself or manually provided when the certificate profile is installed.
    • The reason is that the private key is used to decrypt the profile’s encrypted content and the export password is used to make that possible.
  • The certificate must be deployed to the Mac receiving the encrypted profile before the encrypted profile is. If not, the encrypted profile won’t be readable by the Mac and the profile won’t install.

Screen Shot 2019 09 15 at 5 58 40 PM

  • You likely won’t be able to deploy the encrypted profile using an MDM server.
    • The reason is that when the profile was uploaded to the MDM server, the MDM server may try to read the profile and fail because it doesn’t have access the certificate used to decrypt the encrypted profile’s contents. This causes the upload process to halt and display an error. Instead, you will need to install the encrypted profile using the profiles command line tool.

 

Disable screenshots and screen recordings on macOS Mojave

In certain circumstances, like taking school tests or handling sensitive documents, it may be necessary to disable the ability to create screenshots or make screen recordings. For those who need to do this, it’s possible to set this with a profile.

PayloadType: com.apple.applicationaccess
Key: allowScreenShot
Type: boolean

Once a profile has been built and applied to a Mac running macOS Mojave, trying to create a screenshot or screen recording will result in the following message.

Screenshot disabled message

For more details, please see below the jump.

A sample profile is below and also available on GitHub via the following link:

https://github.com/rtrouton/profiles/tree/master/DisableScreenshotCreation

Apple Device Management book now available for pre-order from Amazon

Over the past year, I’ve been working with my colleague Charles Edge on a new book and I’m delighted to announce it’s now available for pre-ordering on Amazon:

Pre-order link: https://www.amazon.com/Apple-Device-Management-Managing-AppleTVs/dp/1484253876

This quality item is suitable for any gift-giving occasion, in addition to being the perfect something for your own use (perhaps as a doorstop.) Please order now.

Monitoring Jamf Infrastructure Managers on Red Hat Enterprise Linux

A vital component of a Jamf Pro server setup is usually its LDAP connection to a directory service (usually an Active Directory server.) This connection allows the Jamf Pro server to not only leverage the directory service’s users and groups, but also automatically populate information about the owner of the device by doing a lookup in LDAP as part of a computer‘s or mobile device’s inventory update and assist with providing user-specific policies in Self Service.

As more folks move from using self-hosted Jamf Pro servers to now having Jamf host them in Jamf Cloud, this LDAP connection usually requires an LDAP proxy in order to securely connect a Jamf Cloud-hosted Jamf Pro instance to a company’s internally-hosted directory service. Jamf provides an LDAP proxy for this purpose in the form of the Jamf Infrastructure Manager (JIM). 

Because the LDAP connection is so vital, it’s just as vital that the JIM stay up and working all the time. To assist with this, I’ve written some scripts to assist with monitoring and reporting for a JIM running on Red Hat Enterprise Linux. For more details, please see below the jump.

I’ve written three scripts to assist with JIM monitoring:

  • jim_check.sh – monitors the JIM and restarts it if needed.
  • jim_report.sh – sends a report to a designated Slack channel
  • install_jim_check_scripts_and_crontab.sh – installs the jim_check.sh and jim_report.sh scripts into /usr/local/bin and sets up a crontab entry to run the jim_check.sh script every ten minutes.

All three scripts are shown below and are also available on GitHub via the following link:

https://github.com/rtrouton/jamf_infrastructure_manager/tree/master/jim_monitoring

The jim_check.sh script checks the port that the JIM uses for incoming LDAP queries from its Jamf Pro server, to see if the LDAP proxy service is listening on that port. If nothing is listening on that port, the JIM process is automatically stopped and restarted. After the restart completes, the jim_report.sh script is triggered to provide information about the service stoppage.

The jim_report.sh script is designed to capture information from the /var/log/jamf-im.log and forward that information along with basic identifying information for the JIM to a Slack channel via a webhook.

Screen Shot 2019 08 22 at 2 31 15 PM

The general idea is that the forwarded log entries should hopefully show whatever problem the JIM’s LDAP proxy service was having before it went offline and needed to be restarted.

The install_jim_check_scripts_and_crontab.sh script is designed to install both the jim_check.sh and jim_report.sh scripts into /usr/local/bin and also set up a cronjob for regular running on the jim_check.sh script.

The Jamf Pro Push Proxy service, service token renewal and Jamf Nation credentials

Jamf Pro has the ability to push notifications to devices with Self Service installed. This function is enabled using a Jamf-specific service known as the Jamf Push Proxy.

Screen Shot 2019 08 13 at 12 36 58 PM

Screen Shot 2019 08 13 at 12 37 15 PM

To enable this service to work with your Jamf Pro server, you need to set up a push proxy server token using the process shown below:

1. Log into your Jamf Pro server as an administrator.
2. Go to Settings > Global Management > Push Certificates.

Screen Shot 2019 08 13 at 12 08 21 PM

3. Click the New button.

Screen Shot 2019 08 13 at 12 07 46 PM

4. Select the Get proxy server token from Jamf Authorization Server option and click the Next button.

Screen Shot 2019 08 13 at 12 03 57 PM

5. Provide credentials for a Jamf Nation user account and click the Next button.

Screen Shot 2019 08 13 at 12 04 17 PM

6. If successful, you should be notified that the proxy server token has been uploaded to your Jamf Pro server. Click the Done button.

Screen Shot 2019 08 13 at 12 04 44 PM

7. The proxy server token should appear listed as Push Proxy Settings in the Push Certificates screen.

Screen Shot 2019 08 13 at 2 13 26 PM

Once the Push Proxy service has been enabled for your Jamf Pro server, you can use the notifications options in your Self Service policies to provide notifications in Self Service and Notification Center when desired.

Screen Shot 2019 08 13 at 12 37 37 PM

For more details, please see below the jump.

One thing to be aware of is that the push proxy server token has a very short life (one day) and needs to be renewed regularly. The credentials of the Jamf Nation account used to set up the push proxy server token are stored in the Jamf Pro database and used to renew the push proxy server token. This use of stored Jamf Nation credentials has two implications to be aware of:

  1. If the password for that Jamf Nation account is changed or the account is closed, then the Jamf Pro server which is using those credentials will be unable to successfully renew the push proxy server token. This means that the renewal will fail and the certificate stops being renewed.
  2. The Jamf Nation account’s credentials are stored in the database, which may be a security risk if those account credentials have access to other Jamf Nation resources.

To manage these risks, I would recommend setting up a separate Jamf Nation account and use it specifically for enrolling the Push Proxy service on your Jamf Pro server. One thing to be aware of is that the separate Jamf Nation account must have some assets associated with it, so I also recommend talking with Jamf Support as to the best way to manage this.

If you want to change the Jamf Nation account used with the Push Proxy service, you can fix this by deleting the current push proxy token and setting up a new one. You can do this using the process shown below:

1. Log into your Jamf Pro server as an administrator.
2. Go to Settings > Global Management > Push Certificates.

Screen Shot 2019 08 13 at 12 08 21 PM

3. Click the Push Proxy Settings token.

Screen Shot 2019 08 13 at 2 13 26 PM

4. Click the Delete button.

Screen Shot 2019 08 18 at 12 09 12 PM

5. When asked to confirm, click the Delete button.

Screen Shot 2019 08 18 at 12 09 59 PM

At this point, your existing push proxy token should be removed.

Screen Shot 2019 08 18 at 12 10 28 PM

To set up a new one using the new Jamf Nation account, use the procedure described earlier to set up the new push proxy token.

今井夏帆の刺激的VRエロ動画【黒ギャル+オイル=最強説】黒光り美乳を体感

⇒こちらからVRエロ動画を見る

VRエロ動画情報

タイトル:【4K匠・AdultFesta先行配信】黒ギャル+オイル=最強説 今井夏帆

出演:今井夏帆
時間:1時間 21分 58秒
ブランド:KMPVR-bibi-
リリース:2019-08-09
カテゴリ:ギャル,美乳,フェラチオ

紹介文:新進気鋭の黒ギャル「今井夏帆」が遂にKMP VR-bibi-に登場だ!!「もしも今井夏帆が彼女だったら」という夢のようなシチュエーションでラブラブSEX!ローションもたっぷり、オイルもたっぷり、ぬるぬるテカテカ!『黒ギャル+オイル=最強説』が証明された!!収録体位は騎乗位・対面座位・バック・正常位のフルコース!

⇒こちらからVRエロ動画を見る

Session videos now available from Penn State MacAdmins Conference 2019

The good folks at Penn State have posted the session videos from Penn State MacAdmins Conference 2019. The sessions slides are all accessible from the Penn State MacAdmins’ Resources page at the link below:

http://macadmins.psu.edu/conference/resources/

All session videos are available via the link below:

https://www.youtube.com/playlist?list=PLRUboZUQxbyUovbRrw99WWyli5PF9EtXk

I’ve linked my “Installer Package Scripting: Making your deployments easier, one !# at a time” session here:

The “macOS 10.15, the future of Mac administration and more, AMA” panel I co-hosted with Allen Golbig, Lisa Davies, Amanda Wuest, Jennifer Unger and Robert Hammen is linked here:

The “Empowering the Slack Powered Workplace” panel I participated in along with Tim Burke, Erin Merchant and Michael Norton is linked here:

Enabling debug logging for the JAMFSoftwareServer log on Jamf Pro limited access nodes

As part of working on an issue with Jamf Support, I needed to enable debug logging for the JAMFSoftwareServer.log log file on my Jamf Pro server. This is normally a pretty straightforward process:

1. Log into your Jamf Pro server.

2. Go to Management Settings: Jamf Pro Information: Jamf Pro Server Logs.

Screen Shot 2019 08 02 at 10 30 49 AM

3. Click the Edit button.

Screen Shot 2019 08 02 at 10 38 29 AM

4. Check the checkbox for Enable Debug Mode.

Screen Shot 2019 08 02 at 10 38 20 AM

5. Click the Save button.

Screen Shot 2019 08 02 at 10 31 23 AM

6. Verify that the log has changed into debug mode.

Screen Shot 2019 08 02 at 10 31 35 AM

However, what do you do about Jamf Pro servers which are set to limited access? The admin console is disabled on limited access nodes, which means you can’t use the admin console’s functionality to enable debug logging. There is a way, but it means editing some Tomcat settings. For more details, please see below the jump.

To enable debug logging for limited access nodes, you need to edit the log4j.properties file, which manages logging for both the JAMFSoftwareServer.log and JAMFChangeManagement.log logfiles. The log4j.properties file is stored in the following location:

/path/to/tomcat_directory/webapps/ROOT/WEB-INF/classes/log4j.properties

 

To turn debug logging on:

1. Open the log4j.properties file.

2. Search for the following string:

log4j.rootLogger=INFO,JAMF

Screen Shot 2019 08 02 at 11 01 22 AM

Screen Shot 2019 08 02 at 11 01 39 AM

3. Change it to the following:

log4j.rootLogger=DEBUG,JAMF

Screen Shot 2019 08 02 at 11 02 04 AM

4. Save changes to the log4j.properties file.

5. Once the change has been made, restart Tomcat.

 

To turn debug logging off:

1. Open the log4j.properties file.

2. Search for the following string:

log4j.rootLogger=DEBUG,JAMF

Screen Shot 2019 08 02 at 11 02 46 AM

Screen Shot 2019 08 02 at 11 10 33 AM

3. Change it to the following:

log4j.rootLogger=INFO,JAMF

Screen Shot 2019 08 02 at 11 07 23 AM

4. Save changes to the log4j.properties file.

5. Once the change has been made, restart Tomcat.

 

Building customized postinstall scripts for AutoPkg recipes

As part of some recent work, I needed to build a deployable installer package for an application named Zscaler. This application does not use an installer package, nor can it be installed as a drag-and-drop app. Instead, it uses a third party installer application to install.

Screen Shot 2019 07 26 at 4 36 20 PM 1

This is exactly the kind of situation where I want to write an AutoPkg recipe to handle building a deployable installer package for me. As part of that, I had two bits of good news:

  1. There was a publicly available download URL for the Zscaler installer app.
  2. Zscaler has instructions for installing from the command line, so I could wrap up the installer application inside an installer application and use a postinstall script to run the installation process.

Screen Shot 2019 07 26 at 2 51 06 PM

I had one bit of bad news:

The installer process included options for adding things like the Zscaler cloud instance which the app should talk to following the installation as well as various other options which probably shouldn’t be hardcoded into an Autopkg recipe. I especially shouldn’t be hardcoding my own organization’s credentials into a recipe which I was planning to share with other folks.

Normally, sensitive information is something I want to only have in an AutoPkg recipe override. Recipe overrides are locally-stored files that allow you to change certain input variables in AutoPkg recipes. Since the recipe overrides are stored locally on the Mac which is running AutoPkg and not shared with any other resources, the sensitive information is only made available to the AutoPkg installation running on that specific Mac. I’ve used this approach previously for the following:

Sensitive URLs: https://derflounder.wordpress.com/2017/06/12/autopkg-recipes-for-apple-enterprise-connect/
Signing AutoPkg-generated installer packages: https://derflounder.wordpress.com/2017/11/10/adding-installer-package-code-signing-to-autopkg-workflows/

This time though, I didn’t see a way to pass an AutoPkg recipe override’s variables to a postinstall script. I did have one idea though, which was using AutoPkg’s FileCreator processor to create a customized postinstall script. I had previously used the FileCreator processor in other AutoPkg recipes to create postinstall scripts, but those scripts were self-contained and didn’t use variables from the AutoPkg recipe.

AutoPkg Adobe Creative Cloud recipe postinstall script

That said, you never know what AutoPkg can do until you try it and sure enough the FileCreator processor was able to pass recipe variables as part of creating a file. For more details, please see below the jump.

I was able to leverage the ability to pass variables to create this script:

I then created a recipe override and added the following demo values from the Zscaler command line options page:

  • cloudName: zscalertwo.net
  • deviceToken: 123456789
  • policyToken: 987654321
  • userDomain: safemarch.com

The installer package postinstall script generated by this recipe override had the following contents:

In turn, this meant that only the Zscaler command-line options with actual values were run as part of the postinstall script:

Being able to pass variables this way means that the AutoPkg Zscaler .pkg recipe can be used by anyone. Whoever needs to plug in custom variables can do so as part of a recipe override, which allows them to keep their organization-specific information safe while still leveraging AutoPkg’s ability to automatically build installers for deployment.

This technique also has wider applications for anyone who needs to build custom postinstall scripts as part of an AutoPkg recipe because it means that customizable postinstall scripts can be generated on a per-override basis. For example, if you needed to support packaging for multiple organizations, it’s possible to have one core .pkg recipe along with a FileCreator-generated script which is flexible enough to accommodate whatever variables a particular override provides.

Going back to the example of Zscaler, if I needed to support three different organizations, all I would need is the one Zscaler .pkg recipe and three overrides. The overrides would have the different organization’s individual settings and running the overrides would result in three installers with organization-specific settings in the individual installer’s postinstall script.

For folks wanting to take a look at examples, I’ve posted .download, .pkg and .jss recipes for Zscaler to GitHub at the following locations:

https://github.com/autopkg/rtrouton-recipes/tree/master/Zscaler
https://github.com/autopkg/rtrouton-recipes/blob/master/JSS/Zscaler.jss.recipe