by Tykling
25. feb 2018 13:10 UTC
The nature of Ansible is that it connects to the hosts in its inventory files over SSH. This opens up some new possibilities since I now have a place which has SSH access to the rest of the infrastructure, which I can use to automate various monitoring scripts.
I've recently added this script to my Ansible roles and wanted to post it here. It is very simple, nothing fancy about it, it just loops over the hostnames found in the Ansible inventory files, SSHs into each (using Ansibles shell module, and runs pkg audit -F. If a problem is found it sends the output in an email to the email address specified on the commandline.
My ansible_server Ansible role adds this script to crontab on the Ansible servers on the different infrastructures I manage. This means that I get an email if one or more vulnerable packages was found on a server.
The same information is available in the FreeBSD daily periodic security run output emails, but since those mails come every night, and not only when something needs to be acted on, they tend to get overlooked.
Enough talk, here is the code:
#!/bin/sh
# the main function
check_inventory() {
# find unique hosts in ansible inventory file and loop over them
for host in $(grep -Ev "(\\[|^#|^$)" "$1" | sort | uniq); do
# get the pkg audit output, run with -F to ensure we have a fresh vuln xml
output=$(/usr/local/bin/ansible "$host" -m shell -b -a "/usr/sbin/pkg audit -F" -i "$1")
if [ $? -ne 0 ]; then
# vulns found, or ansible could not connect, send email regardless
echo "$output" | mail -s "$(basename "$1") - $host: Vulnerable packages found!" "$2"
fi
done
}
# do we have an email?
if [ $# -ne 1 ]; then
echo "usage: $0 "
exit 1
fi
# loop over inventory files and check them
for file in /usr/local/etc/ansible/*_hosts; do
check_inventory "$file" "$1"
done
By convention my Ansible inventory files are called production_hosts, staging_hosts and so on, so the glob in the script is *_hosts, YMMV.