Enable Outgoing Mail on Raspberry Pi

This article explains how to send email from the Raspberry Pi. It is a generic procedure and also works on other Debian distributions. This is not for receiving mail, only for sending it. (Receiving email on the Pi is a much more involved process, requiring your Pi to perform the role of a full mail server).

The ability to send mail across the Internet is useful. It enables your scripts and applications to send you email about system events or sending data such as pictures from a webcam.

This article was updated in December 2017 and has been successfully tested on Raspbian Stretch/Debian 9.

Install Sendmail

This procedure uses sendmail, the great grandaddy of all email programmes. Install it now as follows. ssh into your pi, or sit in front of the desktop, as you prefer. Become root:

$ sudo su -

Update software lists and install:
# apt-get update
# apt-get install sendmail

This will install sendmail and a few other packages, create the directory /etc/mail, and perform a few other tasks.

Configure Sendmail

Change to /etc/mail and edit the file /etc/mail/submit.mc, using an editor of your choice. (Do not edit the submit.cf file)

# cd /etc/mail
# vi submit.mc

Add the three lines shown below in bold to the file. Put them just after the “DOMAIN(`debian-msp’)dnl” line, as shown:

define(`_USE_ETC_MAIL_')dnl
include(`/usr/share/sendmail/cf/m4/cf.m4')dnl
VERSIONID(`$Id: submit.mc, v 8.14.4-4 2013-02-11 11:12:33 cowboy Exp $')
OSTYPE(`debian')dnl
DOMAIN(`debian-msp')dnl
define(`SMART_HOST',`[mail.btinternet.com]')dnl
FEATURE(`authinfo',`hash -o /etc/mail/authinfo.db')dnl
MASQUERADE_AS(`bloggs.gotdns.org')dnl

Here, mail.btinternet.com is the mail server of my provider (BT). My domain name is bloggs.gotdns.org. Email sent from the Pi will appear to come from an email address “<user>@bloggs.gotdns.org“.

Save the submit.mc file after making the above changes.

Next, edit the authinfo file.

# vi authinfo

Make it contain a single line, like this one:
AuthInfo: "U:myusername@btinternet.com" "P:mypassword" "M:PLAIN"

myusername@btinternet.com is my email address at the ISP. mypassword is the password to go with it. Enter the appropriate address and password for you. Sendmail will use this information to authenticate with your ISP every time it sends an email. It is a basic spam prevention measure implemented by many service providers.

Save the authinfo file and use makemap to create the binary version. The following command creates a file called “authinfo.db“, using the information you placed into authinfo.

# makemap hash /etc/mail/authinfo < /etc/mail/authinfo

Finally, edit your /etc/hosts file and add your domain to the line containing “raspberrypi”. That is the same domain name you used in submit.mc, above (in my case, bloggs.gotdns.org). On a newly installed Raspbian Jessie, it looks like this:

127.0.1.1       raspberrypi

Change that to:

127.0.1.1       raspberrypi bloggs.gotdns.org

Now restart sendmail. This can take a couple of minutes sometimes, so be patient:
# service sendmail restart

Note:If you have found this page after encountering a message like “WARNING: local host name (raspberrypi) is not qualified; see cf/README: WHO AM I?, then adding the domain name to /etc/hosts as just described, should fix it.

Send a Test Email

Send a test email to a mail account you own, eg gmail, hotmail, outlook or whatever:
# /usr/lib/sendmail -v someuser@hotmail.com
Test from Pi
<ctrl-d>

This will print a load of stuff as it sends the mail, including hopefully a “235 PLAIN authentication successful” message. Check your mail account to see the mail came through. (Check the “junk” mail folder too). It should not take more than a second or two, or maybe a few minutes at very busy times.

Fix Local Email

If the above test worked, Internet mail is working from your Pi. Great. Now, however, local mail fails. By “local mail”, I mean email sent from one user on the Pi to another user, for example when cron sends a user the output from their scheduled jobs, or when the system sends diagnostic messages to the root user. It may not be important to you, but best make it work anyway. Proceed as follows.

Tell sendmail not to authenticate for local mail. Edit the file /etc/mail/access and add this line:

SRV_Features:127.0.0.1 A

Save the file and type “make” to regenerate its binary version, access.db:

root@raspberrypi:/etc/mail# vi access
root@raspberrypi:/etc/mail# make
Creating /etc/mail/relay-domains
# Optional file...
Updating access_db ...
The following file(s) have changed:

** ** You should issue `/etc/init.d/sendmail reload` ** **

Restart sendmail:
# service sendmail restart

If you see messages complaining about “sasl2-bin” not being installed, and about enabling SASL2 support at a later date, they can be ignored for the purposes of this procedure.

As a test, try sending a local mail. Eg send a mail to the “pi” user.

root@raspberrypi:/etc/mail# /usr/lib/sendmail -v pi
Hello pi user from root
<ctrl-d>

Again, lots of diagnostic stuff is printed, indicating successful delivery, including something like “050 … Sent”.

Check that user pi did indeed receive the mail. We could login as user pi and read the mail with an application (do that by all means), but just tailing the user’s mail file is quicker:

# tail /var/mail/pi

You will see the received mail, ie. lots of header information followed by a blank line and your actual message:

Hello pi user from root

Raspbian Wheezy only: Enable IPV6

At around the end of March 2016, an update was made to Raspbian Wheezy (Debian 7) that will prevent local mail from working unless you have IPv6 enabled. This only affects users of Wheezy. IPv6 is enabled by default on Jessie (Debian 8), so it isn’t a problem. However, Wheezy users might see errors like these after updating their systems with apt-get:

Eg. local mail fails, even after making all of the configurations above:

root@raspberrypi:# sendmail -v pi
test 
pi... Connecting to [127.0.0.1] via relay...
pi... Deferred: Connection refused by [127.0.0.1]

The “Connection refused” message indicates that the sendmail daemon is not running. Check it with:

root@raspberrypi:# ps -ef | grep sendmail

If it isn’t running, attempt to start the daemon:

root@raspberrypi:# service sendmail restart

If that falls (check with ps again), look at the end of the file /var/log/mail.log for messages like these:

# tail /var/log/maillog
root@raspberrypi:# tail /var/log/mail.log
Apr  3 14:52:07 raspberrypi sm-mta[3064]: NOQUEUE: SYSERR(root): opendaemonsocket: daemon MTA-v6: can't create server SMTP socket: Address family not supported by protocol
Apr  3 14:52:07 raspberrypi sm-mta[3064]: daemon MTA-v6: problem creating SMTP socket
Apr  3 14:52:07 raspberrypi sm-mta[3064]: NOQUEUE: SYSERR(root): opendaemonsocket: daemon MTA-v6: server SMTP socket wedged: exiting

The sendmail daemon is failing to start because it seems to require IPv6 to be running. After much messing about, I found the easiest solution was just to enable IPv6.

Edit the file /etc/modules

root@raspberrypi:# vi /etc/modules

and add a single line to the end of it:

ipv6

and reboot the Pi:

root@raspberrypi:# shutdown -r 0

After the system reboots, local mail should be working and sendmail should be running correctly:

root@raspberrypi:# sendmail -v pi
test
<ctrl-d> 
root@raspberrypi:# ps -ef | grep send
root      2381     1  0 00:21 ?        00:00:00 sendmail: MTA: accepting connections 

Send a Picture

It is quite easy to send email attachments from the command line or a script. One of the best ways is to use mutt.

Install mutt:
# apt-get install mutt

Send an email. You don’t need to be root for this, so type <ctrl-d> to go back to the non-root user. The “echo” bit here just sends an empty email, and the “-a” attaches the jpg file. On my Pi, there is an image called “driveway.jpg” installed by default. Email it as follows. Note the double minus (–) seperating the destination adddress from the other options:

$ echo | mutt -a /usr/share/scratch/Media/Backgrounds/Outdoors/driveway.jpg -s "Photo" -- someuser@hotmail.com

I use this method to email webcam pictures to an external email account.

Conclusion

Thanks for reading. I hope you found this guide useful.

24 thoughts on “Enable Outgoing Mail on Raspberry Pi

  1. Just to confirm: it says create the file “authinfo” & then it mentions it in the config file as “authinfo.db” ~ is that correct?

    • Hi Riquez. Yes that is correct. authinfo.db is created when you run the “makemap” command. I’ve added an extra sentence to clarify that.

  2. Hi,

    Clearly this works, but I get 550 rejected is temporarily blocked. Contact support [pb1]
    Although from all other computers and devices, my mail works OK. Looks like maybe anything sent via simple command line sendmail has a suspicious looking header structure maybe?

  3. Hi, sorry to come back at you so long after you published this but I have been trying your method on a Pi running Jessie. I am also a btinternet user so I have set my system up almost the same as yours, just a different domain name which I get from No-IP.com.
    However, when I try to send an email I get the long list of text you mention but no sign of a “235 PLAIN authentication successful” message”. What I have noticed is part way through I get:
    Connecting to mx.bt.lon5.cpcloud.co.uk. via esmtp
    050 521 rgin14.bt.int.cpcloud.co.uk Service not available – no PTR record for 92.207.157.54

    Do you have any advice on what is causing this and how I might fix it? I’m not very experienced on Linux stuff so any suggestions would be gratefully received

    PhilipJ

    • Hi Philip. The mail system seems to be saying that there is no reverse DNS record (PTR record) associated with your No-IP domain name. That is, your domain name resolves to your IP, but in the other direction, your IP address does not resolve to anything. Usually, if you are using a dynamic IP address (which is most likely) your IP address should resolve to a temporary domain name allocated by your ISP. It can be checked with the “host” command.
      The command:
      host
      …should print your IP address, and the command:
      host

      …should print a temporary domain name

      do both commands work properly ?

      Cheers, Jim.

      • “The command:
        host
        …should print your IP address, and the command:
        host
        …should print a temporary domain name”

        Am I missing something here? These are the same command, and neither of them do anything useful…

  4. Great post.
    A note: for those that need to connect to a different port than 25, I found this => https://unix.stackexchange.com/questions/132711/using-port-587-with-sendmail

    Also, I have a problem. I get a connection, but I get a 535 Incorrect authentication data. >>> MAIL From: SIZE=18 AUTH=pi@mydomain.com

    which is weird because I created authinfo and authinfo.db as you directed above with my username and password. Why does it say from pi@mydomain.com instead of myusername@mydomain.com?

    Thanks.

    • Hi Reswob, thanks for the port information. The message says “pi@mydomain.com”. It seems that the email is being sent by the “pi” user, and not by your other user. Make sure you are logged in as myusername and repeat the test. However, email from either user should work. I am not sure why you are seeing the 535 error. Check that your authinfo file contains the right user name and password.

      • Jim, (and anyone else who finds this comment), the problem was fixed…. but life happened and I don’t remember what tweak I used to fix it. (doh!)

        I suspect it was a typo, but I’m not sure. If I figure it out, I’ll update.

  5. Hello! Great post and it’s helping me a lot.
    I know it’s been a long time, but if you’re out there and can help me with a question …

    I did everything the way you want, but when it comes to sending the email, a timeout error appears.

    “Myemail @ maydomainserver ……. Deferred: Connection timed out with mydomainserver.com”

    What can it be?
    I tested it via another client and the information is all correct.

    Thank you for your time.

    • Hi Danilo. The “Deferred: Connection timed out with…” message usually indicates a problem with the remote mail server. Or more likely, that your system cannot connect to it. Are you able to ping the server from the shell ?

      For example, in the article above, my mail server was mail.btinternet.com. And I can ping that from a shell without a problem.

      # ping mail.btinternet.com
      PING mail.btinternet.bt.lon5.cpcloud.co.uk (65.20.0.43) 56(84) bytes of data.
      64 bytes from mail.btinternet.bt.lon5.cpcloud.co.uk (65.20.0.43): icmp_seq=1 ttl=248 time=9.85 ms
      64 bytes from mail.btinternet.bt.lon5.cpcloud.co.uk (65.20.0.43): icmp_seq=2 ttl=248 time=10.4 ms

      …and so on.

  6. I just want to say thanks, I spent a day trying to sort out sendmail using btinternet.com and your instructions worked a treat.

  7. This was a great article. Super helpful. However I’m getting the same “Deferred” timeout issue when attempting to sen the test email:

    “Deferred: Connection timed out with smtp.g.comcast.net.”

    I’ve confirmed that I’m able to ping / Telnet to the SMTP server no problem.

    Question: Do I need to have an actual domain registered in DNS for all of this to work, or can I just type any old nonsense into MASQUERADE_AS and my hosts file?

    Thanks again!

    • Hi Phil, the “timed out” message indicates some kind of networking error, even though you can ping the server. For example, the server might have been be too busy to allow more mail connections at that time. Try repeating the test later on.

      Yes, you need to register to domain name and put it into the submit.mc file where indicated.

  8. Hey thanks for the great tutorial! Sending mails to the internet works now. But I failed at “Fix Local Email”. There is no makefile 🙁 Maybe you can help me out? Thanks a lot in advance!

    root@RaspberryPi:/etc/mail# ls
    access address.resolve authinfo helpfile local-host-names m4 peers sendmail.conf sendmail.mc service.switch service.switch-nodns submit.mc
    root@RaspberryPi:/etc/mail# make
    make: *** No targets specified and no makefile found. Stop.

    • Also a second question:
      Mails sent by sendmail now come from: “USER @mydomain.com” is there a way to change it to “SOMETHING @mydomain.com” or even “SOMETHING @mydomain.com”? If yes – how?

    • Hi Chris, that is strange. I just checked again and the Makefile (in fact the whole /etc/mail directory) is created when you install Sendmail. You seem to be missing other files too, eg. the “aliases” link, “trusted-users” and the “tls” directory. All I can suggest is to try the procedure again from the beginning.

      Regarding the second question, the mail will normally come from “user@domain”, where “user” is your pi user name, eg “pi”, “chris” or whatever name you are logged in as. There is no easy way of changing it as far as I know.

  9. Thanks for a great tutorial. It has worked well apart from one thing. When I want to send mail from one address of my own domain to another one it seems to recognise it as an ‘internal’ mail and contacts the localhost without going ‘outside’ and then obviously fails.
    When I use it to send a mail to an address at btinternet the start looks as follows: “ZZZ@btinternet.com… Connecting to mail.XXX.YYY. via relay…”, but when I try to send it to another address at XXX.YYY it looks like: “ZZZ@XXX.YYY… Connecting to [127.0.0.1] via relay…”
    So how can I overcome this issue?

    • Hi John. Any email address of the format “ZZZ@XXX.YYY” should cause the email to be sent straight over the Internet. It should connect to BT, and not to 127.0.0.1.

      Testing it on my Pi, any email address of the correct format, even a silly, made up address like “fred@dfsdfsd.grerg”), works as expected:

      $ echo “hi fred” | sendmail -v fred@dfsdfsd.grerg
      fred@dfsdfsd.grerg… Connecting to mail.btinternet.bt.lon5.cpcloud.co.uk. via relay…

      This will be the case even if you own the domain name. The only email addresses to be locally routed are those with no domain part, or whose domain part appears to be a host name (ie. does not include a dot). This allows you to send mail to another user on the same system (your Pi). Eg:

      $ echo “hi root” | sendmail -v root
      root@localhost… Connecting to [127.0.0.1] via relay…

      $ echo “hi root” | sendmail -v root@localhost
      root@localhost… Connecting to [127.0.0.1] via relay…

      echo “hi” | sendmail -v root@localhost.somewhere
      root@localhost.somewhere… Connecting to mail.btinternet.bt.lon5.cpcloud.co.uk. via relay…

      Cheers,
      Jim.

      • Thanks for your reply Jim. Unfortunately I’m definitely trying to send it to an address with a dot in it (XXX.YYY) but it still connects to the localhost. 🙁
        Could it be through some weird link caused by the fact that the details for authentication in authinfo (myusername) also happens to be the name of the machine (ie not raspberrypi but myusername)? It’s the only ‘link’ I can find between the pi and the outside address.

        • Hi Jon, could you do a sendmail test like the ones in my comment above, and post the results ? (just the command and the first “connecting” line will be enough). Also, I’ll need to see the exact email address you are sending to.

          Cheers,
          Jim.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.