rss logo

Bash script to automated Email Notification upon USB Device Connection

Linux terminal logo

On a Debian GNU/Linux system, I have worked on a solution to notify users via email when a USB hard disk drive is connected. The objective is to inform the system administrator that the USB drive is successfully connected.

Installing and configuring msmtp

Example here with msmtp which will send emails to mail.std.rocks relay on the 465 SSL port.

  • Install msmtp:
root@host:~# apt update && apt install msmtp
  • Edit /etc/msmtprc:
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 the userspace rather than the kernel space. It will allow us to execute a script when a USB disk device will be plugged in.

Note: let's say the disk we want to monitor is /dev/sda
  • Just for information we can print all attributes of the /dev/sda device:
root@host:~# udevadm info --attribute-walk --path=$(udevadm info --query=path --name=/dev/sda)
  • Create a /etc/udev/rules.d/10_usb-disk.rules file:
ACTION=="add", SUBSYSTEM=="block", SUBSYSTEMS=="usb", RUN{program}+="/usr/local/sbin/mail_usb_disk.sh"
  • Reload the udev rules and configuration:
root@host:~# udevadm control --reload

Bash script

  • Create /usr/local/sbin/mail_usb_disk.sh file:
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 file:
I've noticed that the script is executed twice when a USB device is plugged in. To prevent sending two emails, I create a /tmp/udev_time file and compare its creation time to the current date. If the time difference is greater than 10 seconds, the email will be sent.
Edit 2023/07/01: Haven't tested but some says that it could be resolved by adding ENV{DEVTYPE}=="usb_device" in 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
Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.

Contact :

contact mail address