Nell’attuale panorama IT, la gestione degli account utente e la garanzia di un accesso sicuro sono fondamentali per mantenere una solida sicurezza del sistema. Uno degli aspetti chiave di questa gestione su macOS è l’uso di token sicuri. I token sicuri sono fondamentali per varie funzioni di sicurezza, tra cui l’abilitazione di FileVault e l’esecuzione di alcune attività amministrative.
In questo articolo analizzeremo uno script che automatizza il processo di concessione dell’accesso sicuro con token agli account utente su macOS, spiegandone l’importanza, le funzionalità e i casi d’uso per i professionisti IT e i Managed Service Provider (MSP).
Background
I token sicuri sono una funzione di sicurezza di macOS che fornisce ulteriori misure di autenticazione, in particolare per quanto riguarda la crittografia FileVault. Per i professionisti IT e gli MSP, la gestione di questi token è essenziale per mantenere ambienti sicuri su numerosi dispositivi.
Lo script fornito semplifica il processo di concessione dell’accesso con token sicuro a un account utente, creando persino l’account se non esiste già. Questa automazione è particolarmente vantaggiosa in ambienti su larga scala, dove la configurazione manuale sarebbe poco pratica e dispendiosa in termini di tempo.
Lo script per creare token sicuri in macOS
#!/usr/bin/env bash # Description: Grants secure token access to Service Account. Account will be created if it doesn't exist. Service Accounts will not show up at the desktop login. # Release Notes: Initial Release # # Custom Fields: # New Account Password Custom Field: A secure custom field that stores the password for the new user account. # Optional Authentication Account Username Custom Field: A secure custom field that stores the username of the admin account that has secure token already on the device. # # Parameters: # username: Username to grant secure token access to # password: Password of user to grant secure token access to # adminuser: (Optional) Secure token Admin username - leave blank to prompt local user # adminpassword: (Optional) Secure token Admin password - leave blank to prompt local user # # Usage: ./Create-SecureTokenAccount.sh <-u|--username <arg>> <-p|--password <arg>> [-a|--adminuser <arg>] [-d|--adminpassword <arg>] # <> are required # [] are optional # Example: ./Create-SecureTokenAccount.sh --username test --password Password1 --adminuser admin --adminpassword Password2 # # Notes: # By using this script, you indicate your acceptance of the following legal terms as well as our Terms of Use at https://www.ninjaone.com/terms-of-use. # Ownership Rights: NinjaOne owns and will continue to own all right, title, and interest in and to the script (including the copyright). NinjaOne is giving you a limited license to use the script in accordance with these legal terms. # Use Limitation: You may only use the script for your legitimate personal or internal business purposes, and you may not share the script with another party. # Republication Prohibition: Under no circumstances are you permitted to re-publish the script in any script library or website belonging to or under the control of any other software provider. # Warranty Disclaimer: The script is provided “as is” and “as available”, without warranty of any kind. NinjaOne makes no promise or guarantee that the script will be free from defects or that it will meet your specific needs or expectations. # Assumption of Risk: Your use of the script is at your own risk. You acknowledge that there are certain inherent risks in using the script, and you understand and assume each of those risks. # Waiver and Release: You will not hold NinjaOne responsible for any adverse or unintended consequences resulting from your use of the script, and you waive any legal or equitable rights or remedies you may have against NinjaOne relating to your use of the script. # EULA: If you are a NinjaOne customer, your use of the script is subject to the End User License Agreement applicable to you (EULA). # # die() { local _ret="${2:-1}" test "${_PRINT_HELP:-no}" = yes && print_help >&2 echo "$1" >&2 exit "${_ret}" } begins_with_short_option() { local first_option all_short_options='upadvh' first_option="${1:0:1}" test "$all_short_options" = "${all_short_options/$first_option/}" && return 1 || return 0 } GetCustomField() { customfieldName=$1 dataPath=$(printenv | grep -i NINJA_DATA_PATH | awk -F = '{print $2}') value="" if [ -e "${dataPath}/ninjarmm-cli" ]; then value=$("${dataPath}"/ninjarmm-cli get "$customfieldName") else value=$(/Applications/NinjaRMMAgent/programdata/ninjarmm-cli get "$customfieldName") fi if [[ "${value}" == *"Unable to find the specified field"* ]]; then echo "" return 1 else echo "$value" fi } # THE DEFAULTS INITIALIZATION - OPTIONALS _arg_username= _arg_password= _arg_adminuser= _arg_adminpassword= print_help() { printf '%s\n' "Grants secure token access to an account. Account will be created if it doesn't exist." printf 'Usage: %s <-u|--username <arg>> <-p|--password <arg>> [-a|--adminuser <arg>] [-d|--adminpassword <arg>] [-h|--help]\n' "$0" printf '\t%s\n' "-u, --username: Username to grant secure token access to. (Required)" printf '\t%s\n' "-p, --password: Password of user to grant secure token access to. (Required)" printf '\t%s\n' "-a, --adminuser: (Optional) Secure token Admin username. (Leave blank to prompt local user)" printf '\t%s\n' "-d, --adminpassword: (Optional) Secure token Admin password. (Leave blank to prompt local user)" printf '\t%s\n' "-h, --help: Prints help" } parse_commandline() { while test $# -gt 0; do _key="$1" case "$_key" in -u | --username) test $# -lt 2 && die "Missing value for the optional argument '$_key'." 1 _arg_username="$2" shift ;; --username=*) _arg_username="${_key##--username=}" ;; -u*) _arg_username="${_key##-u}" ;; -p | --password) test $# -lt 2 && die "Missing value for the optional argument '$_key'." 1 _arg_password="$2" shift ;; --password=*) _arg_password="${_key##--password=}" ;; -p*) _arg_password="${_key##-p}" ;; -a | --adminuser) test $# -lt 2 && die "Missing value for the optional argument '$_key'." 1 _arg_adminuser="$2" shift ;; --adminuser=*) _arg_adminuser="${_key##--adminuser=}" ;; -a*) _arg_adminuser="${_key##-a}" ;; -d | --adminpassword) test $# -lt 2 && die "Missing value for the optional argument '$_key'." 1 _arg_adminpassword="$2" shift ;; --adminpassword=*) _arg_adminpassword="${_key##--adminpassword=}" ;; -d*) _arg_adminpassword="${_key##-d}" ;; -h | --help) print_help exit 0 ;; -h*) print_help exit 0 ;; *) _PRINT_HELP=yes die "FATAL ERROR: Got an unexpected argument '$1'" 1 ;; esac shift done } parse_commandline "$@" # Get Script Variables and override parameters if [[ -n $(printenv | grep -i newAccountUsername | awk -F = '{print $2}') ]]; then _arg_username=$(printenv | grep -i newAccountUsername | awk -F = '{print $2}') fi if [[ -n $(printenv | grep -i newAccountPasswordCustomField | awk -F = '{print $2}') ]]; then # Get the password from the custom field if ! _arg_password=$(GetCustomField "$(printenv | grep -i newAccountPasswordCustomField | awk -F = '{print $2}')"); then # Exit if the custom field is empty if [[ -z "${_arg_password}" ]]; then echo "[Error] Custom Field ($(printenv | grep -i newAccountPasswordCustomField | awk -F = '{print $2}')) was not found. Please check that the custom field contains a password." exit 1 fi # Exit if the custom field is not found echo "[Error] Custom Field ($(printenv | grep -i newAccountPasswordCustomField | awk -F = '{print $2}')) was not found. Please check the custom field name." exit 1 fi fi if [[ -n $(printenv | grep -i optionalAuthenticationAccountUsername | awk -F = '{print $2}') ]]; then _arg_adminuser=$(printenv | grep -i optionalAuthenticationAccountUsername | awk -F = '{print $2}') fi if [[ -n $(printenv | grep -i optionalAuthenticationAccountPasswordCustomField | awk -F = '{print $2}') ]]; then # Get the password from the custom field if ! _arg_adminpassword=$(GetCustomField "$(printenv | grep -i optionalAuthenticationAccountPasswordCustomField | awk -F = '{print $2}')"); then # Exit if the custom field is empty if [[ -z "${_arg_adminpassword}" ]]; then echo "[Error] Custom Field ($(printenv | grep -i optionalAuthenticationAccountPasswordCustomField | awk -F = '{print $2}')) was not found. Please check that the custom field contains a password." exit 1 fi # Exit if the custom field is not found echo "[Error] Custom Field ($(printenv | grep -i optionalAuthenticationAccountPasswordCustomField | awk -F = '{print $2}')) was not found. Please check the custom field name." exit 1 fi fi # If both username and password are empty if [[ -z "${_arg_username}" ]]; then echo "[Error] User Name is required." if [[ -z "${_arg_password}" ]]; then echo "[Error] Password is required, please set the password in the secure custom field." fi exit 1 fi # If username is not empty and password is empty if [[ -n "${_arg_username}" ]] && [[ -z "${_arg_password}" ]]; then echo "[Error] Password is required, please set the password in the secure custom field." exit 1 fi # If username is not empty and password is empty if [[ -n "${_arg_adminuser}" ]] && [[ -z "${_arg_adminpassword}" ]]; then echo "[Error] Password is required, please set the password in the secure custom field." exit 1 fi UserAccount=$_arg_username UserPass=$_arg_password UserFullName="ServiceAccount" secureTokenAdmin=$_arg_adminuser secureTokenAdminPass=$_arg_adminpassword macOSVersionMajor=$(sw_vers -productVersion | awk -F . '{print $1}') macOSVersionMinor=$(sw_vers -productVersion | awk -F . '{print $2}') macOSVersionBuild=$(sw_vers -productVersion | awk -F . '{print $3}') # Check script prerequisites. # Exits if macOS version predates the use of SecureToken functionality. # Exit if macOS < 10. if [ "$macOSVersionMajor" -lt 10 ]; then echo "[Warn] macOS version ${macOSVersionMajor} predates the use of SecureToken functionality, no action required." exit 0 # Exit if macOS 10 < 10.13.4. elif [ "$macOSVersionMajor" -eq 10 ]; then if [ "$macOSVersionMinor" -lt 13 ]; then echo "[Warn] macOS version ${macOSVersionMajor}.${macOSVersionMinor} predates the use of SecureToken functionality, no action required." exit 0 elif [ "$macOSVersionMinor" -eq 13 ] && [ "$macOSVersionBuild" -lt 4 ]; then echo "[Warn] macOS version ${macOSVersionMajor}.${macOSVersionMinor}.${macOSVersionBuild} predates the use of SecureToken functionality, no action required." exit 0 fi fi # Exits if $UserAccount already has SecureToken. if sysadminctl -secureTokenStatus "$UserAccount" 2>&1 | grep -q "ENABLED"; then echo "${UserAccount} already has a SecureToken. No action required." exit 0 fi # Exits with error if $secureTokenAdmin does not have SecureToken # (unless running macOS 10.15 or later, in which case exit with explanation). if [ -n "$secureTokenAdmin" ]; then if sysadminctl -secureTokenStatus "$secureTokenAdmin" 2>&1 | grep -q "DISABLED"; then if [ "$macOSVersionMajor" -gt 10 ] || [ "$macOSVersionMajor" -eq 10 ] && [ "$macOSVersionMinor" -gt 14 ]; then echo "[Warn] Neither ${secureTokenAdmin} nor ${UserAccount} has a SecureToken, but in macOS 10.15 or later, a SecureToken is automatically granted to the first user to enable FileVault (if no other users have SecureToken), so this may not be necessary. Try enabling FileVault for ${UserAccount}. If that fails, see what other user on the system has SecureToken, and use its credentials to grant SecureToken to ${UserAccount}." exit 0 else echo "[Error] ${secureTokenAdmin} does not have a valid SecureToken, unable to proceed. Please update to another admin user with SecureToken." exit 1 fi else echo "[Info] Verified ${secureTokenAdmin} has SecureToken." fi fi # Creates a new user account. create_user() { # Check if the user account exists if id "$1" >/dev/null 2>&1; then echo "[Info] Found existing user account $1." else echo "[Warn] Account $1 doesn't exist. Attempting to create..." # Create a new user dscl . -create /Users/"$1" # Add the display name of the User dscl . -create /Users/"$1" RealName "$3" # Replace password_here with your desired password to set the password for this user dscl . -passwd /Users/"$1" "$2" # Set the Unique ID for the New user. Replace with a number that is not already taken. LastID=$(dscl . -list /Users UniqueID | sort -nr -k 2 | head -1 | grep -oE '[0-9]+$') NextID=$((LastID + 1)) dscl . -create /Users/"$1" UniqueID $NextID # Set the group ID for the user dscl . -create /Users/"$1" PrimaryGroupID 20 # Append the User with admin privilege. If this line is not included the user will be set as standard user. # sudo dscl . -append /Groups/admin GroupMembership "$1" echo "[Info] Account $1 created." fi } # Adds SecureToken to target user. securetoken_add() { if [ -n "$3" ]; then # Admin user name was given. Do not prompt the user. sysadminctl \ -secureTokenOn "$1" \ -password "$2" \ -adminUser "$3" \ -adminPassword "$4" else # Admin user name was not given. Prompt the local user. currentUser=$(stat -f%Su /dev/console) currentUserUID=$(id -u "$currentUser") launchctl asuser "$currentUserUID" sudo -iu "$currentUser" \ sysadminctl \ -secureTokenOn "$1" \ -password "$2" \ interactive fi # Verify successful SecureToken add. secureTokenCheck=$(sysadminctl -secureTokenStatus "${1}" 2>&1) if echo "$secureTokenCheck" | grep -q "DISABLED"; then echo "[Error] Failed to add SecureToken to ${1}. Please rerun policy; if issue persists, a manual SecureToken add will be required to continue." exit 126 elif echo "$secureTokenCheck" | grep -q "ENABLED"; then echo "[Info] Successfully added SecureToken to ${1}." else echo "[Error] Unexpected result, unable to proceed. Please rerun policy; if issue persists, a manual SecureToken add will be required to continue." exit 1 fi } # Create new user if it doesn't already exist. create_user "$UserAccount" "$UserPass" "$UserFullName" # Add SecureToken using provided credentials. securetoken_add "$UserAccount" "$UserPass" "$secureTokenAdmin" "$secureTokenAdminPass"
Analisi dettagliata
Panoramica dello script
Lo script in questione è progettato per garantire l’accesso sicuro tramite token a un account utente su macOS, con la possibilità di creare l’account se non esiste già. Ecco una descrizione dettagliata, passo per passo, di come funziona lo script per creare token sicuri in macOS:
- Parsing dei parametri: Lo script per creare token sicuri in macOS inizia definendo una funzione die per gestire gli errori e una funzione print_help per visualizzare le informazioni di utilizzo. Analizza quindi gli argomenti della riga di comando per estrarre il nome utente, la password e, facoltativamente, il nome utente e la password dell’amministratore.
- Variabili d’ambiente: Controlla la presenza di variabili d’ambiente che possono sovrascrivere i parametri della riga di comando. Se sono impostate variabili d’ambiente specifiche, lo script per creare token sicuri in macOS recupera i loro valori per utilizzarli come parametri.
- Controllo della versione di macOS: Lo script per creare token sicuri in macOS controlla la versione di macOS per verificare che supporti la funzionalità di token sicuro. Esce se la versione di macOS è troppo vecchia per utilizzare i token sicuri.
- Controllo dello stato del token sicuro: Controlla se l’account utente specificato ha già un token sicuro. Se l’account utente dispone già di un token sicuro, lo script per creare token sicuri in macOS termina, poiché non sono necessarie ulteriori azioni.
- Controllo del token utente amministratore: Se viene fornito un nome utente amministratore, lo script per creare token sicuri in macOS verifica che questo utente amministratore abbia un token sicuro. Se non c’è, lo script esce con un errore, a meno che la versione di macOS sia la 10.15 o successiva; in quel caso si consiglia di utilizzare un processo diverso.
- Creazione dell’account utente: Lo script per creare token sicuri in macOS include una funzione per creare un nuovo account utente se non esiste già. Assegna un ID univoco, imposta una password e configura altri attributi necessari.
- Concessione di un token sicuro: Lo script per creare token sicuri in macOS tenta di concedere un token sicuro all’account utente specificato, utilizzando le credenziali fornite. Se viene fornito il nome utente dell’amministratore, vengono utilizzate quelle credenziali; altrimenti, viene richiesta l’autenticazione dell’utente locale.
Casi d’uso potenziali
Immagina un professionista IT di nome Alex che gestisce un parco di dispositivi macOS per una grande azienda. Alex deve assicurarsi che tutti gli account utente su questi dispositivi abbiano token sicuri per la crittografia FileVault. Controllare e concedere manualmente i token sicuri su ogni dispositivo richiederebbe molto tempo.
Distribuendo questo script per creare token sicuri in macOS attraverso uno strumento di gestione centralizzato, Alex può automatizzare il processo, assicurandosi che tutti gli account utente dell’organizzazione dispongano dei token sicuri necessari e mantenendo così la conformità con i criteri di sicurezza dell’azienda.
Confronti
Altri metodi per creare token sicuri in macOS comportano in genere l’intervento manuale attraverso le Preferenze di sistema di macOS o l’uso di comandi sysadminctl individualmente per ogni utente. Pur funzionando, questi metodi non sono scalabili per la gestione di un gran numero di dispositivi. Lo script per creare token sicuri in macOS automatizza queste fasi, rendendole più efficienti e riducendo la probabilità di errore umano.
Domande frequenti
-
Cosa succede se l’account utente esiste già?
Lo script per creare token sicuri in macOS verifica l’esistenza dell’account utente e, se esiste già, salta la fase di creazione.
-
Posso utilizzare questo script per creare token sicuri in macOS su versioni precedenti di macOS?
Lo script per creare token sicuri in macOS include controlli per garantire che venga eseguito solo sulle versioni di macOS che supportano i token sicuri, in particolare macOS 10.13.4 e versioni successive.
-
Cosa succede se l’utente amministratore non ha un token sicuro?
Lo script per creare token sicuri in macOS esce con un errore se l’utente amministratore non dispone di un token sicuro, tranne che su macOS 10.15 o successivo, dove viene suggerita una procedura alternativa.
Implicazioni
La concessione di token sicuri agli account utente è fondamentale per abilitare FileVault ed eseguire le attività amministrative in modo sicuro. L’automazione di questo processo contribuisce a mantenere elevati standard di sicurezza, a garantire la conformità ai criteri organizzativi e a ridurre il rischio di accessi non autorizzati.
Raccomandazioni
- Aggiorna regolarmente lo script: Assicurati che lo script per creare token sicuri in macOS sia aggiornato con le ultime modifiche di macOS e di seguire le pratiche di sicurezza.
- Campi personalizzati sicuri: Utilizza campi personalizzati sicuri per memorizzare informazioni sensibili come le password.
- Gestione centralizzata: Distribuisci lo script per creare token sicuri in macOS attraverso uno strumento di gestione centralizzato per garantire la coerenza tra tutti i dispositivi.
Considerazioni finali
Automatizzare il processo di concessione dei token sicuri mediante questo script per creare token sicuri in macOS migliora notevolmente l’efficienza e la sicurezza della gestione dei dispositivi macOS. Per i professionisti IT e gli MSP, questo script è uno strumento prezioso per mantenere solide pratiche di sicurezza.
NinjaOne offre soluzioni complete che si integrano perfettamente con script come questo, fornendo un approccio strutturato alla gestione e alla sicurezza IT. Utilizzando NinjaOne, è possibile ottimizzare i flussi di lavoro e garantire che tutti i dispositivi siano sicuri e conformi ai criteri dell’organizzazione.