Arch Linux mail server tutorial - part 3 - Get DNS right, it's important!
Published on 2017-12-29. Modified on 2021-07-20.
In this part of the tutorial we're going to take a look at the important parts of setting up DNS in order to run a mail server.
Get DNS right, it's important!
DNS is short for Domain Name System. DNS is a comprehensive translation system that in its simplest form is used to translate domain names to unique IP addresses.
Because computers communicate using numbers, and we humans, obviously, do not, DNS translates such numbers into human-friendly phrases. Each IP address on the Internet must be distinct from others. An IPv4 address could be a set of any four numbers in the range from 0 to 255, like 208.67.222.222. When you type a domain name into your browser, the DNS system translates the domain name into the IP address associated with the domain. Once the website IP address is found, your browser connects with the web server and the requested page is displayed in your browser. This works the same for SMTP servers when they relay email.
DNS is the cornerstone in how the Internet functions.
In order to operate a mail server you need to setup some DNS records for your server. If you are the owner of the example.com
domain, and a mail server on the Internet wants to send an email to foo@example.com
, that mail server needs to find out which other mail server on the Internet it will have to establish an SMTP connection to in order to deliver the email.
If you don't know anything about DNS you need to do some research first. It is very important that you get DNS right!
Here are some recommended resources:
You need the following records set up:
- An A record and a CNAME record, or two A records (must have!).
- A MX record (must have!).
- A PTR record (very important).
- A SPF record (very important).
- A DKIM record (very important).
- A DMARC record (very important).
The PTR, SPF, DKIM, and DMARC records are not obligatory, but they are very important if you want to make sure the emails you send out isn't rejected by receiving mail server (more about that in a moment).
The A, CNAME, and MX records
Because different services can run on different machines you need to specify both an IP address for your apex domain (the domain name without anything in front of it), and an IP address for the FQDN you enter as the MX server.
When a foreign SMTP server contacts a DNS server in order to get information about your SMTP server, it will ask who can receive email for the apex domain, example.com
, and get the FQDN located in the MX record, mail.example.com
, then it will ask for the IP address of the FQDN mail.example.com
INFO:
In most cases bigger corporations have more than one SMTP server, just in case a server should fail to respond for various reasons. Each server is then listed in an order of priority, like this:
gmail.com. 3600 IN MX 5 gmail-smtp-in.l.google.com.
gmail.com. 3600 IN MX 10 alt1.gmail-smtp-in.l.google.com.
gmail.com. 3600 IN MX 20 alt2.gmail-smtp-in.l.google.com.
gmail.com. 3600 IN MX 30 alt3.gmail-smtp-in.l.google.com.
gmail.com. 3600 IN MX 40 alt4.gmail-smtp-in.l.google.com.
The server with the lowest priority number, in this case number 5, will be chosen first.
If you have the resources it's always a good idea to have at least one backup server.
Now, mail.example.com
and example.com
may very well be the same machine, but you need to tell the DNS server that either by using two A records, or by using a CNAME record with mail.example.com
which points to example.com
and then use an A record for example.com
So you should then at least have these three records to begin with:
HOST TYPE POINTS TO TTL example.com A 1.2.3.4 3600 mail.example.com CNAME example.com 3600 example.com MX mail.example.com 3600
Or:
HOST TYPE POINTS TO TTL example.com A 1.2.3.4 3600 mail.example.com A 1.2.3.4 3600 example.com MX mail.example.com 3600
The reason why you need to setup both example.com
and mail.example.com
is because they could each be associated with two different machines and IP addresses.
Let's make another example in which example.com
and www.example.com
are the same machine serving HTML (a web server in other words), but the mail server mail.example.com
is setup on another machine. The setup would then look like this:
HOST TYPE POINTS TO TTL example.com A 1.2.3.4 3600 www.example.com CNAME example.com 3600 example.com MX mail.example.com 3600 mail.example.com A 4.5.6.7 3600
If you have never handled DNS before this part can be a bit confusing so you need to make sure you do it right. Look at the information provided by your DNS provider on how to set it up correctly and ask them if you're in doubt.
We can imagine an email DNS request between the mail server (SMTP) and the DNS server as a conversation:
SMTP server asks: I got an email for foo@example.com
, who's responsible for accepting email for the domain example.com
?
The DNS server looks at the MX record and provides the answer: mail.example.com
is responsible for accepting email on behalf of example.com
.
The SMTP server then asks: Where's mail.example.com
located on the Internet?
The DNS server then looks at the A record for mail.example.com
and answers: It's located at IP address 4.5.6.7.
If example.com
and mail.example.com
are located on the same IP address, it's your choice whether you want to use two A records or one A record and a CNAME record. When a DNS server is authoritative for domains located in the same zone there is no difference between A records and CNAME records queries, they are equally fast.
If you try to look up www.gmail.com
you'll see something like this:
$ dig www.gmail.com ;; ANSWER SECTION: www.gmail.com. 86400 IN CNAME mail.google.com. mail.google.com. 593961 IN CNAME googlemail.l.google.com. googlemail.l.google.com. 268 IN A 172.217.13.197
Which shows that www.gmail.com
points to mail.google.com
, and mail.google.com
points to googlemail.1.google.com
, which is located at the IP address 172.217.13.197. In other words all these addresses are identical. The DNS server resolved the CNAME's for us and attaches the whole answer in one go.
The PTR record
A Pointer Record (PTR) resolves an IP address to a fully-qualified domain name (FQDN) as an opposite to what an A record does. PTR records are also called Reverse DNS records. PTR records are mainly used to check if the server name is actually associated with the IP address from where the connection was initiated.
You can get the IP address of a domain by using the "dig" command:
$ dig send.one.com send.one.com. 1003 IN A 46.30.211.140
And you can get the FQDN when you lookup the IP address (if a PTR record is setup) using the -x
option:
$ dig -x 46.30.211.140 140.211.30.46.in-addr.arpa. 1078 IN PTR send.one.com.
The most difficult record to deal with is the PTR record because you need permission from the owner of the IP address to set it up. If you cannot setup a PTR record because you don't own the IP address you're running with, and your ISP won't help you, you should first look for other options because some mail servers reject email from other mail servers that are missing a valid PTR record. However, if you haven't got any other options, which many home based legit mail server owners don't, you can still run your mail server, but you must make sure you get the SPF, DKIM, and DMARC records set. People do successfully run mail servers without valid PTR records without any problems (I myself have never had any problems), but the common denominator is the SPF, DKIM, and DMARC records.
The reason why a PTR record is important regarding mail servers is that any spammer may be able to send mail to a mail server, but many spammers will not be able to create a PTR record for their IP address, because they are using an open relay or a personal ISP, ie. an IP address that doesn't belong to them. This means that their IP address would not have an associated PTR record, or the PTR record is associated with the ISP. As such, blocking emails from IP addresses with no PTR record reduces the spam the mail server sends out and this is default on some SMTP servers.
The PTR record should match the SMTP response on port 25 when the receiving server sends back a verification check, which is the FQDN of the mail server. The PTR record shouldn't match the MX record as some believe, because the MX record may hold another server IP address altogether. The verification response that happens, which is called "sender verify" by most email servers, is when there is a match between the PTR record and the SMTP FQDN.
You can see a server's SMTP response by issuing the following command to an SMTP server using the IP address or the FQDN:
$ telnet 1.2.3.4 25 220 mail.example.com ESMTP OpenSMTPD
Where 1.2.3.4 is the IP address for the server in question. Basically, you will get a response that tells the server hostname, which is what the PTR record should match, in this case mail.example.com
.
Some administrators setup their mail server PTR record with a FQDN that points to a CNAME record. So if mail.example.com
is a CNAME for smtp.example.com
then they use that, but CNAME should never be used for any mail related matters. Make sure you set it to your FQDN of your mail server!
The PTR record should not contain anything besides the IP address and the FQDN.
This is how it should look. First we lookup the IP address for the SMTP server that One.com is using (as we did in the above example):
$ dig send.one.com send.one.com. 164 IN A 46.30.211.140
Then we use that IP address to lookup the PTR record:
$ dig -x 46.31.211.140 140.211.30.46.in-addr.arpa. 2240 IN PTR send.one.com.
Notice the trailing dot, that's not something you should put in, it gets automatically added.
If you are in doubt, get assistance from the ISP or DNS hoster your are using.
Continuing from the example above, let's add the PTR record to our DNS setup:
HOST TYPE POINTS TO TTL example.com A 1.2.3.4 3600 mail.example.com A 1.2.3.4 3600 example.com MX mail.example.com 3600 4.3.2.1.in-addr.arpa PTR mail.example.com 3600
Please notice how the IP address in the PTR record is listed backwards, this is how it is supposed to be.
The SPF record
A Sender Policy Framework (SPF) record is a simple email-validation system designed to detect email spoofing by providing a mechanism to allow receiving mail exchangers to check that incoming mail from a domain comes from a host authorized by that domain's administrators.
I highly recommend reading the Wikipedia article about the Sender Policy Framework if you don't know what it is or how it works.
Then go to SPF Record Syntax in order to understand the different options and attributes.
You can use a SPF wizard to construct your SPF record.
Once you're done setting up DNS you can verify your settings with an online tool like: DNSsy or MX ToolBox.
Make sure you understand the different attributes before you use it.
Let's add our SPF record to our example.
HOST TYPE POINTS TO TTL example.com A 1.2.3.4 3600 mail.example.com A 1.2.3.4 3600 example.com MX mail.example.com 3600 4.3.2.1.in-addr.arpa PTR mail.example.com 3600 example.com TXT v=spf1 a -all 3600
The DKIM record
As you probably remember we created a DKIM signature in part 2 of the tutorial. Use cat
to output the public key and insert the public key string into a TXT field in a DNS record.
# cat /etc/mail/dkim/public.key MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDIKOKNy/ghYjFz8FfxOxdzXxUN +x2+RONxX6icGZnF6m1Ji4YJMP5QuujoZEWDHhyTOJ5YqCCoBm3c73kns84gXcdw 5oXcounxtG3eROewl5ncpkgbn+eR8uTe+tSV8GU7J+koUXaXrlPpF9Qna0qgeTxv w56WH3oQZm1jAV0zYQIDAQAB
I have shortened the key in the example below:
HOST TYPE POINTS TO TTL example.com A 1.2.3.4 3600 mail.example.com A 1.2.3.4 3600 example.com MX mail.example.com 3600 4.3.2.1.in-addr.arpa PTR mail.example.com 3600 example.com TXT v=spf1 a -all 3600 selector1._domainkey.mail.example.com TXT v=DKIM1; p=MIG...; s=email; t=s 3600
The key goes into the p=
part of the options.
Remember we used the name "selector1" for our selector. You can call it anything, but remember it must match the "selector" field in /etc/dkimproxy/dkimproxy_out.conf
:
# specify the selector (i.e. the name of the key record put in DNS) selector selector1
If you would rather like it to be myselctor
, you could use that:
selector myselector
And then in the DNS record:
myselctor._domainkey.mail.example.com TXT v=DKIM1; p=MIG...; s=email; t=s 3600
You can verify your DKIM record using the tool dkimcore.
If you get the error, "This is not a good DKIM key record. You should fix the errors shown in red", and it says, "The p= field must be base64 encoded", then it is because you have managed to get white spaces into the public.key
when you copy/pasted it. Remove the white spaces.
The DMARC record
DMARC uses the two existing mechanisms, Sender Policy Framework (SPF) and DomainKeys Identified Mail (DKIM). A DMARC policy can tell a receiving mail server whether or not to accept an email from a particular sender. Not all receiving SMTP servers will perform a DMARC check, but all the major ISPs do and its implementation is growing fast. You can use DMARC to protect your domains against abuse in phishing or spoofing attacks.
You can use a DMARC Wizard to setup your DMARC DNS record.
HOST TYPE POINTS TO TTL example.com A 1.2.3.4 3600 mail.example.com A 1.2.3.4 3600 example.com MX mail.example.com 3600 4.3.2.1.in-addr.arpa PTR mail.example.com 3600 example.com TXT v=spf1 a -all 3600 selector1._domainkey.mail.example.com TXT v=DKIM1; p=MIG...; s=email; t=s 3600 _dmarc.mail.example.com TXT v=DMARC1; p=reject; sp=none; rua=mailto:postmaster@example.com!20m; ruf=mailto:postmaster@example.com!20m; rf=afrf; pct=100; ri=86400 3600
You can use dmarcian to inspect your DMARC record, and your SPF and DKIM records too.
Final notes
If you need to manually add the "Let's Encrypt" validation string to your DNS setup, maybe because the "acme.sh" client haven't got support for your DNS provider, or because you're using another client, then it looks like this:
_acme-challenge.mail.example.com TXT F24BbLWJyjTkFpg-LqSLiUWksaUwPbZB-LdaqbOxCcc 3600
Regarding blacklisting of mail servers, eventually, no matter what you do, you will most likely get blocked now and then even if you do everything right so don't worry to much about it.
If you're an SMTP server administrator reading this: Please stop filtering email on the mail server. Instead educate people in proper email address usage and email client filtering.