fetch mail via SSH from a remote server and send them via a mail account to someone
suppose you have a server somewhere in a very restricted network. there is no way for you to send emails to your regular mail account in order to receive alerts such as Disk failures, backup reports etc… BUT: you have ssh access :)
you could setup a reverse tunnel to an smtp server somehwere, but your restricted network might not like long lasting ssh connections and kick you out all the time.. so here is a solution, where a linux machine with SSH access to your cut-off server can collect mails on that server and then forward it to a smtp server for delivery.
in my example, i deliberately change the FROM and TO header fields to always point to my own mail addres, as i want to be the sole recipient of all mails from this server and my SMTP allows only my own email address as a sender address.. you can adjust that to be a full blown mail realyer .. but be carefule what you wish for ;)
Prerequisites
besides ssh we also need msmtp and formail. the latter is part of the procmail package in ubuntu:
sudo apt install procmail msmtp
setup password less ssh access as the user who's mail you want to fetch from the target server
create a directory tree for our mail fetcher app
mailfetcher/ ├── mailfetcher.sh ├── .msmtprc └── outbox
write that .msmtprc
config file.. here is an exmaple:
- .msmtprc
account default host my.mail.server port 587 tls on tls_starttls on tls_trust_file /etc/ssl/certs/ca-certificates.crt tls_certcheck on auth on user my_Mail_user password "Super$ecretPassw0rd" from "my_email@address.fake"
make sure to put the right values in there for your mail account :)
The Script
the script below will connect to your server, fetch all mails from /var/mail/<user>
and create a file for each mail in a local outbox
path. once the mails are downloaded, it will erase them from the server as to not download them again in the future.
it will then start a loop where it goes through all downloaded messages and sends them via msmtp.
- mailfetcher.sh
#!/bin/bash MYPATH=$(dirname "$(readlink -f $0))") cd $MYPATH user="root" server="myrestricted.server" mail="my_email@address.fake" ssh ${user}@${server} cat /var/mail/${user} | \ FILENO=$(date +%s001) \ formail -i "To: $mail" -k -R From: Old-From: -X Subject: -X Date: -X To: -X Old-To: -ds sh -c \ 'cat > outbox/msg.$FILENO' && \ ssh ${user}@${server} 'echo "" > /var/mail/${user}' for msg in outbox/msg.*; do cat $msg | msmtp -C .msmtprc -t -v && rm -f $msg sleep 15 done
fill the first variables with the right content ;)
make the script executable:
chmod 755 mailfetcher.sh
testing and cron job
to test the script, simply run it from a shell, it will print verbose output from the smtp sessions. if you run into message rate limit issues, increase the time for the sleep 15
command on the second to last line of the script.
once you are satisfied, set up a cron job..
crontab -e
here is an example where we run the script once per hour to fetch mail and deliver it.. Headline
00 * * * * /home/psuter/mailfetcher/mailfetcher.sh >& /dev/null