Automatic Secure and BootstrapToken

Ismere
Contributor

I already posted a somehow working, but solving it only in a quick and dirty way, script for this.
But over the course of the last few weeks i finally had some time to create something that worked a bit better and allows some troubleshooting.

Before using this keep in mind that it needs some Prerequisites fulfilled to work (all of them are also listed in the script) and you need to change line 34 to have your JamfServeradress in it. Beside this if you already switched to Bearertoken Authentication you need to do some changes to the setextensionattribute function to get a BearerToken and constructing the API-Call including it.
Prerequisites are:
1. Known Adminaccount from PreStage
2. API-Account with enough Privileges to write Extension Attributes
3. 2 Policies, first one to delete the Adminaccount (Customtrigger: accountdeletion) and a Second one to recreate it (Customtrigger accountcreation).
4. EA named autobootstrap (if you use a different name you need to change it in Line 36)
This script then is run in a Policy set to run with the Triggers "Enrollment Complete" and Check-In (for retry)
Excluding Computers that already have a BootstrapToken or the EA autobootstrap not being emtpy/retry
The script:

#!/bin/bash
# Author: Mengert, Florian (Ismere), Free University of Berlin
# Co-Author: TKu, Free University of Berlin
#
# This Scripts does a background Terminallogin to get a secureToken and escrowing bootstrap
# Intended Usage for ZeroTouch Enrollments with central Backupadmins, securing the secureToken on them
#
# Prerequisits:
#   1. Known Adminaccount
#   2. Known API-Account (EA write permissions)
#   3. Policy to delete and create account (customtrigger: accountdeletion ; accountcreation )
#   4. Extension Attribute to save status (StringValues Dropdown: success retry failed error
# Suggestion for Scope: SmartGroup with empty EA-Value or retry
# Suggested Trigger: Enrollment Complete and Recurring Check-in
# Retrying may repeat indefinetly if there is a generall problem with the connection to JAMF-Server
# 
# ERROR CODES
#   0 everything worked
#   1 non defined error
#   11 wrong admin user or password - accound maybe corrupt -> JAMF policy called by trigger accountdeletion & accountcreation
#   12 adminaccount without secureToken
#   13 could not save Bootstrap to Server (retry recommended)

# global variables from JAMF
admin="${4}"
pass="${5}"
apiUsername="${6}"
apiPassword="${7}"

# function to set extensionAttributes in JAMF (User/Pass Auth) 
setextensionattribute() {

    # Variables
    apiURL="yourJAMFServerURL"	# JSS URL without trailing forward slash
 
    eaName=autobootstrap                     				# Name of Extension Attribute
    eaValue="$1"                        					# Value for Extension Attribute
    computerUDID=$(/usr/sbin/system_profiler SPHardwareDataType | /usr/bin/awk '/Hardware UUID:/ { print $3 }')

    # Construct the API data
    apiData="<computer><extension_attributes><extension_attribute><name>${eaName}</name><value>${eaValue}</value></extension_attribute></extension_attributes></computer>"
    apiPut=`curl -H "Content-Type: text/xml" -sfu ${apiUsername}:${apiPassword} ${apiURL}/JSSResource/computers/udid/${computerUDID} -d "${apiData}" -X PUT` 

    # Execute API Call
    /bin/echo ${apiPut}    
}

# function wrap expect script
securebootstrap() {
expect <<EOD
    #using globaly defined arguments

    #starting login process
    spawn login $admin

    #waiting for password question and entering password
    expect {
        "Password:" {send "$pass\r"}
        "Login incorrect" {exit 11}
    }
    #checking for secureToken
    send "sysadminctl -secureTokenStatus $admin\r"

    expect {
        -re "ENABLED" {send "sudo profiles install -type bootstraptoken\r"}
        -re "DISABLED" {exit 12}
    }
    #interaction for creating Bootstraptoken
    expect "Password:"
    send -- "$pass\r"
    expect "Enter the admin user name:"
    send -- "$admin\r"
    expect "Enter the password for user 'admin':"
    send -- "$pass\r"
    #check for success or retry
    expect {
        -re "Bootstrap Token escrowed" {send "logout\r"}
        -re "Unable to save" {exit 13}
    }

    exit 0
EOD
}

# trying to create bootstrap 1st attempt
securebootstrap
# get last error code to check result
check1=$?
echo $check1
if [ $check1 -eq 11 ] 
then 
    # defined account not found or not working recreating account for 2nd attempt
    sudo jamf policy -event accountdeletion
    sudo jamf policy -event accountcreation
    # 2nd attempt
    securebootstrap
    #getting new errorcode, retaining old one for sanity
    check2=$?
    echo $check2
    if [ $check2 -eq 13 ]
    then
        # could not save
        setextensionattribute retry
        exit 13
    elif [ $check2 -eq 12 ]
    then
        # secureToken missing
        setextensionattribute failed
        exit 12
    elif [ $check2 -ne 0 ]
    then
        # undefined error
        setextensionattribute error
        exit 1
    else
        # created
        setextensionattribute success
        exit 0
    fi 
elif [ $check1 -eq 12 ]
then
    # secureToken missing
    setextensionattribute failed
    exit 12
elif [ $check1 -eq 13 ]
then
    # could not save
    setextensionattribute retry
    exit 13
elif [ $check1 -ne 0 ] 
then
    # undefined error
    setextensionattribute error
    exit 1
else
    # success
    setextensionattribute success
    exit 0  
fi


Hopefully this will help some more Admins out there.
Greetings Ismere

3 REPLIES 3

jwolff
New Contributor

I have a Mac that no user has a Secure Token and BootstrapToken is not in JAMF due to this. Will this script work to create a Secure Token and BootstrapToken?

 

 

Hi,
that depends on the full state of the computer. First off even without a Secure and BootstrapToken a Mac can be in JAMF. This version of the script even assumes that the Mac is in JAMF to delete and recreate a defective Adminuseraccount trough Policies.

If no User has logged into the Mac it is totally normal that no one has a Secure Token because the first account logging in is getting it.
If, for any Reason, there are already users on the Mac and there is still no Secure Token then sadly no this script will not help. This Script is more or less for freshly installed Macs.

Beside that i do not know how you will run a Script without logging in a User without the use of any MDM....
Eventually trying to activate FileVault can, sometimes, create the SecureToken you want but if even this is not working then reinstalling is the only option in my experience.

In our Case we are scooping this script trough a Policy with our specific credentials to every Computer right after they finished enrolment.

jwolff
New Contributor

Thank you for the thorough explanation, that's more of what I suspected and what I'd gathered that in the event (unknown why of the cause) that we have an M1 Mac that has had a user sign in and they didn't get a SecureToken after Filevault enablement, wiping/resetting the Mac is the best route.