Link to home
Start Free TrialLog in
Avatar of Digital_Skream
Digital_SkreamFlag for United States of America

asked on

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

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.
Avatar of arnold
arnold
Flag of United States of America image

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?

 
Avatar of Digital_Skream

ASKER

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.
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

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

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.  
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?
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.
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?
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.
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.
ASKER CERTIFIED SOLUTION
Avatar of Gabriel Orozco
Gabriel Orozco
Flag of Mexico image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
When you say "disabled local email ssytem" do you mean that you disabled postfix?
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.
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
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?
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.
Results in:
-bash: /usr/bin/sendmail: No such file or directory
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.
Thanks
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
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.
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.
@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.
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.
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.
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?
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.