Posted on 10-31-2017 04:06 PM
Yesterday, my boss approached me and handed me this challenge...
THERE ARE NO ISSUES - ONLY OPPORTUNITIES TO IMPROVE
"I need to acquire the /var/log/system.log from user X. I don't want to walk over to the user's desk. We might need to do this again in the future. Can Jamf do this?"
My immediate response was, "Why yes! Jamf CAN do this!"
INTO THE WEEDS WE GO
Here are the hurdles I had to endure...
This leaves me to figure out how to drop files into a secure location on a particular cloud sharing platform OR use email.
I chose email...
LET'S GET SCRIPTING, KIDDIES
So here is the script I wrote. It's far from perfect. I'm sure there some stuff I could do better.
The script zips up /var/logs/system.log into a nice, neat package with a unique file name and saves it to /tmp/.
The script then sends the zip file via sendmail as an attachment to the email address of your choice, but before we can do that, we need to enable postfix on the Mac.
We also need to do some fancy footwork on mime encoding, etc. YOIKES!
And then there's house keeping duties.
At the end of the day, I placed the following script into a Self Service policy...
You'll have to edit certain stuffs so this works in your environment - stuffs such as to/from email addresses, etc.
NOTE - The script can also be run in stand-alone mode without Jamf.
#!/bin/bash
# Description: Sends a user's /var/log/system.log to the email address of your choosing
# Written by Caine Hörr
# Written on 2017-10-31
# I gratuitously cannibalized sendmail code from http://backreference.org/2013/05/22/send-email-with-attachments-from-script-or-command-line/
main(){
sanity_checks # Check all required dependencies
postfix_lookup_table_modify # Create/Modify the Postfix lookup table from the sasl_passwd file
postfix_stop_service # Stop postfix
postfix_start_service # Start postfix
local_system_attributes # Acquire and format system specific attributes
compress_log_files # Compress log files in to zip format
generate_email # Creates and sends email containing log files
cleanup # Cleanup / Housekeeping
quit # Quit notification
}
sanity_checks(){
run_as_root
postfix_main_cf_confirmation
postfix_sasl_password_confirmation
}
run_as_root(){
# Check for admin/root permissions
if [ "$(id -u)" != "0" ]; then
# Quit script immediately.
echo "Script must be run as root, or have root privileges (ie. sudo)."
quit
exit 1
fi
}
postfix_main_cf_confirmation(){
# Set variable
main_cf="/etc/postfix/main.cf"
# Check existence of /etc/postfix/main.cf
if [ -f "${main_cf}" ]; then
echo "SUCCESS: ${main_cf} exists."
# Confirm contents of /etc/postfix/main.cf are correct...
postfix_main_cf_check_settings
# Return to sanity_checks
else
# Fatal error. Quit script immediately.
echo "ERROR: ${main_cf} does not exist!"
quit
exit 1
fi
}
postfix_main_cf_check_settings(){
# Set variable
main_cf_settings=`more /etc/postfix/main.cf | grep -i "SOME VALUE THAT YOU WANT TO SEARCH FOR GOES HERE"`
if [ "${main_cf_settings}" = "# SOME VALUE THAT YOU WANT TO SEARCH FOR GOES HERE SMTP Relay Settings" ]; then
echo "SUCCESS: ${main_cf} has been configured with proper settings."
else
echo "WARNING: ${main_cf} has not been configured with proper settings."
# Append settings to /etc/postfix/main.cf
postfix_main_cf_configure_settings
fi
}
postfix_main_cf_configure_settings(){
# Write the following contents to /etc/postfix/main.cf
echo "NOTICE: Configuring ${main_cf} with proper settings."
cat <<EOT >> /etc/postfix/main.cf
# SOME VALUE THAT YOU WANT TO SEARCH FOR GOES HERE SMTP Relay Settings
relayhost=smtp.yourcompany.com:587
smtp_sasl_auth_enable=yes
smtp_sasl_password_maps=hash:/etc/postfix/sasl_passwd
smtp_use_tls=yes
smtp_tls_security_level=encrypt
tls_random_source=dev:/dev/urandom
smtp_sasl_security_options=noanonymous
smtp_always_send_ehlo=yes
smtp_sasl_mechanism_filter=plain
EOT
echo "SUCCESS: ${main_cf} has been configured with proper settings."
}
postfix_sasl_password_confirmation(){
# Set variable
sasl_passwd="/etc/postfix/sasl_passwd"
# Check existence of /etc/postfix/sasl_passwd
if [ -f "${sasl_passwd}" ]; then
echo "SUCCESS: ${sasl_passwd} exists."
# Confirm contents of /etc/postfix/sasl_passwd are correct...
postfix_sasl_passwd_check_settings
else
echo "WARNING: ${sasl_passwd} does not exist."
# Create /etc/postfix/sasl_passwd with coreect contents...
postfix_sasl_passwd_create_modify
fi
}
postfix_sasl_passwd_check_settings(){
sasl_passwd_settings=`more /etc/postfix/sasl_passwd | grep "smtp.yourcompany.com"`
if [ "${sasl_passwd_settings}" = "smtp.yourcompany.com:587 username:password" ]; then
echo "SUCCESS: ${sasl_passwd} has been configured with correct settings."
else
echo "WARNING: ${sasl_passwd} has not been configured with correct settings."
# Append correct settings to /etc/postfix/sasl_passwd
fi
}
postfix_sasl_passwd_create_modify(){
# Write the following contents to /etc/postfix/sasl_passwd
echo "NOTICE: Configuring ${sasl_passwd} with correct settings."
cat <<EOT >> /etc/postfix/sasl_passwd
smtp.yourcompany.com:587 username:password
EOT
}
postfix_lookup_table_modify(){
# Create/Modify the Postfix lookup table from the sasl_passwd file
# This will create /etc/postfix/sasl_passwd.db
echo "NOTICE: Creating the postfix lookup table."
sudo postmap /etc/postfix/sasl_passwd
}
postfix_stop_service(){
# Stop postfix
echo "NOTICE: Stopping the postfix service."
sudo /usr/sbin/postfix stop
}
postfix_start_service(){
# Start postfix
echo "NOTICE: Starting the postfix service."
sudo /usr/sbin/postfix start
}
local_system_attributes(){
local_username=`/usr/bin/stat -f "%Su" /dev/console`
echo "Local Username: ${local_username}"
local_hostname=`hostname`
echo "Local Hostname: ${local_hostname}"
local_date=`date +"%Y-%m-%d_%I%M%S%p_%Z"`
echo "Local Date: ${local_date}"
}
compress_log_files(){
# Compress system.log file
log_file_path="/var/log/system.log"
zip_file_name="${local_date}_${local_hostname}_${local_username}.zip"
zip_file_path="/tmp/${zip_file_name}"
echo "Compressing ${log_file_path} to ${zip_file_path}"
zip ${zip_file_path} ${log_file_path}
}
generate_email(){
# some variables
# refactoring the script such that all these values are
# passed from the outside as arguments should be easy
from="jss@yourcompany.com"
to="recipient@yourcompany.com"
subject="${zip_file_name} from Jamf Pro Self Service"
boundary="ZZ_/afg6432dfgkl.94531q"
body="See attached zip file"
declare -a attachments
attachments="${zip_file_path}"
mimetype="application/zip"
# Build headers
{
printf '%s
' "From: $from
To: $to
Subject: $subject
Mime-Version: 1.0
Content-Type: multipart/mixed; boundary="${boundary}"
--${boundary}
Content-Type: text/plain; charset="US-ASCII"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline
$body
--${boundary}
Content-Type: application/zip
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="${zip_file_path}"
"
base64 "$zip_file_path"
echo
# print last boundary with closing --
printf '%s
' "--${boundary}--"
} | sendmail -t -oi # one may also use -f here to set the envelope-from
}
cleanup(){
rm -f ${zip_file_path}
}
quit(){
# Quit notification.
echo "Quitting..."
}
main
exit
FOLLOW-UP
So hay - if you have any thoughts or suggestions to make this better... I'm all ears!
Thanks for reading!
Cheers!
Caine Hörr
A reboot a day keeps the admin away!
Posted on 10-31-2017 06:21 PM
You couldn't just use curl with a PUT to a webserver? Or would that contravene other organisational rules?
I have no actual idea how to configure this, just thought it might be easier than emailing and could be given a front end for easily reading the files as well.
Posted on 11-01-2017 01:15 PM
Great share Caine, Thank you !!!
C
Posted on 11-01-2017 02:10 PM
I would look into something like ElasticSearch/Logstash to accomplish like something this. Use Jamf to install MetricBeat on end user machines, and have the logs sent to ES and displayed with a tool like Kibana on a central server. This is what we use in production and it’s a life saver having all that raw data accesssible and graphable in the browser.
Posted on 12-29-2017 03:17 PM
If such options were (or should become) available to me, I'd certainly make use of them! ;-)
Caine Hörr
A reboot a day keeps the admin away!
Posted on 01-06-2021 04:28 PM
does this script still work??? the logs look like its working but I dont see the file in the /tmp folder. and I dont get any emails.