Hi everyone, to have a little fun and for a personnal project I needed to send mails via linux's terminal. The first option I had was to use the mail command from postfix. But for some reason I didn't want to use that method.
So, as I had time to waste and because I like that, I wanted to do it by myself. I then remembred that telnet allowed us to communicate with servers like, for example : smtp servers, and to use them to send mails.
As I have a gmail adress, i've used google's smtp. A little plus, google's smtp only accept TLS or SSL, secured protocols for those who are lookig for a secured way to send mails, it's great.
So let's get started, we will see in a first time how the communication with google's smtp happens.
To use google's smtp, you'll obiously need a gmail adress, it won't work with any other adress, if you want to send mails with another mail adress, you'll have to use another smtp, for exemple if you have an outlook address, use outlook's smtp.
Step 1: Talking With Google's Smtp
1 : Install telnet
You'll first need to install telnet with it's SSL support, to do so run the command : sudo apt-get install telnet-ssl
As i said in the introduction, google refuses unsecured connexions, by installing this extension of telnet you will can use the -z ssl argument in your telnet command, which means you're going to use SSL protocol over the connection.
2 : Start telnet
Once it's installed you can try to connect to google's smtp by using : telnet -z ssl smtp.gmail.com 465
The 465 here means you're going to connect on the port 465 of google's smtp server.
It should respond you this :
Connected to gmail-smtp-msa.l.google.com
Escape character is '^]'.
220 mx.google.com ESMTP k6sm22114824wia.6 - gsmt
3 : Say hello !
To start communicating, you have to be polite, and of corse you've got to say hello. More seriously, you have to type : HELO hellogoogle
The HELO here and what's following it, is supposed to be your domain, in the reality you can enter whatever you want.
It should respond you : 250 mx.google.com at your service
4 : Time to log
Once you get the server's answer, it's finally timefor you to tell who you are, you just have to type : AUTH LOGIN
It means what it means, you're asking to log yourself, it'll ask you your username and password.
But before that he should respond : 334 VXNlcm5hbWU6
5 : What's your name ?
So as google really loves to secure everything, you'll have to encode your mail adress in base64, you can use this website to do so: Base64
Copy the encoded string the website gives you and paste it in terminal, google will then check it and see if he recognizes it. If it does it will print you this : 334 UGFzc3dvcmQ6
Meaning that it knows you and is now waiting for you to enter your password.
6 : What's the secret code ?
You now have to enter your password, just like before you'll have to encode it in base64 ( Base64 )
If your mail and password are correct, google will tell you : 235 2.7.0 Accepted
And will let you continue
7 : Who's talking ?
The smtp is now going to ask you who will be the sender of the mail. You just have to type your mail address, without to encode them this time : MAIL FROM: < firstname.lastname@example.org >
The < > are to be kept, don't remove them just replace what's inside by your mail address.
The server will repond you : 250 2.1.0 OK fm10sm5922664wib.7 - gsmtp
The part underligned depends of the mail, it won't be the same for you.
8 : Who's that mail for ?
So now you have to enter the email adress you want to send the mail to.
Just like before you just have to type : RCPT TO: < email@example.com >
And once more the < > are to be kept.
The server will respond you : 250 2.1.5 OK fm10sm5922664wib.7 - gsmtp
Here the string in the middle is the same cause i'm sending a mail to myself
9 : Speak now !
After all those steps, it's finally time to write your mail.
To do so type : DATA
Server's gonna tell you : 354 Go ahead fm10sm5922664wib.7 - gsmtp
You now can enter the subject of your mail : just enter : Subject: I'm sending mails !
Press enter to confirm the subject, then everything you'll write are going to compose the mail's text for example :
That's my first mail via telnet, AWESOME !
Second useless line just because i can
The dot tells the server where is the end of your mail, if everythings's fine, you should receive this message from the server : 250 2.0.0 OK 1381416452 fm10sm5922664wib.7 - gsmtp
10 : Say goodbye
To disconnect from the server you can use telnet's command QUIT, this isn't a message sent to the smtp.
And we're done ! your mail has been sent ! That's magic and so cool !
You'll tell me, but wait tha'ts stupid to send a mail that way, it takes way too much time for a simple thing we can do on our navigator in a couple seconds.
And i'll tell you YES, but for some tasks you won't have the choice. In my case I wanted to send me by mail the state of all my servers, and my public IP, because as i don't have a fix IP at home, the only way for me to reach my home over internet is to know my IP. For this i send to myself a mail every 30 minutes, or whenever my ip changes, with my IP and my servers status.
To do such a thing, i had to make all the things we did, into a script that would automate my mail shipment.
Check next step to see this !
Step 2: Automate the Mail Shipment
So, to automate all the steps we've been doing before, i've been looking for the net, something that could allow me to do this, cause the bash dosn't permit such a thing.
And i've finally find something close to the bash, the expect !
Basically, it will wait a string to be printed on the terminal. And only when this string is received, it will write another one.
For exemple when you start the telnet communication with google the server answer you a string ending by "SMTPUTF8", and when this string is written in the terminal, the script shall send the response HELO
I invite you to check all the previouses steps, as you can see for every string you send to the server there is a response.
I've base my script on this.
Here is how i made it, i've create a bash script that shall retrieve my public IP address, and the status of all my server and send it into a string as an argument to my expect script.
First the bash script that call my expect script ( it's a light version just for the exmple )
I've upload the both scripts.
#This line is here cause i'll use crontab later
echo "Récupération de l'adresse ip publique"
curl ifconfig.me > ipPublic.txt
IP+=$(cat ipPublic.txt) PLEX=""
echo "IP publique maison : " $IP
service --status-all | grep plex > tmp.txt
if [[ -s tmp.txt ]]; then
echo "Envoi du mail ..."
/home/diard/Téléchargements/telnetScript.exp $IP $PLEX
echo "Script terminé"
________________________________END OF BASH SCRIPT_____________________________
And there it is the expect script. The script i just showed you, calls the follo with the Ip and status of my server.
set HELO "HELO yo"
set SMTP "smtp.gmail.com"
set PORT "587"
set AUTH "AUTH LOGIN"
set LOGI "<yourEncodedMail>"
set PASS "<yourEncodedPass>"
set EXPE "MAIL FROM: <yourMail>"
set DEST "RCPT TO: <DestMail>"
set DATA "DATA"
set SUBJ "SUBJECT: Server info"
set MES1 [lindex $argv 0]
set MES2 [lindex $argv 1]
set POIN "."
set QUIT "QUIT"
set timeout 10
spawn /usr/bin/openssl s_client -starttls smtp -connect $SMTP:$PORT -crlf -ign_eof
expect eof exit
________________________________END OF EXPECT SCRIPT____________________________
Step 3: Run This Every X Time
As i said i wanted to send myself a mail every 30 minutes, to do so i have to execute this script every 30 minutes. So i've used cron.
To add something to execute every x time, use : sudo crontab -e
Add at the end of the file : 0,30 * * * * /bin/bash /home//Téléchargements/scriptIp.sh >> /home/
This line means that every 30 minutes you'll start the script scriptIp.sh and you will redirect the output into a log file.
As cron works a bit specially, you have to explicitly expose your environment vars.
To do so type echo $PATH in your termianl copy paste the result of the command into the beggining of the bash script like that :
And it's the end of this little tutorial, hope it will help ;).