One of the most common needs when setting up a new web server is sending email. The safest and easiest way to do this is to connect your server to a mailing service such as SendGrid or Amazon SES. Using an external service will help you avoid pitfalls like your server IP getting blacklisted by anti-spam services.
In this tutorial we’ll go over how to connect FreeBSD’s built-in Sendmail service to SendGrid to send emails from your server. You can also adapt the settings for a different external mail service without much trouble.
If you’re new to FreeBSD, some of what we do may look a little scary, but you’ll soon be comfortable rolling up your sleeves to do a little recompiling of system tools like the FreeBSD pros.
Note: As of July 1, 2022, DigitalOcean no longer supports FreeBSD Droplets through the Control Panel or API. However, you can still spin up FreeBSD Droplets using a custom image. Learn how to import a custom image to DigitalOcean by following our product documentation.
In this tutorial, we will:
Before you begin this guide you’ll need the following:
nano
or vim
hostname
This tutorial is most easily followed as root:
sudo su
First, we need to recompile Sendmail so it can authenticate with an external mail service - in this case, SendGrid.
All of the steps are included here, but if you like, you can follow along with the official FreeBSD handbook.
Some software will be compiled from FreeBSD’s Ports Collection, so we need to make sure that is up to date first.
portsnap fetch && portsnap update
The Portmaster utility will let us easily compile software from the Ports tree, so let’s get that installed.
pkg install portmaster
Run the following command to make sure the system knows to install newly compiled packages in the latest package format for FreeBSD.
echo 'WITH_PKGNG=yes' >> /etc/make.conf
Using our newly installed Portmaster utility, compile and install the cyrus-sasl2
package with the following command. This is used for authentication with the external mail service.
portmaster security/cyrus-sasl2
When prompted, ensure LOGIN is checked, which should be by default. Choose OK and press ENTER
twice to choose all the defaults. When prompted, answer y
to upgrade and install your packages. You should expect a large amount of output, ending with:
Output===>>> Done displaying pkg-message files
===>>> The following actions were performed:
Upgrade of pkg-1.4.12 to pkg-1.5.0
Upgrade of perl5-5.18.4_11 to perl5-5.18.4_13
Installation of security/cyrus-sasl2 (cyrus-sasl-2.1.26_9)
Edit the file (creating it if it does not already exist) /usr/local/lib/sasl2/Sendmail.conf
and add the following to it:
vim /usr/local/lib/sasl2/Sendmail.conf
pwcheck_method: saslauthd
Next, install the saslauthd
service for SASL authentication. When prompted, accept the defaults and choose OK.
portmaster security/cyrus-sasl2-saslauthd
Edit the system configuration file /etc/rc.conf
and add the following configuration parameters at the end of the file. Replace your_hostname
with your server’s hostname.
vim /etc/rc.conf
hostname = "your_hostname"
sendmail_enable="YES"
saslauthd_enable="YES"
Now start the saslauthd
service.
service saslauthd start
You should see this output:
Outputusage: hostname [-fs] [name-of-host]
usage: hostname [-fs] [name-of-host]
Starting saslauthd.
Edit the /etc/make.conf
file, adding the following parameters so the system knows which SASL Sendmail options to use.
vim /etc/make.conf
SENDMAIL_CFLAGS=-I/usr/local/include/sasl -DSASL
SENDMAIL_LDFLAGS=-L/usr/local/lib
SENDMAIL_LDADD=-lsasl2
In this section we’ll recompile Sendmail to use SASL authentication.
Now we need to sync the latest source code for FreeBSD 10.1.
First, we’ll install Subversion so we can easily get the source code we need.
pkg install subversion
Now we can check out the latest code for recompiling, directly from the FreeBSD project website, to update our sources in /usr/src
.
svn co http://svn.freebsd.org/base/releng/10.1/ /usr/src
The next commands you need to run in succession, one group at a time. What we are doing here is telling the system to recompile (or rebuild) the built-in Sendmail packages with our new security and login requirements, and then reinstall Sendmail.
cd /usr/src/lib/libsmutil
make cleandir && make obj && make
cd /usr/src/lib/libsm
make cleandir && make obj && make
cd /usr/src/usr.sbin/sendmail/
make cleandir && make obj && make && make install
You’ve made it this far, and we’re done recompiling things. Let’s keep going!
For this next step we’ll walk through a basic Sendmail configuration that will tell Sendmail to route all outbound mail through our selected external smart hosting service.
First we’re going to be safe and create a backup of the /etc/mail
directory.
cp -a /etc/mail /etc/mail.bak
Enter the mail configuration directory.
cd /etc/mail
Run the following command to generate a basic mail configuration.
make
Create and edit the relay-domains
file, adding the following parameters. Replace your_server.example.com
with your FQDN, and example.com
with your domain name.
vim /etc/mail/relay-domains
your_server.example.com
example.com
Create and edit the local-host-names
file, adding the following parameters. Replace the variables with your local hostnames.
vim /etc/mail/local-host-names
your_server
your_server.example.com
Create and edit the access
file, adding the following parameters. (Note you’ll need to change the smtp.sendgrid.net
address if you’re using a provider other than SendGrid.)
vim /etc/mail/access
smtp.sendgrid.net OK
GreetPause:localhost 0
Create and edit the authinfo
file, adding the following parameters. Replace smtp_username
and smtp_password
with your SendGrid account name and password. If you elected to use a different external mail provider, you’ll also need to change the smtp.sendgrid.net
value on both lines to the server address for your provider.
vim /etc/mail/authinfo
AuthInfo:smtp.sendgrid.net "U:root" "I:smtp_username" "P:smtp_password" "M:LOGIN"
AuthInfo:smtp.sendgrid.net:587 "U:root" "I:smtp_username" "P:smtp_password" "M:LOGIN"
The access
and authinfo
files are really going to be simple databases from which Sendmail reads configuration parameters. This may sound confusing, especially if you’re new to FreeBSD and Sendmail, but you just need to run these two painless commands from the /etc/mail/
to generate the databases.
makemap hash access < access
makemap hash authinfo < authinfo
Now we’ll edit the base configuration we generated a few commands aback. Edit the your_server.mc
file. (You can ls
the /etc/mail/
directory if you’re not sure of the file name.)
vim /etc/mail/your_server.example.com.mc
Insert the following configuration lines between the dnl define(
SMART_HOST’, your.isp.mail.server')
block and the dnl Uncomment the first line to change the location of the default
block as shown below.
You’ll need to change the smtp.sendgrid.net
address to your provider’s server address if you’re not using a SendGrid account like in the example. You’ll also need to update the two instances of example.com
to the domain you’d like the mail to be from. (Note that you may need to set appropriate TXT, DKIM, PTR etc. records to avoid reports of spoofing.)
dnl define(`SMART_HOST', `your.isp.mail.server')
dnl SET OUTBOUND DOMAIN
MASQUERADE_AS(`example.com')
MASQUERADE_DOMAIN(example.com)
FEATURE(masquerade_envelope)
FEATURE(masquerade_entire_domain)
dnl SMART HOST CONFIG
define(`SMART_HOST', `smtp.sendgrid.net')dnl
define(`RELAY_MAILER_ARGS', `TCP $h 587')dnl
define(`confAUTH_MECHANISMS', `GSSAPI DIGEST-MD5 CRAM-MD5 LOGIN PLAIN')dnl
FEATURE(`authinfo',`hash /etc/mail/authinfo.db')dnl
TRUST_AUTH_MECH(`GSSAPI DIGEST-MD5 CRAM-MD5 LOGIN PLAIN')dnl
dnl Uncomment the first line to change the location of the default
Before we apply the changes, let’s walk through a bit of the above configuration. The first block is telling Sendmail that we’d like to make sure it appears that our outbound mail is coming from our domain example.com
.
The second block is defining where we want to smart host our mail to, including the port, authentication methods, and our authentication info that we set up in a previous step. Notice that we’re referencing the /etc/mail/authinfo.db
file.
Now let’s apply the changes we’ve made. Make sure you’re still in the /etc/mail/
directory. Make sure Sendmail is started:
service sendmail start
Updating our configuration:
make
make install restart
Restart Sendmail:
service sendmail restart
Our Sendmail configuration is done. The next step is to send a test email.
Now that we have gone through all the steps for a proper setup, let’s make sure that everything is working.
Use the mailx
command to send a test message to a real email account you use every day.
mailx your_real_email_address@example.com
When prompted, enter test
or whatever you want for a subject, and then press ENTER
.
Subject: test
You’ll then be presented with just a cursor and the ability to write the body of your test email. Just write the single word test
again and press ENTER
again.
test
You need to tell mailx
that you’re done writing your message; to do that we have to end the message with a single .
and press ENTER
one final time. You’ll immediately see EOT
as confirmation of that.
.
EOT
Next, run the the following command to check that the mail queue is empty and that our message has been sent.
mailq
The output should look like this if our test message has been successfully sent, and you should see it in your inbox shortly.
/var/spool/mqueue is empty
Total requests: 0
Go check your email now to make sure the message arrived. It should be from freebsd@example.com.
Blindly trusting the fact that the mail queue is empty is not a valid test of success. Even if you’ve already received the message, you’re going to want to know the basics in viewing your mail logs. Run the following command.
tail -f /var/log/maillog
The two keys you’re looking for in the log output are
Sent (<message id> Message accepted for delivery)
relay=smtp.sendgrid.net. [208.43.76.147], dsn=2.0.0, stat=Sent (Delivery in progress)
Make sure you can spot these messages in the log output below.
Mail LogFeb 11 04:09:13 your_server sm-mta[49080]: t1B49CW0049080: from=<freebsd@your_server>, size=331, class=0, nrcpts=1, msgid=<201502110409.t1B49CZ4049079@your_server>, proto=ESMTP, daemon=Daemon0, relay=localhost [127.0.0.1]
Feb 11 04:09:13 your_server sendmail[49079]: t1B49CZ4049079: to=your_real_email_address@example.com, ctladdr=freebsd (1001/1001), delay=00:00:01, xdelay=00:00:01, mailer=relay, pri=30040, relay=[127.0.0.1] [127.0.0.1], dsn=2.0.0, stat=Sent (t1B49CW0049080 Message accepted for delivery)
Feb 11 04:09:13 your_server sm-mta[49082]: STARTTLS=client, relay=smtp.sendgrid.net., version=TLSv1/SSLv3, verify=FAIL, cipher=AES128-GCM-SHA256, bits=128/128
Feb 11 04:09:13 your_server sm-mta[49082]: t1B49CW0049080: to=<your_real_email_address@example.com>, ctladdr=<freebsd@your_server> (1001/1001), delay=00:00:00, xdelay=00:00:00, mailer=relay, pri=30331, relay=smtp.sendgrid.net. [208.43.76.147], dsn=2.0.0, stat=Sent (Delivery in progress)
This shows that your message has been accepted and is on its way to your inbox, which may be a bit anticlimactic if you’ve already received it.
To do live testing and troubleshooting, you can have two terminal sessions open and leave the tail -f /var/log/maillog
command running in one, while you send test messages in the other.
You’re now ready to start sending outbound email from your FreeBSD server via SendGrid or any other mail service you like. Any web sites or web applications you deploy will now be able to take advantage of this with minimal to no configuration.
If you have any questions or comments, please leave them below.
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!
I thought the purpose of using a relay was to make the process easier. I don’t see how the process of sending to an external smtp service is any easier than sending directly to recipients.
The only benefit of the external service appears to be tech support in setting up your mail. That actual setup is not easier, or am I missing something?
Hi,
Can you please create a How To Send Email through an External SMTP Service with Sendmail on Ubuntu 14.04?
Thanks
Hi, The email send by this has a name “Created by bsdcloud-init”. How can I customize it accordingly? Thanks W.