Issue
I have this shell running in OPNSense to check any new DHCP releases that don't match with the table and send an alert email. However, this code is very cpu consuming. I might try to put the changes of the given time period, and compare those.
Do you guys any have any better ideas?
#!/usr/local/bin/bash
# Define the location of the static DHCP release file
STATIC_DHCP_FILE="/var/dhcpd/etc/dhcpd.conf"
# Define the location of the new DHCP release file
NEW_DHCP_FILE="/var/log/dhcpd/latest.log"
# Define the subject of the email
SUBJECT="New DHCP Release Detected"
# Define the last line of the file
LAST_LINE=$(tail -n 1 "$NEW_DHCP_FILE")
# Create last line file
touch /tmp/last_match
while true; do
# Check if the file has changed
if ! cmp -s /tmp/last_match "$NEW_DHCP_FILE"; then # Use cmp instead of diff
LAST_LINE=$(tail -n 1 "$NEW_DHCP_FILE")
DHCP_MODE=$(echo "$LAST_LINE" | awk '{print $9}')
if [ "$DHCP_MODE" == "DHCPOFFER" ]; then
IP=$(echo "$LAST_LINE" | awk '{print $11}')
MAC=$(echo "$LAST_LINE" | awk '{print $13}')
ETH=$(echo "$LAST_LINE" | awk '{print $15}')
if ! grep -qi "$MAC" "$STATIC_DHCP_FILE"; then
# Run the nmap command and store the output in a variable
OUTPUT=$(nmap -sP "$IP")
# Extract the hostname from the output using grep and cut
HOSTNAME=$(echo "$OUTPUT" | grep -m 1 "Nmap scan report for" | cut -d " " -f 5)
echo "$LAST_LINE" > /tmp/last_match
BODY=`printf "A new DHCP release has been detected for an unknown device. The details are as follows:\n\nOn $(date)\nIP Address: $IP\nMAC Address: $MAC\nHostname: $HOSTNAME\n"`
echo -e "$BODY"
sleep 3
python3 /root/sendmail.py -s "$SUBJECT" -a "$BODY"
fi
fi
fi
done
Solution
Don't call awk
multiple times when only one is needed.
More importantly, don't busy-wait / poll. Just read new data when it arrives.
For example:
static_dhcp_file=/var/dhcpd/etc/dhcpd.conf
new_dhcp_file=/var/log/dhcpd/latest.log
subject="New DHCP Release Detected"
tail -f -n1 "$new_dhcp_file" |
while read _ _ _ _ _ _ _ _ mode _ ip _ mac _ eth _; do
if [[ $mode = DHCP_OFFER ]] && ! grep -qi $mac "$static_dhcp_file"; then
host=$(nmap -sP $ip | awk '/Nmap scan report for/ { print $5; exit }')
body=$(printf "A new DHCP release has been detected for an unknown device. The details are as follows:\n\nOn $(date)\nIP Address: ${ip}\nMAC Address: ${mac}\nHostname: ${host}\n")
echo "$body"
sleep 3
python3 /root/sendmail.py -s "$subject" -a "$body"
fi
done
Note that your original code could theoretically miss changes. If more than one new line is added to latest.log
during your sleep 3
, only the final one will be noticed.
Answered By - jhnc Answer Checked By - Timothy Miller (WPSolving Admin)