Setting up an Email Server With a VPS

Created on
July 5, 2021
Events of
Summer 2021
a picture of a paper airplane on a beige bric wall by Daria Nepriakhina, courtesy Unsplash Daria Nepriakhina Author's Note: Due to the enumerating nature of Wireguard, Source NAT rules do not work from behind the NAT. As a result, you should host the email apparatuses on the endpoint and maintain synchronous users with the same UID, GID and directory structure. Share from the NAT to the endpoint what is needed over NFS, and specify the private IP of the Wireguard endpoint, not the carrier.
This haunted me for ages. I bungled firewall rules, name resolvers and shook a DO rep and myself a few times to get this right. So, the instructions are for Debian Buster, but they work for LMDE4, so either is fine. This tutorial follows closest to the one on Server World Info (see citation in footer). We will be using PAM authentication behind our Wireguard network with ufw activated on the endpoint. Substitute example IPs to your own network. If you haven't yet, complete the Wireguard tutorial FIRST. Assume I did sudo -i before I started entering commands. This tutorial will cover inbound and outbound email.
You need a domain, above all else. Get one, modify its Zone Record to point to the endpoint's PUBLIC IP address as shown here. Add an SPF record like the one shown here. Add a user-specifying MX record, like the one here. This syntax is suitable for Enom users. Contact your registrar or peruse their FAQs to find out what works. Also, take the time to clean up your IP's reputation if you are able to. It will improve deliverability.
Now we lay down the firewall rules on the endpoint. So, as a DO customer, I have three firewalls that need to be configured. Allow port 25 (smtp), 110 (pop3), 143 (imap), 465 (smtps), 587 (submission), 993 (imaps) and 995 (pop3s). Once you get these working, map them how you want afterwards. Next, we need to install postfix, sasl libraries, and the imap and pop3 tools. Run these commands in the terminal:
apt-get install postfix sasl2-bin
This makes a request to the App Package Transporter to download the binaries for Postfix and Simple Auth Security Layer. Postfix facillitates the sending and receipt of email to and from the endpoint. SASL secures the credentials you use to talk to the SMTP server. When you send messages, you communicate to port 587 or 465, but the message is sent over to port 25 on its way out. The reason we need SASL is to prevent the server from being used as an open, unauthenticated relay, which would quickly create reputation issues.

As you finish installation, you will be presented with a Getty UI Prompt. Select "No configuration", press the right arow key until it highlights OK and then press Enter. Allow the installation to finish. We will now copy a template file that has most possible configuration options included but commented out. All you have to do is uncomment the lines I specify or append new lines to the end of the document. Remember, comments are your friend. Run the following command:
cp /usr/share/postfix/main.cf.dist /etc/postfix/main.cf
This copies the template to the postfix working directory. Because you chose no configuration, there isn't one. Now that there is, open it in a privileged nano session, and refer to this document for what should be changed. Use CTRL + SHIFT + - to search by line number, and CTRL + 3 and SHIFT + 3 (in that order) to see the numbering for yourself. We need to begin creating users to send email with, followed by adding their usernames to the /etc/newaliases file. If you are only hosting one domain, specifying it in this file will not matter. It will, however, require you OMIT the domain when logging in.
We now need to edit the /etc/aliases and add the usernames we created to the file. Please see this file to get an idea of what you need to do. When you are finished editing this file, you will need to edit the /etc/master.cf file and format it as you see it in this file. Run the following privileged command:
newaliases && systemctl restart postfix
This reloads the alias file and postfix at the same time. The '&&' operator is yet another boolean, but for 'and'. We It feels great not having to pay extra for aliases anymore.
So, Dovecot is what is used to store the email when it is not being transferred between smtp servers. Run the following command to get things started:
apt-get install dovecot-core dovecot-pop3d dovecot-imapd dovecot-managesieved dovecot-lmtpd
This command installs the dovecot core package and the binaries for pop3 and imap, plus the ability to sort messages (advanced reading below). Depending on what functionality you plan to enable, you might install different packages later. For specialized topics please start here. For now, let us open the /etc/dovecot/dovecot.conf, where we will enable listening by uncommenting Line 30. If you do not need ipv6, remove the comma followed by the double colon (, ::). Save the file. Then, move on to /etc/dovecot/conf.d/10-auth.conf and make a change to Line 10, and make sure dovecot does not disable plaintext authentication, which it normally does, by changing make a change to line 100, appending 'login' to the list of authentication mechanisms. Also, edit Line 51 and choose %Ln as the auth_username_format. This allows for flexibility with LMTP and extra origin domains later. The default is different.
We now need to affirm the mailbox location we originally specified in the postfix configuration by opening /etc/dovecot/conf.d/10-mail.conf. We are going to specify a different mailbox location in Line 30. In the mail_location field, type "maildir:~/Maildir". This instructs dovecot to save email messages to the "Maildir" folder of whatever user is signed in. Since we are using PAM, this means a "Maildir" directory should show when you receive your first email. Now we need to instruct dovecot to listen for postfix smtp authentication. Open the /etc/dovecot/conf.d/10-master.conf file and make changes to lines 107 to 109. The output should resemble this. We also need to enable TLS for Dovecot so we can securely access our mail over port 993 and 995. We will open /etc/dovecot/conf.d/10-ssl.conf and make changes to line 6, by saying 'yes' to SSL, and adjust lines 12 and 13 to point to the same certificates we mentioned in the /etc/postfix/main.cf, but you MUST retain the chevron brackets in order for dovecot to read the certificates or it will fail. When you are done, restart dovecot using the following privileged command:
systemctl restart dovecot
Securing your server goes a long way in preventing it from being overrun by anon hoodlums, or worse, those who do not mean to. That is where the SASL binaries we downloaded earlier come into play. We will need to create a file using your favorite terminal editor. In my case, that is nano:
nano /etc/postfix/sasl/smtpd.conf
Add the following text to this file, and then hit Ctrl+S to save. Ctrl is represented by the caret symbol and M is the alt key. Press Ctrl+X to leave.
We must now create a separate SASL process to be used by Postfix. We are going to copy an existing file and then edit the file we copied. Issue the following commands:
cp /etc/default/saslauthd /etc/default/saslauthd-postfix
Edit it so its inputs resemble the following text file.
Some files and folders will need their permissions adjusted or created in order for this to work. Root becomes owner, but SASL becomes the group owner for these new directories. CHMOD 710 implies that the owner has full control, the group can execute, but everyone else cannot do anything. Issue the following command:
dpkg-statoverride --add root sasl 710 /var/spool/postfix/var/run/saslauthdt
Remember when we told Dovecot that Postfix would be the handler for most mail processes? We have to tell SASL that too, by adding Postfix to the SASL group. Type adduser postfix sasl to do just that. Restart everything using the following commands:
service saslauthd restart
systemctl restart dovecot postfix

The good part is finally here: The login process. You will need to create a new email account, and because I do not know how, you need to create the initial folders yourself. The username field should be just the username, the server should be the same value as $myhostname in your main.cf, and the password should be the same as your user account. If you have issues connecting, type tail -n 30 /var/log/mail.log to get a handle on what is going on. Happy Sending and Receiving, and don't be a sphincter about it.
Advanced Reading - Sieve
There are other things you can do now that you have settled into maintaining your own email server, and that is automatically filtering messages into subfolders of your choosing once they arrive. This requires the activation of LMTP, and the installation of dovecot-managesieved. You will need to open /etc/dovecot/conf.d/15-lda.conf in your favorite terminal editor. Despite the tutorial, you do not need to edit Line 7. Instead, edit Lines 40, 43 and 47 by uncommenting them and changing their option to yes, yes and $mail_plugins sieve, respectively. This ensures that if you type your filter wrong, it will create the folder with the misspelling rather than toss the message into the void. You will also need to edit /etc/postfix/main.cf and navigate to line 468, and uncomment the field. Type /usr/lib/dovecot/deliver to ensure that mail sorting AFTER delivery is handed off to Dovecot.
There is a specific process that needs to be enabled in the /etc/dovecot/conf.d/10-master.conf file that gets LMTP to start listening. Enter the following text after Line 52 or the Submission entry, after the last closing brace. I did not specify a default process limit, and it did not affect delivery. In addition, you need to make sure that dovecot knows where the sieve file is and how it should be handled. Open /etc/dovecot/conf.d/90-sieve.conf and edit line 39 to point to its location, and line 123 to specify how LMTP will interpret recipients. The "+" option works best for the settings mentioned in this tutorial. Here is an example file to get you started.
We also need to open /etc/dovecot/conf.d/20-lmtp.conf and add the following text to the end of the document, replacing the existing protocol lmtp entry. As always, restart everything once you have added those features in, and view logs if things go south or not as expected:
service saslauthd restart
systemctl restart dovecot postfix

Advanced Reading - DKIM Signing
Securing our server using SASL is one of many steps you can take to protect your email reputation. But DKIM goes the extra step in making sure it is done well. We will need to open up our zone record in a separate window, and in another, install the following:
apt-get install opendkim opendkim-tools
We must then generate a key that is used by your domain. Use the following command. The below example opens a shell as the opendkim user, writes a file called currentyear to the /etc/dkimkeys directory for domain.net:
sudo -u opendkim opendkim-genkey -D /etc/dkimkeys -d domain.net -s currentyear
Two files are created in this directory, and you will notice that the filenames are the same, but have the extensions .private and .txt. More on this shortly. The keys must only have read and write permissions for the owner, or else OpenDKIM will fail to start. Enter the following commands after you have created the keys:
cd /etc/dkimkeys
chmod 600 *.key

This changes to the /etc/dkimkeys folder, followed by assigning key files with read and write permissions for the owner only.
We now have to configure OpenDKIM to point to the .private file, and our zone record to point to the DKIM record. Open up /etc/opendkim.conf, and edit Line 13 to point to your domain, minus the hostname. Edit Line 14 to point to the absolute path toward the .private file, and edit Line 15 to match the name for the .private and .txt file. Edit Line 33 to point to a internet port facing localhost. The example shows 8891, but any port should work. The syntax is inet:chosenport@localhost. Comment out Line 34 to disable. The internet socket is an option for those who do not want to fuss with permissions. We must edit /etc/postfix/main.cf and add the following text to the end of the file which will allow OpenDKIM to sign headers before messages are sent. Finally, restart EVERYTHING:
service saslauthd restart
systemctl restart dovecot postfix opendkim

Assuming you are looking at your zone record, create a TXT field based on the information you find in /etc/dkimkeys/currentyear.txt and append it to your domain zone file. If you use a hosting company, the host field should say "currentyear._domainkey", the type field should say "TXT", and the text field should be void of line breaks if you are using a hosting company interface and add a semicolon at the end of the "p=" string. Validate your DKIM settings using either port25.com or mxtoolbox.com, and happy validated sending!
- 🎙
© 2021 Server World Info, Debian Wiki | SASL Debian Wiki | DKIM Cadena-IT Mass Transit Honchkrow | Last modified (none)