Solved

How can I use shell scripting to send email using SMTP authentication

Posted on 2008-10-14
27
5,482 Views
Last Modified: 2013-12-16
I have a need to be able to send a text email to various recipients from a linux box, but must use SMTP authentication to send it.  I have done this countless times in Win32 using VBScript and CDO, but just can't find the right guide to show me how to get this accomplished under linux using bash scripting.
is there a simple 1-2-3 method of putting something together that will accept a username/password for sending email from a script?  it needs to be non-interactive, as this will be run from various nightly tasks on the server.
0
Comment
Question by:Digital_Skream
  • 13
  • 8
  • 6
27 Comments
 
LVL 76

Expert Comment

by:arnold
Comment Utility
Do you have a local smtp service running (postfix/sendmail)?
You can configure postfix/sendmail to authenticate to the smarthost.

You could look into whether the sendmail/postfix on your system looks for specific environment variables. i.e. username=user password=pass which it then checks before.

Why do you require smtp-auth on localhost?

 
0
 
LVL 1

Author Comment

by:Digital_Skream
Comment Utility
The linux box is a remote system, and my mail server is an exchange system at a different facility.  No local smtp services are installed or running on the linux system.
0
 
LVL 19

Expert Comment

by:Redimido
Comment Utility
you can simply use mailx

mailx can use smtp-auth. just create a .mailrc in the home directory of the user, like

# cat .mailrc

account myisp {

set verbose

set smtp-use-starttls   (Uses SSL)

set smtp=smtp.mail.yahoo.com:465(This is dependant on your email provider)

set from=YOUREMAILADDRESS@...

set smtp-auth=login  (Authentication via login/username/password)

set smtp-auth-user=YOUREMAILADDRESS (Also tried YOUREMAILADDRESS@...)

set smtp-auth-password=MY_PASSWORD

}

# 

# For standard smtp-auth (NO TLS):

account myisp {

set verbose

set smtp=smtp.mail.yahoo.com

set from=YOUREMAILADDRESS@...

set smtp-auth=login  (Authentication via login/username/password)

set smtp-auth-user=YOUREMAILADDRESS (Also tried YOUREMAILADDRESS@...)

set smtp-auth-password=MY_PASSWORD

}

Open in new window

0
 
LVL 1

Author Comment

by:Digital_Skream
Comment Utility
I must be missing something.
I am getting :
LOG: MAIN
  ** me@mydomain.com R=nonlocal: Mailing to remote domains not supported
I used the NO TLS code snippet, and here are my files:

cat testmail

#!/bin/bash

# script to send simple email

# email subject

SUBJECT="SET-EMAIL-SUBJECT"

# Email To ?

EMAIL="me@mydomain.com"

# Email text/message

EMAILMESSAGE="/tmp/emailmessage.txt"

echo "This is an email message test"> $EMAILMESSAGE

echo "This is email text" >>$EMAILMESSAGE

# send an email using /bin/mailx

/usr/bin/mailx -s "$SUBJECT" "$EMAIL" < $EMAILMESSAGE
 

cat .mailrc

# For standard smtp-auth (NO TLS):

set verbose

set smtp=mail.mydomain.com

set from=me@mydomain.com

set smtp-auth=login

set smtp-auth-user=me

set smtp-auth-password=mypassword

Open in new window

0
 
LVL 76

Expert Comment

by:arnold
Comment Utility
See if there is a /usr/bin/sendmail on the system.
you could use arp-get postfix to get it installed on your remote system.
You would then configure it to send through the provider or let postfix handle the delivery.
Another option, is to allow the IP of the remote system to relay through your exchange provided the remote IP is static.  This is not the best solution but a workable one.
Another option if the mailing is destined to your email address on the exchange server, there should not be any need to authenticate the mailing should be processed as though it is being sent by anyone outside.  
0
 
LVL 1

Author Comment

by:Digital_Skream
Comment Utility
There is a need to authenticate because eventually, this script will be utilized to send email to a large number of people on various email systems in different geographical areas.  i am testing right now with only a local email address just to get most of the bugs worked out.  isn't that how you test your code?

Does mailx ONLY work if there is a local email/smpt server in place?
0
 
LVL 76

Expert Comment

by:arnold
Comment Utility
usually, when a script needs to email, one should use a local smtp.
If however, you still want to use a shell script, perl would be a simpler mechanism.  There is a NET::SMTP module that can be used.

You might still use your bash script and then pipe the output to the perl script which will establish the smtp connection to your exchange, authenticate and pass the data along.

http://perldoc.perl.org/Net/SMTP.html
http://forums.devshed.com/perl-programming-6/net-smtp-auth-method-263637.html

You would then use the exchange with a distribution list rather than having the mailing addressed to multiple people by the script.

I think, a better solution is to add postfix to the remote system.  It does not have to accept external connections to send outgoing email.
0
 
LVL 1

Author Comment

by:Digital_Skream
Comment Utility
Ok, I installed postfix, and that took care of the problems.
One last thing... the set from="me@mydomain.com" setting in .mailrc is not working.
Everything is being sent as the current linux user rather than the email address I want to have in the reply-to.... any ideas?
0
 
LVL 19

Expert Comment

by:Redimido
Comment Utility
mailx can use a remote smtp, so no need to add a local SMTP. also it is just a matter of say

smtp user@destiny.mail.server < mailfile.txt

since the smtp-auth is already added to the ~/.mailrc


if the mail server you plan to use is indeed not in the local area network, I would go with the local mail server instead.

In general, I would try not to add another layer of complexity since you would need to also manage the local mail server if you add it.
0
 
LVL 1

Author Comment

by:Digital_Skream
Comment Utility
This is why I am trying to get a script that I can use to send notification emails.
Teh scenario is this: I have a linux server sitting at a client's location in another state.  I want the linux box to be able to send a simple "backups are done" email once a night to both the client's email address and to my email address.  I want this email to be "from" a specific notifications email address in my domain.
i am going to be rolling out dozens (or more hopefully) of these systems to future and current clients all around the country, so i **REALLY** don't want to have to manage dozens of separate email servers.
when I try to point smtp towards the remote server, it gives me a 550 error.
0
 
LVL 19

Accepted Solution

by:
Redimido earned 500 total points
Comment Utility
I've just finished a test from one of my linux servers

I disabled local email system just to check.

this was the .mailrc:
----8<---------------------------
set verbose
set smtp=testmta.com
set smtp-auth=login
set smtp-auth-user=gorv@testmta.com
set smtp-auth-password=holaesteesundemo
----8<---------------------------


I created a test file with
----8<---------------------------
From: Gabriel
To: Gabriel
Subject: prueba
this is a SMTP-AUTH test

Saludos
----8<---------------------------

the command line was:

 mailx gorv@anotheremailserverIhave.com < a.txt


the only drawback was it sent me verbose to the screen all the test. it worked like a charm.

I recall there is a set that works to avoid the output to screen in .mailrc.. you just need to google for ".mailrc"
I think it can be
set terse

try FIRST to connect from your test box by hand using
telnet testserver.com 25

to see if it answers correctly and there is no firewall blocking you in the middle.

hope this helps
0
 
LVL 1

Author Comment

by:Digital_Skream
Comment Utility
When you say "disabled local email ssytem" do you mean that you disabled postfix?
0
 
LVL 76

Expert Comment

by:arnold
Comment Utility
when you pipe data to postfix use the | /usr/bin/sendmail -t -fyouremail@yourdomain.com -oi
This will force the processing of the To:, Cc: and Bcc lines if any from the data being pumped in.

(I believe the the /usr/bin/sendmail is a symbolik link to a postfix binary which will handle the same switches as sendmail.
0
Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

 
LVL 19

Expert Comment

by:Redimido
Comment Utility
Digital_Skream: I simply took down my MTA (QMail on that server) so if the delivery was successful it was impossible my local MTA was the one doing the task ;) this was just to prove mailx does what it says
0
 
LVL 1

Author Comment

by:Digital_Skream
Comment Utility
Ok.  
Here's what i've done.
Starting fresh, I uninstall postfix and mailx.
I install mailx (sudo apt-get install mailx)
Then I configured the .mailrc exactly as above, and then did the same command as yourself, and it replied back:
-------------------()-----------------<
LOG: MAIN
  <= root@linux.remote U=root P=local S=483
root@linux:~# delivering 1Kq9iu-0003JD-Qy
R: nonlocal for me@mydomain.com
LOG: MAIN
  ** me@mydomain.com R=nonlocal: Mailing to remote domains not supported
LOG: MAIN
  <= <> R=1Kq9iu-0003JD-Qy U=Debian-exim P=local S=1384
delivering 1Kq9iv-0003JF-8i
R: system_aliases for root@linux.remote
R: system_aliases for normaluser@linux.remote
R: userforward for normaluser@linux.remote
R: procmail for normaluser@linux.remote
R: maildrop for normaluser@linux.remote
R: lowuid_aliases for normaluser@linux.remote (UID 1000)
R: local_user for normaluser@linux.remote
T: appendfile for normaluser@linux.remote
LOG: MAIN
  Completed
LOG: MAIN
  => normaluser <root@linux.remote> R=local_user T=mail_spool
LOG: MAIN
  Completed
-------------------()-----------------<

What am I doing wrong?
0
 
LVL 76

Expert Comment

by:arnold
Comment Utility
try the following at the bash prompt:

echo "To: youremail@address<cr>
From: theemail@address_of_sender<cr>
Subject: Test<cr>
<cr>
This is a test" | /usr/bin/sendmail -t -f theemailaddress@sender -oi<cr>


You can then incorporate this mechanism in your bash script.
0
 
LVL 1

Author Comment

by:Digital_Skream
Comment Utility
Results in:
-bash: /usr/bin/sendmail: No such file or directory
0
 
LVL 1

Author Comment

by:Digital_Skream
Comment Utility
Ok, finally got things to a place that I can reproduce successful results.
Had to do a 'apt-get purge postifx' to get rid of the old shreds of testing installations.
Then, I had to do a 'apt-get install -f postfix' to force it to reinstall any dependencies.
After that, install mailx, setup the .mainrc file and away we go!
To reiterate for future generations:

To easily configure your Ubuntu linux box to send emails from a script, follow these steps:
1.) apt-get install postfix
1a) configure it to be a internet site
2.) apt-get mailx
3.) create a .mailrc in your home directory with the following:
-------()------<
set verbose
set smtp=mail.yourdomain.com
set smtp-auth=plain
#Change auth=login if your mailhost requires it
set smtp-auth-user=username
set smtp-auth-password=password
-------()------<
4.) To test, create a text file anmed msg1 (echo test > msg1)
5.) run the following command:
mailx your emailaddy@yourdomain.com < msg1
6.) you should receive the email.

Still no way to successfully get mailx toput a different email address in as the From or Reply To address, but I can live with that for now I guess.
0
 
LVL 1

Author Closing Comment

by:Digital_Skream
Comment Utility
Thanks
0
 
LVL 19

Expert Comment

by:Redimido
Comment Utility
Great, thanks!

Still I believe you should be able to send email *without* postfix installed, unless postfix is needed because mailx binaries are included on its package
0
 
LVL 1

Author Comment

by:Digital_Skream
Comment Utility
I agree, that it *should* be able to be done... for example, using a command line app to act as a pop/smtp mail client... but everything I saw - and I have been experimenting with a lot of stuff hte past two days, mutt, mail, mailx, postfix, esmtp, pine, etc. - is all interdependent on having an MTA installed on the linux box.  It seems that whenever a discussion starts to go where I need it to go, someone pops up with a "this isn't for spamming!" and the discussion gets shut down.
In windows, I just write a short vbscript that uses the built-in CDO of Windows, and poof, i can send an email using a remote smtp server.  in linux it seems that I have to have a local MTA installed.
Go figure.
0
 
LVL 76

Expert Comment

by:arnold
Comment Utility
Not sure whether you want to follow the method I outlined.  If you are willing to try, you need to find where your sendmail/postfix binary is.
Run the following at the prompt:
where sendmail or where postfix
apropo sendmail or apropo postfix.
Once you locate the path, try the mechanism outlined earlier.
0
 
LVL 1

Author Comment

by:Digital_Skream
Comment Utility
@arnold
This is one of the problems in trying to get help with linux.
The simplest things (like locate sendmail to find the correct binary) are old hat and second-nature to the gurus, so it never occurs to them to tell newbies like me "do this". :)

Now I just have to figure out how to get it to use the smtp-auth.
It sends perfectly to my gmail account, but since it doesn't authenticate properly, it bounces off my exchance server.
0
 
LVL 76

Expert Comment

by:arnold
Comment Utility
The only time SMTP authentication is needed is to relay through a server.  When a message is destined to a recipient that your servers handles, there should not be a requirement for authentication.  If all mail servers were setup the same way you have configured your exchange server, no one will ever get any emails.
You should at least allow the remote server the ability to connect and transmit the message without the need to authenticate.  Do not add the remote server to the allow relay rule set.
0
 
LVL 1

Author Comment

by:Digital_Skream
Comment Utility
Just to clarify, because you seem to think that I made a mistake in configuring my exchange server ...
I do NOT require authentication to RECEIVE email to my domain.
I DO require authentication if a mail client (pegasus, eudora, outlook, thunderbird, etc.) wants to send an email to someone that is NOT in my domain FROM my mail server.  For example:
A user named Joe lives in California.  He has a POP/SMTP account on my domain/server.
He points his email client to mail.mydomain.com for the POP and SMTP servers.
He also sets up authentication, so that the mail server allows him to send an email to someone else in another part of the world on another domain.  Otherwise, he would only be able to send email to local recipients (other people @mydomain.com).
I also do not allow incoming emails that are sourced at residential IP's, as these are usually zombie PCs sending out spam as mini-SMTP servers.

If all mail servers were setup the way my exchange server is, there'd be less spam.

The whole point of this question was to setup a method in a script that would allow me to have a commandline mail client sending mail from my mail server, but while simple to accomplish with other operating systems, it apparently isn't trivial with linux.  that's ok, though.  I learned a lot.  lost a bunch of money/time/sleep, but I can write that off as an investment. :)
Thanks for your help.
0
 
LVL 76

Expert Comment

by:arnold
Comment Utility
If your server is configured as you outlined, the mailing from the remote linux box should reach your server without the need for SMTP auth.
Check the postfix log to see what happened when a connection to your Exchange server was attempted.  The issue could very well be that the IP your remote system has is being blocked by the residential IP restriction mechanism you use.

Can you telnet your_exchange_server_ip 25?
0
 
LVL 19

Expert Comment

by:Redimido
Comment Utility
when Digital_skream set this
set smtp=mail.yourdomain.com

mailx ceased using the local MTA.

this should be apparent if you check the maillog, where nothing should be logged, while the email should be logged in the remote mail.yourdomain.com mail log file.
0

Featured Post

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

If you have a server on collocation with the super-fast CPU, that doesn't mean that you get it running at full power. Here is a preamble. When doing inventory of Linux servers, that I'm administering, I've found that some of them are running on l…
It’s 2016. Password authentication should be dead — or at least close to dying. But, unfortunately, it has not traversed Quagga stage yet. Using password authentication is like laundering hotel guest linens with a washboard — it’s Passé.
Learn how to find files with the shell using the find and locate commands. Use locate to find a needle in a haystack.: With locate, check if the file still exists.: Use find to get the actual location of the file.:
Learn how to navigate the file tree with the shell. Use pwd to print the current working directory: Use ls to list a directory's contents: Use cd to change to a new directory: Use wildcards instead of typing out long directory names: Use ../ to move…

728 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now