Bash script to automated Email Notification when a USB Device is Connected
- Last updated: Dec 3, 2024
On a Debian GNU/Linux system, I've been working on a solution to notify users by e-mail when a USB hard disk drive is connected. The aim is to inform the system administrator that the USB drive is successfully connected.
- To achieve this, I used the following components:
- udev: a device manager that invokes a custom script
- msmtp: for sending emails
Installing and configuring msmtp
Here's an example with msmtp, which will send e-mails via the mail.std.rocks relay on SSL port 465.
- Install msmtp:
root@host:~# apt update && apt install msmtp
- Edit the
/etc/msmtprc
file:
account STD
#Mail Server :
host mail.std.rocks
port 465
from backup@std.rocks
#LOGIN / PASSWORD
user backup@std.rocks
password MyWeakPassword
auth on
tls on
tls_starttls on
tls_trust_file /etc/ssl/certs/ca-certificates.crt
tls_certcheck off
logfile /var/log/msmtp.log
account default : STD
udev
udev is a device manager for GNU/Linux systems that dynamically manages devices and their corresponding device nodes in the system. It stands for "userspace device" and operates in user space rather than kernel space. It will allow us to run a script when a USB disk device is connected.
Note: let's say the disk we want to monitor is /dev/sda- For your information, we can display all the attributes of the
/dev/sda
device:
root@host:~# udevadm info --attribute-walk --path=$(udevadm info --query=path --name=/dev/sda)
- Create a file
/etc/udev/rules.d/10_usb-disk.rules
:
ACTION=="add", SUBSYSTEM=="block", SUBSYSTEMS=="usb", RUN{program}+="/usr/local/sbin/mail_usb_disk.sh"
- Reload
udev
rules and configuration:
root@host:~# udevadm control --reload
Bash script
- Create the file
/usr/local/sbin/mail_usb_disk.sh
:
root@host:~# touch /usr/local/sbin/mail_usb_disk.sh && chmod +x /usr/local/sbin/mail_usb_disk.sh
- Edit
/usr/local/sbin/mail_usb_disk.sh
:
Edit 2023/07/01: I haven't tested this, but some people say it could be solved by adding ENV{DEVTYPE}=="usb_device" to the rule.
#! /bin/sh
MAIL_ADDRESS="backup@std.rocks"
DATE=$(/bin/date "+%Y-%m-%dT%H:%M:%S")
UDEV_TIME="$(/bin/date --date="$(stat /tmp/udev_time | grep Modif | sed 's/Modif.*: //')" +%s)" #get /tmp/udev_time creation time
touch /tmp/udev_time
CUR_TIME="$(/bin/date +%s)"
#difference between current time and /tmp/udev_time creation time
TIME_DIFF=$(( (CUR_TIME - UDEV_TIME) ))
#Function
mailto () {
LANG=C
rm -f /tmp/mail_usb_disk.header
echo "From: $MAIL_ADDRESS" >> /tmp/mail_usb_disk.header
echo "To: $MAIL_ADDRESS" >> /tmp/mail_usb_disk.header
echo "Date: "`/bin/date -R` >> /tmp/mail_usb_disk.header
echo "Subject: Disk has been plugged in" >> /tmp/mail_usb_disk.header
echo "Content-type: text/plain; charset=utf-8" >> /tmp/mail_usb_disk.header
echo "" >> /tmp/mail_usb_disk.header
echo "Disk has been plugged in" >> /tmp/mail_usb_disk.header
cat /tmp/mail_usb_disk.header | /usr/bin/msmtp -f "$MAIL_ADDRESS" "$MAIL_CLIENT"
rm -f /tmp/mail_usb_disk.header
}
#Send email if time difference is greater than 10s
if [ "$TIME_DIFF" -gt 10 ]; then
mailto
fi