Setup Sendmail with Raspberry PI to Send Emails (and Attachments)
This tutorial will show you how to install and configure Sendmail on Raspberry PI computer boards, to enable your RPI to send email from the terminal console or scripts/app. This is helpful when you need to send notifications from bash scripts or even applications.
Please note that Sendmail is not a terminal email client. If you need this, you can take a look at my Terminal Email Client with Raspberry PI and Mutt. Moreover, if you need to send email notifications from your Python programs, you can try my Send Email from Raspberry PI with Python tutorial.
What is Sendmail
Sendmail is a Mail Transfer Agent running in many Linux distributions from the early 1980s. It had so much success that in 1996 about 80% of the publicly reachable mail servers on the Internet ran Sendmail (ref. Sendmail page on Wikipedia).
Despite the usage decline in recent years, it remains a great tool offering great flexibility in routing emails.
It is important to note that Sendmail is NOT an email server, in the sense that an email server must be able also to deliver email messages to the users and give them a way to access their mailboxes. So, Sendmail needs an external service to deliver email messages. This can be, for example, any email service provider like Gmail, Hotmail, Yahoo, and so on.
For this tutorial, I will show you how to install and configure Sendmail to send email via Gmail, but you can use it with any other Internet email provider, just changing the connection parameter according to the SMTP settings usually available also for email clients.
What We Need
As usual, I suggest adding from now to your favourite e-commerce shopping cart all the needed hardware, so that at the end you will be able to evaluate overall costs and decide if to continue with the project or remove them from the shopping cart. So, hardware will be only:
- Raspberry PI Computer Board (including proper power supply or using a smartphone micro USB charger with at least 3A)
- high speed micro SD card (at least 16 GB, at least class 10)
Step-by-Step Procedure
Get Google App Password (Only for Gmail Users)
Many internet email providers allow you to use your email password for applications. Gmail uses a different authentication process, so it requires you to get an “App Password”. This is a 16-character string, different from your email password, that you can use in substitution of it.
The official link explaining how to get an App Password with your Google account can be found at the following link: https://support.google.com/mail/answer/185833?hl=en.
Prepare the Operating System and Install Sendmail
Usually, you will need Sendmail with headless installations. So, you can start installing Raspberry PI OS Lite which gives you the best performance with your RPI. In some cases, you may prefer installing a complete Desktop environment: in this case, you can start by installing Raspberry PI OS Desktop (working from its internal terminal). If you need help with the difference between the two options, you can read my Raspberry PI OS Lite vs Desktop article.
Once installed, please make sure your OS is up to date with the following terminal command:
sudo apt update -y && sudo apt upgrade -y
To make Sendmail work, we also need to setup a complete hostname for our Raspberry PI. We can do it by editing the hosts file:
sudo nano /etc/hosts
In the opened file, you should find the following row:
127.0.1.1 raspberrypi
So, please append the “raspberrypi.local”, so that this line should appear as the following:
127.0.1.1 raspberrypi raspberrypi.local
Save and close.
You can now install Sendmail with the following terminal command:
sudo apt install sendmail -y
Setup Remote Email SMTP
At this point, we must configure the settings according to the SMTP configuration provided from your internet email provider. Please open the sendmail.mc configuration file as follows:
sudo nano /etc/mail/sendmail.mc
At the end of this file, you will find the following lines:
MAILER_DEFINITIONS
MAILER(`local')dnl
MAILER(`smtp')dnl
Append the following lines just before the “MAILER_DEFINITIONS” line.
Please change the parts highlighted in red according to your provider settings. In many cases, you should get it working by changing just the SMTP address (“smtp.gmail.com” below) and the SMTP port (“587” below). The following are those tested by me with Gmail and you can leave as shown in case you are using Gmail:
define(`SMART_HOST',`smtp.gmail.com')dnl
define(`RELAY_MAILER_ARGS', `TCP $h 587')dnl
define(`ESMTP_MAILER_ARGS', `TCP $h 587')dnl
define(`confAUTH_MECHANISMS', `EXTERNAL GSSAPI DIGEST-MD5 CRAM-MD5 LOGIN PLAIN')dnl
FEATURE(`authinfo',`hash /etc/mail/auth/client-info')dnl
TRUST_AUTH_MECH(`EXTERNAL DIGEST-MD5 CRAM-MD5 LOGIN PLAIN')
Save and close. Recompile the Sendmail settings with the following command:
sudo make -C /etc/mail
Setup Authentication
Now, we must set the authentication string that will allow Sendmail to authenticate with our remote internet email provider. Let’s create the “auth” folder and the client-info file, which will include the authentication settings:
sudo mkdir /etc/mail/auth/
sudo nano /etc/mail/auth/client-info
In the new file, please add the following string, changing the words highlighted in red with your own username and password. In the case of Gmail, of course, the password must be the App Password previously created:
AuthInfo:smtp.gmail.com "U:*******bba@gmail.com" "P:abcd efgh ijkl mnop"
Save and close.
Let’s create the database maps used by Sendmail:
sudo makemap hash /etc/mail/auth/client-info < /etc/mail/auth/client-info
Restart Sendmail
Finally, we can restart sendmail to get all the configuration working. The following command will do the job:
sudo systemctl restart sendmail.service
We can check that the service is running correctly with the systemctl status command:
pi@raspberrypi:~ $ sudo systemctl status sendmail.service
● sendmail.service - LSB: powerful, efficient, and scalable Mail Transport Agent
Loaded: loaded (/etc/init.d/sendmail; generated)
Active: active (running) since Thu 2024-02-08 22:09:16 CET; 10min ago
Docs: man:systemd-sysv-generator(8)
Process: 23379 ExecStart=/etc/init.d/sendmail start (code=exited, status=0/SUCCESS)
Tasks: 1 (limit: 9262)
CPU: 99ms
CGroup: /system.slice/sendmail.service
└─23435 "sendmail: MTA: accepting connections"
Feb 08 22:09:13 raspberrypi su[23412]: (to smmsp) root on none
Feb 08 22:09:13 raspberrypi su[23412]: pam_unix(su:session): session opened for user smmsp(uid=107) by (uid=0)
Feb 08 22:09:14 raspberrypi su[23412]: pam_unix(su:session): session closed for user smmsp
Feb 08 22:09:14 raspberrypi sm-mta[23433]: gethostbyaddr(192.168.1.218) failed: 1
Feb 08 22:09:14 raspberrypi sm-mta[23435]: starting daemon (8.17.1.9): SMTP+queueing@00:10:00
Feb 08 22:09:16 raspberrypi sendmail[23379]: Starting Mail Transport Agent (MTA): sendmail.
You may note the gethostbyaddr() check failing. This will not create problems in sending emails.
Test Sendmail
We are ready to test our email-sending tool.
Sending a Simple Email from Terminal Prompt
By default, the command “sendmail recipient@example.com” (where “recipient@example.com” is the address which will receive the email message) enables an interactive session where you can specify many settings like the subject. You can also write the body message in different lines. The sending process will start when you will use the CTRL+D key combination. Try the following test, by changing the “recipient@example.com” with your address:
pi@raspberrypi:~ $ sendmail recipient@example.com
Subject: Test
ciao
You will receive an email with the specified subject and the “ciao” in your email body.
You can even add multiple recipients after the sendmail command:
pi@raspberrypi:~ $ sendmail recipient1@example.com recipient2@example.com
Subject: Test
ciao
An interesting sendmail option is the “-v”, which means “verbose”. This option will let you see the email transferring flow so that you can debug any error.
We’ll test it by appending the sendmail command to an “echo” message. In this way there’s no need to hit the CTRL+D combination, as sendmail will immediately start the email delivery without the interactive session:
echo "Subject: sendmail test" | sendmail -v recipient@example.com
Sending Email From a File
Instead of compiling the email message from a txt message. Let’s try it by creating a generic mail.txt file:
nano email.txt
Include the following 2 lines:
From: Your Name <********@gmail.com>
Subject: Test sendmail message
This is the email body
Save and close. We’ll send this email with the following terminal command:
sendmail recipient@example.com < email.txt
Sending HTML Email From a File
As you’ve seen, the messages sent up to now are in plain text. Let’s try to compose an HTML message. In this case, you will need a bit of HTML coding skills, but it will allow you to create cool email messages.
Let’s change the mail.txt content. Open for editing:
nano email.txt
Replace the content with the following:
Subject: Test sendmail HTML message
Content-Type: text/html
MIME-Version: 1.0
<html>
<h1>This is the title</h1>
<p style="width:20px;height:20px;background-color:#ffcc00;">
<b>This</b> is the email body
</p>
</html>
Close and save. Check the results by sending this email message:
sendmail recipient@example.com < email.txt
Sending HTML Email From a File with Attachment
The last example adds an attachment to our email message.
Let’s create first a simple txt attachment:
nano attach.txt
We’ll insert just a simple text record in this attachment:
test attachment
Save and close.
Open again our mail.txt for editing:
nano email.txt
Replace the content with the following:
subject: Test sendmail HTML message with Attachment
mime-version: 1.0
content-type: multipart/related; boundary=messageBoundary
--messageBoundary
Content-Type: text/html
<html>
<h1>This is the title</h1>
<p style="width:20px;height:20px;background-color:#ffcc00;">
<b>This</b> is the email body
</p>
</html>
--messageBoundary
content-type: text/plain; name=attach.txt
content-transfer-encoding: base64
Close and save. Now, we need to add the attachment to this email message. We can add it once encoded with base64, but we must add a new line (empty) after the “content-transfer-encoding: base64” line. Both the operations can be achieved with the following terminal command:
echo -e >> email_att.txt && base64 attach.txt >> email_att.txt
You can see the result with the cat command, to check that your output is similar to mine:
pi@raspberrypi:~ $ cat email.txt
subject: Test sendmail HTML message with Attachment
mime-version: 1.0
content-type: multipart/related; boundary=messageBoundary
--messageBoundary
Content-Type: text/html
<html>
<h1>This is the title</h1>
<p style="width:20px;height:20px;background-color:#ffcc00;">
<b>This</b> is the email body
</p>
</html>
--messageBoundary
content-type: text/plain; name=attach.txt
content-transfer-encoding: base64
dGVzdCBhdHRhY2htZW50Cg==
Please note the empty line before the “dGVzdCBhdHRhY2htZW50Cg==”, which is the result of encoding the file.
Now, you can test it with the same sendmail command:
sendmail recipient@example.com < email.txt
What’s Next
Interested in more cool ways to use your Raspberry PI computer board? Take a look at peppe8o Raspberry PI computer tutorials!
Enjoy!
Hi!
great job. In my case i had to install libsasl2-modules to work.
sudo apt-get install sasl2-bin libsasl2-modules
Thank you for your feedback Stefano. I will re-test it as soon to check if something changed in the default packages with Bookworm