Difference between revisions of "Automatic Email and Text Notifications"
(→Automatic Email Download) |
|||
Line 475: | Line 475: | ||
poll "imap.mail.yahoo.com" protocol IMAP username "myaccount@yahoo.com" password "InsertPasswordHere" is "username" here keep folder "DDNS-Mailbox" ssl | poll "imap.mail.yahoo.com" protocol IMAP username "myaccount@yahoo.com" password "InsertPasswordHere" is "username" here keep folder "DDNS-Mailbox" ssl | ||
</source> | </source> | ||
+ | |||
+ | You'll notice that it creates a file <code>/shares/Private/000__DDNS-ALERT__.txt</code>. The "000" is just to put it at the top of the directory listing. Also notice that I make it read-write for everyone so I can delete it from my webapp. | ||
Set up permissions on all three files, and create the log file: | Set up permissions on all three files, and create the log file: | ||
Line 491: | Line 493: | ||
chmod 640 /scripts/config/ddns-fetchmailrc | chmod 640 /scripts/config/ddns-fetchmailrc | ||
</source> | </source> | ||
− | |||
− |
Revision as of 15:46, 2 October 2018
These tutorials describe my method of automatic messaging via email and text (SMS) from my Linux servers.
TODO:
add crontab, user/group, replace /logs with /var/log, correct the permissions of files
Contents
Required Packages
These packages are necessary for the all the following sections of this tutorial. In Debain, install them with apt-get
:
apt-get install ssmtp procmail fetchmail
Directory Structure
Just for reference, here are the locations of the relevant files:
/
├── etc
│ └── ssmtp
│ └── ssmtp.conf
└── scripts
├── config
│ ├── accounts.conf
│ ├── ddns-fetchmailrc
│ └── ddns-mailprocess.sh
├── ddns.sh
├── email.sh
├── external-ip.sh
├── notifications.sh
└── sms.sh
And permissions:
ls -l /scripts
drwxr-xr-x 4 root config 4096 Jun 20 08:52 config -rwxr-xr-- 1 root root 260 Jun 20 08:40 ddns.sh -rwxr-xr-- 1 root mailers 564 Apr 23 12:18 email.sh -rwxr-xr-- 1 root root 529 Apr 27 07:56 external-ip.sh -rwxr-xr-- 1 root root 3834 May 15 08:32 notifications.sh -rwxr-xr-- 1 root texters 545 Apr 23 12:24 sms.sh
ls -l /scripts/config
-rwxr----- 1 root mailers 147 May 1 13:01 accounts.conf -rwxr----- 1 root config 246 May 21 09:49 ddns-fetchmailrc -rwxr-x--- 1 root config 604 Jun 20 08:52 ddns-mailprocess.sh
Email and Text Messaging with SSMTP
First set up the /etc/ssmtp/ssmtp.conf
. I use a dedicated Gmail account (named serveraccount@gmail.com in the example below) for all of my server messaging. When I receive an email from my server, it will look like it's coming from that Gmail.
Make a backup copy of the original config:
cp /etc/ssmtp/ssmtp.conf /etc/ssmtp/ssmtp.conf.orig
Here are the contents of my modified /etc/ssmtp/ssmtp.conf
. Replace the relevant values.
#
# Config file for sSMTP sendmail
#
# The person who gets all mail for userids < 1000
# Make this empty to disable rewriting.
root=serveraccount
# The place where the mail goes. The actual machine name is required no
# MX records are consulted. Commonly mailhosts are named mail.domain.com
#mailhub=mail
# Where will the mail seem to come from?
rewriteDomain=gmail.com
# The full hostname
# This can be left as 'localhost'
hostname=localhost
# Are users allowed to set their own From: address?
# YES - Allow the user to specify their own From: address
# NO - Use the system generated From: address
FromLineOverride=YES
mailhub=smtp.gmail.com:587
UseStartTLS=YES
UseTLS=YES
AuthMethod=LOGIN
AuthUser=serveraccount@gmail.com
AuthPass=InsertPasswordHere
TLS_CA_File=/etc/pki/tls/certs/ca-bundle.crt
FromLineOverride=YES
Since the file contains a password, make sure the file is not readable to normal users.
chown root:mail /etc/ssmtp/ssmtp.conf
chmod 640 /etc/ssmtp/ssmtp.conf
And because you don't have to remember this password, it would be a good idea to make it very long and complex (16+ characters; uppercase, lowercase, numbers, and special characters; no dictionary words).
You now need to log onto the serveraccount Gmail account and enable "less secure apps" at https://myaccount.google.com/lesssecureapps?pli=1
Here is more info about less secure apps: https://support.google.com/cloudidentity/answer/6260879?hl=en
You should now be able use the ssmtp
command line tool from your server. Most of the time, you will need to include a subject line. It's important that it follows the format below (capital 'S' on Subject, colon, space, YourSubject, two newlines):
echo -e "Subject: Hi\n\nHello, world!" | ssmtp myaccount@yahoo.com
Create Security Groups
I use group membership to control read access to certain files. You don't have to do this, but it was useful for me.
Create the groups:
groupadd texters #allowed to sent text messages
groupadd mailers #allowed to send email messages
groupadd config #allowed to read other config files
You can add a user to all three groups like this:
usermod -aG texters,mailers,config username
Create a Secure Accounts File
For some of the automatic messaging, you need to store text and email accounts in a file. To find the destination address to send text (SMS) messages to your cell, look on your cell provider's website for the proper account/domain name. It will probably be something like "<your-phone-number>@<provider-domain>". List of provider addresses
Contents of my /scripts/config/accounts.conf
file:
#!/bin/bash
#
# Secure account information
# Permissions must be 750 root:mailers
smsto="17775551234@myprovider.net"
mailto="myaccount@yahoo.com"
Change the permissions on the file:
chown root:mailers /scripts/config/accounts.conf
chmod 750 /scripts/config/accounts.conf
Email Script
This script can be used to send an email message.
Contents of the file /scripts/email.sh
:
#!/bin/bash
# Send email message:
# Usage: $0 "<Subject>" "<Message>"
default_subject="Alert from Server (`date`)"
subject=""
message=""
case $# in
2)
subject="$1"
message="$2"
;;
1)
subject="$default_subject"
message="$1"
;;
*)
echo "Send Email Message:"
echo " Usage: `basename $0` \"Message\""
echo " `basename $0` \"Subject\" \"Message\""
exit 1
;;
esac
dir="$(cd $(dirname ${BASH_SOURCE[0]})&&pwd)"
. $dir/config/accounts.conf
echo -e "Subject: $subject\n\n$message" | /usr/sbin/ssmtp $mailto
Set up permissions:
chown root:mailers /scripts/email.sh
chmod 754 /scripts/email.sh
You can create an alias so you can quickly run this from the command line:
echo "alias email='/scripts/email.sh'" >>~/.bashrc
source ~/.bashrc
Usage:
# Send message with default subject
email "This is a test message."
# Send message with a subject
email "Test Subject" "This is a test message."
Text Script
This script can be used to send a text (SMS) message.
Contents of the file /scripts/sms.sh
:
#!/bin/bash
# Send SMS message:
# Usage: $0 "<Subject>" "<Message>"
default_subject="Alert"
subject=""
message=""
case $# in
2)
subject="$1"
message="$2"
;;
1)
subject="$default_subject"
message="$1"
;;
*)
echo "Send SMS Message:"
echo " Usage: `basename $0` \"Message\""
echo " `basename $0` \"Subject\" \"Message\""
exit 1
;;
esac
dir="$(cd $(dirname ${BASH_SOURCE[0]})&&pwd)"
. $dir/config/accounts.conf
echo -e "To: $smsto\nSubject: $subject\n\n$message" | /usr/sbin/ssmtp $smsto
Set up permissions:
chown root:texters /scripts/sms.sh
chmod 754 /scripts/sms.sh
You can create an alias so you can quickly run this from the command line:
echo "alias sms='/scripts/sms.sh'" >>~/.bashrc
source ~/.bashrc
Usage:
# Send message with default subject
sms "This is a test message."
# Send message with a subject
sms "Test Subject" "This is a test message."
Scheduled Notifications Script
One of my life improvement tasks was to organize chores into scheduled chore days and rely on text/email notification to remind me to do them.
This dramatically reduced the amount of time I spend working on chores, and the amount of effort I spend thinking about what needs to be done. I could barely get projects done because every day I was loading my task list with chores. Now I don't think about chores until I'm notified. When I think of new chores, new items for my inventory, or other things I need to be reminded of, I update my checklists. When I feel I can improve scheduling or consolidate chores, I update my notifications script.
This utilizes the Email Script and Text Script from the previous sections.
Contents of the file /scripts/notifications.sh
:
#!/bin/bash
#
# Send regular notifications.
# Currently set to run daily at NOON.
#
# Get current datetime values
dt=(`date +%Y\ %m\ %d\ %H\ %M\ %S\ %a\ %s\ %I\ %p\ %Z`)
y=$((10#${dt[0]})) #year
M=$((10#${dt[1]})) #month
d=$((10#${dt[2]})) #day
h=$((10#${dt[3]})) #hour(24)
m=$((10#${dt[4]})) #minute
s=$((10#${dt[5]})) #second
w=${dt[6]} #day of week (eg. Sun)
e=$((10#${dt[7]})) #epoch
t=$((10#${dt[8]})) #hour(12)
p=${dt[9]} #meridian (AM/PM)
z=${dt[10]} #timezone (eg. PDT)
# Schedule command when date ($1) matched regex ($2) with extra grep parameters ($3)
# Use parameter -P at $3 for perl regex: in case you need to use (str1|str2).
# Example: schedule $M$d "(115|21)" -P && sms "Subject" "Message"
# Don't use -P when you want a range of numbers including 2 or more digit numbers (ie. [1-15]).
schedule(){ echo "$1" | grep -wq $3 "$2";}
sms(){ /scripts/sms.sh "$1" "$2";}
eml(){ /scripts/email.sh "$1" "$2";}
notify(){ sms "$1" "$2";eml "$1" "$2";}
# =================================
# ==== Temporary Notifications ====
# =================================
# Dentist appointment
#schedule $M$d "58" && notify "Dentist" "Appointment 4:00pm 10/31/2017"
# =================================
# ====== Chore Notifications ======
# =================================
# LAUNDRY DAY
# Day before
schedule $w$d "Mon[1-7]" && notify "LAUNDRY DAY" "WORK: Check gas. HOME: Do laundry, put laundry away."
schedule $w$d "Mon(15|16|17|18|19|20|21)" -P && notify "LAUNDRY DAY" "WORK: Check gas. HOME: Do laundry, put laundry away."
# WEEKLY CLEANING DAY
schedule $w "Tue" && notify "WEEKLY CLEANING DAY" "WORK: Fill gas, shopping. HOME: Clean, litter, sweep/vac, fridge, trash, check meds."
# Day after
schedule $w "Wed" && notify "WEEKLY REMINDER" "Order meds if necessary."
# MONTHLY CLEANING DAY
schedule $w$d "Tue[1-7]" && notify "MONTHLY CLEANING DAY" "WORK: Car stuff. HOME: Dishes, kitchen, bathroom, dust, inventory."
# BUSINESS DAY
schedule $d "[1-4]" && notify "BUSINESS DAY" "Rent due before 5th (\$720). Fedloan, budgeting, donations, next-buy."
# TECH DAY
schedule $w$d "Mon[1-7]" && notify "TECH DAY" "WORK: Updates, phone, healthcheck, security scan, organize files. HOME: Organize Workstation/Laptop, USB drives."
# SHOPPING DAY
schedule $w$d "Wed[1-7]" && notify "SHOPPING DAY" "Shopping, carwash. Maybe do during lunch."
# GROOMING DAY
schedule $w$d "Sun[1-7]" && notify "GROOMING DAY" "Shave/trim, clip nails."
schedule $w$d "Sun(15|16|17|18|19|20|21)" -P && notify "GROOMING DAY" "Shave/trim, clip nails."
# ELIMINATION DAY
schedule $w$d "Sun(15|16|17|18|19|20|21)" -P && notify "ELIMINATION DAY" "Do at least one item on TO_ELIMINATE list."
# INVENTORY DAY
# Disabled. Inventory is now included in monthly cleaning day.
# schedule $w$d "Tue[1-7]" && notify "INVENTORY DAY" "Do home, car, and office inventory."
# =================================
# = Other Permanent Notifications =
# =================================
# Air filter replacement notifications
schedule $M$d "71" && notify "Air Filter" "Holmes HAP726: Replace HEPA filters (model:HAPF600,qty:2)"
schedule $M$d "[1|7]1" && notify "Air Filter" "Holmes HAP726: Replace Carbon filters (model:HAPF600,qty:2)"
Now set the permissions:
chown root:root /scripts/external-ip.sh
chmod 754 /scripts/external-ip.sh
Reporting External IP Address
My home server does not have a static IP address, so I use dynamic DNS. With my free DDNS service, I have to renew the domain name every 30 days. So if I forget to renew it, it will expire and I won't be able to access my server unless I know the IP address. As a contingency, I created a script that sends my external IP address to an email account every 6 hours. Then at least I would be able find out what my last IP was and use that to access my server.
Contents of the file /scripts/external-ip.sh
:
#!/bin/bash
log="/var/log/external-ip.log"
ipsrc="http://checkip.dyndns.org"
date="`date`"
addr="myaccount@yahoo.com"
ip=`curl -s --connect-timeout 3 $ipsrc 2>/dev/null|grep -Po "Current IP Address: .*?\<"|tr '<' '\0'`
echo "IP: $ip"
if [ -z "$ip" ];then
echo "$date ERROR: Could not get external IP from $ipsrc" >>$log
else
echo -e "Subject:[`hostname`] $date $ip" | /usr/sbin/ssmtp $addr
if [ "$?" = "0" ];then
echo "$date SUCCESS: $ip sent to $addr" >>$log
else
echo "$date ERROR: Could not send to $addr" >>$log
fi
fi
Now set the permissions:
chown root:root /scripts/external-ip.sh
chmod 754 /scripts/external-ip.sh
This script appends to a log file /var/log/external-ip.log
:
touch /var/log/external-ip.log
chown root:root /var/log/external-ip.log
chmod 644 /var/log/external-ip.log
Automatic Email Download
As mentioned in a previous section, I use free dynamic DNS which requires that I renew it manually every 30 days. I need to remind myself to do this. My provider sends an email notification a few days before it expires, but I hat email and I don't want it in my face all the time, certainly not in my phone.
The best solution I found was to retrieve the email automatically and send me a text message with only the subject line in the message. I eventually created a second method of notification: it generates a file in a place that I regularly go, the folder that contains all of my to-do lists.
Contents of the file /scripts/ddns.sh
:
#!/bin/bash
#
# This script is run by a cron job.
/usr/bin/fetchmail -N -d0 -f "/scripts/config/ddns-fetchmailrc" -m "/scripts/config/ddns-mailprocess.sh"
alertfile="/shares/Private/000__DDNS-ALERT__.txt"
if [ -e $alertfile ];then
chown root:root $alertfile
chmod 777 $alertfile
fi
Contents of the file /scripts/config/ddns-mailprocess.sh
:
#!/bin/bash
#
# This script is run by /scripts/ddns.sh
mailto="17775551234@myprovider.net"
date="`date`"
log="/var/log/ddns.log"
alertfile="/shares/Private/000__DDNS-ALERT__.txt"
sms="/scripts/sms.sh"
cat /dev/stdin | grep -i "^Subject:" | sed 's/Subject\://g' | $sms "DDNS" "`cat /dev/stdin` ( $date )" &&\
echo "$date - DDNS notification sent to $mailto" | tee -a $log | sed "s/$mailto/cell\ phone/g" >$alertfile &&\
chmod 777 $alertfile
Contents of the file /scripts/config/ddns-fetchmailrc
:
#
# This rc file is run by /scripts/ddns.sh
# This file MUST have root:root and chmod 700
set postmaster "username";
poll "imap.mail.yahoo.com" protocol IMAP username "myaccount@yahoo.com" password "InsertPasswordHere" is "username" here keep folder "DDNS-Mailbox" ssl
You'll notice that it creates a file /shares/Private/000__DDNS-ALERT__.txt
. The "000" is just to put it at the top of the directory listing. Also notice that I make it read-write for everyone so I can delete it from my webapp.
Set up permissions on all three files, and create the log file:
touch /var/log/ddns.log
chown root:root /var/log/ddns.log
chmod 640 /var/log/ddns.log
chown root:root /scripts/ddns.sh
chmod 754 /scripts/ddns.sh
chown root:config /scripts/config/ddns-mailprocess.sh
chmod 750 /scripts/config/ddns-mailprocess.sh
chown root:root /scripts/config/ddns-fetchmailrc
chmod 640 /scripts/config/ddns-fetchmailrc