CasperCheck | No Webserver?

TomDay
Release Candidate Programs Tester

Working to implement the awesome CasperCheck solution from @rtrouton , but I have no access to a web server to post by quickadd pkg to. Has anyone tried or had success hosting the quickadd file in Google Drive?

9 REPLIES 9

B-35405
Contributor

Yes, I use Google Drive to host the Quickadd package that's intended to be used more than once.

TomDay
Release Candidate Programs Tester

@B-35405 Not sure I have my permissions set properly, would you mind sharing how you have sharing set up for this file and what the file path look like for the file link in Drive?

perrycj
Contributor III

@TomDay I had to modify the original script a bit and we decided to bury the quickadd package within the OS and made the permissions so only root can access the QA pkg.

Also put in several layers of checks, in the forms of extension attributes and files that live on the OS, so that if any one of them were removed at any point, caspercheck would get installed again from the JSS.

TomDay
Release Candidate Programs Tester

@perrycj Mind if I take a look at your script?

perrycj
Contributor III

@TomDay Sure

#!/bin/bash



# For the jss_server_address variable, put the complete 
# fully qualified domain name address of your Casper server

jss_server_address=""

# For the jss_server_address variable, put the port number 
# of your Casper server. This is usually 8443; change as
# appropriate.

jss_server_port=""

# For the log_location variable, put the preferred 
# location of the log file for this script. If you 
# don't have a preference, using the default setting
# should be fine.

log_location=""


quickadd_dir=""
quickadd_installer=$(eval echo "$quickadd_dir""/QuickAdd.pkg")

# The variables below this line should not need to be edited.
# Use caution if doing so.


# Begin function section
# =======================
#
# Function to provide logging of the script's actions to
# the log file defined by the log_location variable

ScriptLogging(){

    DATE=`date +%Y-%m-%d %H:%M:%S`
    LOG="$log_location"

    echo "$DATE" " $1" >> $LOG
}

CheckForNetwork(){

# Determine if the network is up by looking for any non-loopback network interfaces.

    local test

    if [[ -z "${NETWORKUP:=}" ]]; then
        test=$(ifconfig -a inet 2>/dev/null | sed -n -e '/127.0.0.1/d' -e '/0.0.0.0/d' -e '/inet/p' | wc -l)
        if [[ "${test}" -gt 0 ]]; then
            NETWORKUP="-YES-"
        else
            NETWORKUP="-NO-"
        fi
    fi
}

CheckSiteNetwork (){

  #  CheckSiteNetwork function adapted from Facebook's check_corp function script.
  #  check_corp script available on Facebook's IT-CPE Github repo:
  #
  # check_corp:
  #   This script verifies a system is on the corporate network.
  #   Input: CORP_URL= set this to a hostname on your corp network
  #   Optional ($1) contains a parameter that is used for testing.
  #   Output: Returns a check_corp variable that will return "True" if on 
  #   corp network, "False" otherwise.
  #   If a parameter is passed ($1), the check_corp variable will return it
  #   This is useful for testing scripts where you want to force check_corp
  #   to be either "True" or "False"
  #   USAGE:
  #   check_corp         # No parameter passed
  #   check_corp "True"  # Parameter of "True" is passed and returned


  site_network="False"
  ping=`host -W .5 $jss_server_address`

  # If the ping fails - site_network="False"
  [[ $? -eq 0 ]] && site_network="True"

  # Check if we are using a test
  [[ -n "$1" ]] && site_network="$1"
}

#




CheckTomcat (){

# Verifies that the JSS's Tomcat service is responding via its assigned port.


tomcat_chk=`nc -z -w 5 $jss_server_address $jss_server_port > /dev/null; echo $?`

if [ "$tomcat_chk" -eq 0 ]; then
       ScriptLogging "Machine can connect to $jss_server_address over port $jss_server_port. Proceeding."
else
       ScriptLogging "Machine cannot connect to $jss_server_address over port $jss_server_port. Exiting CasperCheck."
       ScriptLogging "======== CasperCheck Finished ========"
       exit 0
fi

}


InstallCasper () {

 # Check for the cached Casper QuickAdd installer and run it
 # to fix problems with Casper being able to communicate with
 # the Casper server


    if [[ -f "$quickadd_installer" ]] ; then
        ScriptLogging "Casper installer is present. Installing."
        /usr/sbin/installer -dumplog -verbose -pkg "$quickadd_installer" -target /
        ScriptLogging "Casper agent has been installed."
    else
        ScriptLogging "Missing."
    fi


}

CheckCasper () {

  #  CheckCasper function adapted from Facebook's jamf_verify.sh script.
  #  jamf_verify script available on Facebook's IT-CPE Github repo:
  #  Link: https://github.com/facebook/IT-CPE



  # Checking for the jamf binary
  if [[ ! -f "/usr/local/bin/jamf" ]]; then
    ScriptLogging "Casper's jamf binary is missing. It needs to be reinstalled."
    InstallCasper
  fi

  # Verifying Permissions
  /usr/bin/chflags noschg /usr/local/bin/jamf
  /usr/bin/chflags nouchg /usr/local/bin/jamf
  /usr/sbin/chown root:wheel /usr/local/bin/jamf
  /bin/chmod 755 /usr/local/bin/jamf

  # Verifies that the JSS is responding to a communication query 
  # by the Casper agent. If the communication check returns a result
  # of anything greater than zero, the communication check has failed.
  # If the communication check fails, reinstall the Casper agent using
  # the cached installer.


  jss_comm_chk=`/usr/local/bin/jamf checkJSSConnection > /dev/null; echo $?`

  if [[ "$jss_comm_chk" -eq 0 ]]; then
       ScriptLogging "Machine can connect to the JSS on $jss_server_address."
  elif [[ "$jss_comm_chk" -gt 0 ]]; then
       ScriptLogging "Machine cannot connect to the JSS on $jss_server_address."
       ScriptLogging "Reinstalling Casper agent to fix problem of Casper not being able to communicate with the JSS."
       InstallCasper
  fi

  # Checking if machine can run a manual trigger
  # This section will need to be edited if the policy
  # being triggered has different options than the policy
  # described below:
  #
  # Trigger: iscasperup
  # Plan: Run Script iscasperonline.sh
  # 
  # The iscasperonline.sh script contains the following:
  #
  # | #!/bin/sh
  # |
  # | echo "up"
  # |
  # | exit 0
  #


  jamf_policy_chk=`/usr/local/bin/jamf policy -trigger iscasperup | grep "Script result: up"`

  # If the machine can run the specified policy, exit the script.

  if [[ -n "$jamf_policy_chk" ]]; then
    ScriptLogging "Casper enabled and able to run policies"

  # If the machine cannot run the specified policy, 
  # reinstall the Casper agent using the cached installer.

  elif [[ ! -n "$jamf_policy_chk" ]]; then
    ScriptLogging "Reinstalling Casper agent to fix problem of Casper not being able to run policies"
    InstallCasper
  fi


}

#
# End function section
# ====================
#

# The functions and variables defined above are used
# by the section below to check if the network connection
# is live, if the machine is on a network where
# the Casper JSS is accessible, and if the Casper agent on the
# machine can contact the JSS and run a policy.
#
# If the Casper agent on the machine cannot run a policy, the appropriate
# functions run and repair the Casper agent on the machine.
#

ScriptLogging "======== Starting CasperCheck ========"

# Wait up to 60 minutes for a network connection to become 
# available which doesn't use a loopback address. This 
# condition which may occur if this script is run by a 
# LaunchDaemon at boot time.
#
# The network connection check will occur every 5 seconds
# until the 60 minute limit is reached.


ScriptLogging "Checking for active network connection."
CheckForNetwork
i=1
while [[ "${NETWORKUP}" != "-YES-" ]] && [[ $i -ne 720 ]]
do
    sleep 5
    NETWORKUP=
    CheckForNetwork
    echo $i
    i=$(( $i + 1 ))
done

# If no network connection is found within 60 minutes,
# the script will exit.

if [[ "${NETWORKUP}" != "-YES-" ]]; then
   ScriptLogging "Network connection appears to be offline. Exiting CasperCheck."
fi


if [[ "${NETWORKUP}" == "-YES-" ]]; then
   ScriptLogging "Network connection appears to be live."

  # Sleeping for 15 seconds to give WiFi time to come online.
  ScriptLogging "Pausing for two minutes to give WiFi and DNS time to come online."
  sleep 15
  CheckSiteNetwork

  if [[ "$site_network" == "False" ]]; then
    ScriptLogging "Unable to verify access to site network. Exiting CasperCheck."
  fi 


  if [[ "$site_network" == "True" ]]; then
    ScriptLogging "Access to site network verified"
    CheckTomcat
    CheckCasper
  fi

fi

ScriptLogging "======== CasperCheck Finished ========"

exit 0

Just have to define the variables in the beginning of the script with details of your environment. Then make a package with this script, a launchdaemon and the quickadd package in the directory you want it to live. We give 705 permissions to the quickadd pkg (owner has RWX and everyone has RX but no W, group has nothing). We stash it in the /System/Library/user template directory, several layers deep.

The other thing is make sure the LaunchDaemon has permissions of 644 (owner RW and then group and everyone R only).

TomDay
Release Candidate Programs Tester

Thx for posting @perrycj, appreciate you sharing. Finally able to jump back on this project after getting pulled in so many other directions. As I work more on this I think I must be doing something wrong in my script somewhere, when I run just the script as a test to check connections etc the script quits quickly.

Here are my results in verbose mode when I am connected to Ethernet:

Checking for policies triggered by "iscasper" for user "tom"...
 verbose: Checking for active ethernet connection...
 verbose: Active ethernet connection found...
 verbose: Removing any cached policies for this trigger.
 verbose: Parsing servers...
 verbose: The Management Framework Settings are up to date.
No policies were found for the "iscasper" trigger.

Here are my results in verbose mode when I am connected to just WiFi:

Checking for policies triggered by "iscasper" for user "tom"...
 verbose: Checking for active ethernet connection...
 verbose: No active ethernet connection found...
 verbose: Removing any cached policies for this trigger.
 verbose: Parsing servers...
 verbose: The Management Framework Settings are up to date.
No policies were found for the "iscasper" trigger.

perrycj
Contributor III

Hey @TomDay You have to make a policy that has the trigger iscasperup or whatever you want to call it. The instructions are in my example, which is taken from the original workflow this was adapted from by @rtrouton

It looks like you don't have that policy set up yet in your JSS and therefore are getting that message.

TomDay
Release Candidate Programs Tester

@perrycj Good catch! SMH at myself as I used the wrong manual trigger, the policy and script execute as designed now!

Follow up question, just want to confirm that you are creating 1 pkg that includes the script, a launchdaemon and the quickadd package? ---> "Then make a package with this script, a launchdaemon and the quickadd package in the directory you want it to live."

perrycj
Contributor III

@TomDay Yup just all in one package.