Today at work, the support staff needed to check and see if a customer’s email server was setup to relay mail via their database server. Normally when asked, I direct the support staff to the send the SMTP commands via Telnet like so:
You do/type this Server responds with Telnet to hostname on port 25 220 (then identifies itself – possibly with several lines of 220 + text) HELO your_domain_name or whatever 250 (followed by human readable message) MAIL FROM:you@hostname.com (ie, your email address) 250 is syntactically correct (or similar) RCPT TO:them@someplace_else.com (email address you want to send to) 250 is syntactically correct DATA Tells you to send data then CRLF period CRLF at end You type your message then CRLF period CRLF (ie, type a period on a line by itself then hit ENTER) 250 QUIT Signoff message
But I figured instead of telling them the same thing every other week it was time to brush up on my bash scripting skills and learn something new in the process.
I first tried to read in the variables and then send them out to a telnet command but quickly realized that once telnet was executed in the script it would no longer accept the bash variables that I had created. I knew from previous scripts that I could use the expect commands (more info) but expect is not usually a package that gets installed on a linux server by default and most of these servers are production database servers, which no admin would allow a random package to get installed with out testing it first.
So with expect out of the question it was time for some Google searches which let me to an article from the Linux Journal titled “More on Using Bash’s Built in /dev/tcp File (TCP/IP)“ This struck my interest, first because I didn’t know that this was possible and second because this was the same way that I had done it in the Windows/AutoIT world (I will post more about this later). Here is the full script that I wrote. Feel free to use this as you need or if you see a way for me to make it better please let me know.
Script
#!/bin/bash # Written by: Terry Moore # Created on Date: 2009-10-12 # Test mail relay from a Linux database server # Version 0.2 # Last update 2009-10-13 #Body of Email DATA="The test message has been sent" #Subject of Email SUBJECT="Mail Relay Test" ######### Header ########## echo echo echo echo "***************************************" echo "* *" echo "* Mail Relay Test App *" echo "* *" echo "***************************************" echo echo "Press control+c at any time to cancel" echo "Please answer all of the following questions:" echo ##### Get Mail Server ####### LOOP=0 while [ $LOOP -ne 1 ] do echo -n "Enter Mail Server Name: " ; read MAILSERVER; if [ "$MAILSERVER" != '' ] ; then LOOP=1 fi done ###### GET PORT ########## echo -n "Enter Port: [typically 25]: "; read PORT; if [ "$PORT" = '' ] ; then LOOP=1 PORT="25" fi ###### GET MAIL FROM ########## echo -n "Enter Mail From: [support@email.com]" ; read MAILFROM if [ "$MAILFROM" = '' ] ; then MAILFROM="support@email.com" LOOP=0 fi ###### GET MAIL TO ########## LOOP=0 while [ $LOOP -ne 1 ] do echo -n "Enter Mail To: " ; read MAILTO if [ "$MAILTO" != '' ] ; then LOOP=1 fi done #### SEND MAIL via RAW TCP ####### echo echo "Connecting to $MAILSERVER on Port $PORT"; echo "Please wait ... " echo exec 3<>/dev/tcp/$MAILSERVER/$PORT if [ $? -ne 0 ] ; then echo echo "ERROR: Cannot connect to the Mail Server"; echo "Please check the servername and/or the port number" exit fi echo -en "HELO mail.email.com\r\n" >&3 echo -en "MAIL FROM:$MAILFROM\r\n" >&3 echo -en "RCPT TO:$MAILTO\r\n" >&3 echo -en "DATA\r\n" >&3 echo -en "Subject: $SUBJECT\r\n\r\n" >&3 echo -en "$DATA\r\n" >&3 echo -en ".\r\n" >&3 echo -en "QUIT\r\n" >&3 cat <&3 echo echo echo "Check the above output for errors" echo
I know I have to do more error checking and data sanitizing but you can get the drift as to how to use bash’s builtin /dev/tcp device file to send telnet commands.
More on Using Bash’s Built-in /dev/tcp File (TCP/IP)
by Steve Deemer
26 Dec 2009 at 18:27
Nice job!
To work on roadrunner.com smtp server, all I had to add was From: and To: header in message.
I got frustrated trying to get netcat to work.
“cat file | nc -i1 smtp-server.com 25″
Pingback
by Google Analytic Statistics for One Year. | Motersho
26 Aug 2010 at 11:47
[...] Fedora 12 to work with a Samsung TV (1,820) Autoit Command Line Parameters. A new approach (1,081) HOWTO: Send SMTP commands via a bash script and the /dev/tcp device file [...]
by Robert
15 Sep 2010 at 18:35
I keep getting /dev/tcp/ No such file or directory.
by Terry Moore
15 Sep 2010 at 21:21
I have tested this on Fedora and Ubuntu. What disto are you trying to run this on?
by Terry Moore
29 Nov 2010 at 20:02
@Robert. After some research it would seem that your version of Bash is not compiled with /dev/tcp support.