Note: This is the first in our series of tutorials on how to set up authentication mechanisms for your mail server, including rDNS, SPF, DKIM, and DMARC.

One of the first things that a responsible ESP must deal with, before starting to mail on behalf of their customers, is Reverse DNS (rDNS from now on). This is true for businesses that send out their own email, as well. This is our tutorial on how to set up rDNS.

There has been a lot of discussion about the value — or lack of — checking rDNS as part of the checks that mailbox providers perform routinely. Being pragmatic, your role is actually about getting your email to the inbox, so let’s focus on passing that test.

[NOTE: ISIPP SuretyMail can set up your rDNS for you if you would rather not do it yourself. For more information about this service, contact us here.]

What is rDNS?

Put in plain English, rDNS is a mechanism that allows email servers that are receiving email from you to determine what domain(s) you have associated with the IP address from which you are sending email. For example, the ISIPP email server is connected to the Internet through the IP address That server is called ‘’. If all you have is our IP address (as is this case when a sending email server connects to a receiving email server), rDNS allows you to discover that the server sending you the email from is called

For those who want a deeper, more technical explanation, rDNS is a mechanism that allows finding the name (or names, nothing prevents multiple names!) that has been associated with a given IP address. It uses a special type of DNS Resource Record called a “Domain Name Pointer”, or “PTR” which is defined in RFC-1035 for this purpose. You may think of rDNS as a caller-id of sorts, helping the receiver know who is trying to send email.

Before we go into how to set up your rDNS, let’s have a brief discussion of how email receivers use it, at the other end, to identify who is sending them email.

NOTE: The below discussion is highly technical, and you can skip it if you like, and go straight to the section
How to Configure rDNS‘.

The process of rDNS delegation (we’ll define this further down) for IP version 4 was briefly defined in RFC-1033. The general idea is to have a very special domain address, ``, that everybody knows to use to perform rDNS lookup.

Then, you simply flip around the IP address at the dots. So, if you want to find out the rDNS for the IP address ``, you would simply turn it around on the dots (this is actually referred to as an “octet boundary”) and tack the `` at the end before issuing your lookup for a matching PTR record, like so:

system_prompt$ dig ptr


You can also use (much more verbose) `nslookup` for this purpose, as follows:

system_prompt$ nslookup
> set query=ptr

Non-authoritative answer: name =

Of course, that is a lot of typing, which is why there are options that cut right to the chase:

system_prompt$ dig -x


For IP version 6 (“IPv6”), the idea is similar although some lessons were learned in the process. The first change is that the special domain used to lookup rDNS in IPv6 is ``. Instead of flipping the IP address at the dots, we’ll do that at each hexadecimal digit of the uncompressed IPv6 address.

So, in order to look up the name corresponding to the IPv6 address `2607:f8b0:4002:c01::6a`, one would have to type in this command:

system_prompt$ dig ptr \

Now you can thank the developers of `dig` for adding the `-x` shortcut, thus shortening it to

system_prompt$ dig -x 2607:f8b0:4002:c01::6a

A note about Time to Live (TTL)

DNS is a worldwide, distributed and highly available database. Its scalability — its ability to operate at the scale it does — depends on the extensive use of caching. That is, client computers query “recursive caching name servers” that in turn query other servers until they are able to provide a suitable response. At that point, they store a copy of such response, just in case the same query comes later.

Just imagine how much bandwidth and processing resources are saved every day when these servers remember the IP addresses they are supposed to return when someone’s computer asks for ``.

DNS administrators can add Time To Live (TTL) information to the DNS data, which informs those caching name servers how long they are allowed to use that response. It’s very common to use TTL values between a few hours and a few days. Put another way, this tells the other servers that they can rely on the data they just got for up to the amount of time defined in the TTL.

The pro of using a longer TTL is that fewer DNS queries will hit the provider’s name servers, because answers will be remembered elsewhere for longer periods.

The con is that when a change is made, it takes longer for the change to make its way through the Internet. For example, a TTL of 258835 seconds, or almost 3 days, would mean that if you were to change that PTR record, you would have to wait for as many as 3 days before the change would be visible everywhere on the Internet.

What assurances are provided by rDNS?

This is a very important question. Having a well-configured rDNS only tells your email receiving counterpart that you’re paying some attention to detail and that you have certain control over the IP address range you’re using.

For email deliverability purposes, you’ll want to make sure that your rDNS — or reverse resolution — matches the forward resolution. That is, if your mail server identifies itself as `` in its
`HELO` response, then you want the following assertions to hold:

1. Resolving the rDNS of the IP address originating at your mail server, at least one of the resulting names is ``.

2. Resolving the name `` must return, among its IP addresses, the IP address used to originate the connection.

3. The fewer IP addresses you have associated with a domain name (and vice-versa), the better.

The more rigorous you are with this, the fewer issues you will experience over time. For instance, working with multiple names and IP addresses will generally work very well, but there are exceptions where the receiving system has not correctly implemented the Forward rDNS verification.

How to Configure rDNS

The right way to set up your rDNS varies depending on how many IP addresses you have and how you have received them. We’ll go into the detail for each one of those variations below. It all starts with editing your DNS zone file.

However, before starting with this topic it is very important to check an often overlooked detail: What does your mail server thinks its name is?

You want to verify this in two ways:

1. Connect to any of its ports (usually 25 or 587) and look at the greeting:

system_prompt$ swaks -s -t bl********@is***.com
=== Trying…
=== Connected to
<- 220 ESMTP Postfix NO UBE -> EHLO localhost

<- 221 Bye In this case we have used `swaks` (the "SWiss Army Knife SMTP") to connect to our mail server and check its greeting. In this example the greeting is minimal and contains only the mandatory `220`, the hostname (``) and the token `ESMTP` that tells the SMTP client that this server is capable of using extension in the ESMTP protocol. So in this case, we know that the server thinks its name is ``. This is the piece of information that we wanted. 2. Now, send yourself an email and look at the mail headers. You want to look for a header similar to this: Received: from ( []) ... In this case, the `Received` header that was added by the recipient's mail server reported the name that the sending server used in its `HELO` or `EHLO` command (as well as the IP address and the reverse). Your goal at this time is to tweak the configuration of your MTA to ensure both names are the same and, more importantly, that the name of your mail server is the one you want. For most cases, you want your mail server name to be obvious and under the domain you associate with your mailing operations. Once you have completed this step, then you will need to work through one or more of the following sections to complete the setup of your rDNS information. DNS Delegation

In DNS parlance, “delegation” refers to the passing of authority between two name servers. For instance, when a mail receiver wants to check the rDNS for your IP address, it will first ask a computer above you in the network hierarchy — for example the mail receiver will ask your ISP.

Your ISP may respond among the lines of “I don’t know that answer myself, but you can ask that server right there”. This is what’s called ‘delegation’, and it happens hundreds of billions of times each and every day in the Internet.

For delegation to succeed, the delegating server and the delegated server need to be configured properly.

rDNS with No Delegation

This is very common when you’re renting mail servers from a hosting provider with a limited number of IP addresses. Under these kind of scenarios, it is common that no delegation is made. Instead, you
simply ask the provider to set up whatever name you need, usually by opening a ticket or using a self-provisioning portal.

It’s a good idea to check the TTL of the existing PTR record before requesting the change, to have a good idea of how long the change will take before it’s visible across the Internet.

It’s also a good idea to request a TLL of 3600 (TTL is measured in seconds, so 3600 is 1 hour) to 14400 (4 hours) for your new rDNS. This might not be granted by the provider, but in practice that is a functional time window to effect changes.

And it’s also always a good idea to configure rDNS even for IP addresses you’re not using. For those cases you’ll want to choose names that clearly communicate that the IP address is not in use. The more information you can convey to interested parties, such as ISPs researching an abuse complaint, the better.

Traditional Delegation

Under traditional delegation, you will be expected to provide DNS resolution for one or more zones such as `` that are delegated to you directly from the entity that manages IP space in your part of the world.

These DNS zones are pretty much standard zones, except that they normally contain only `SOA` (which stands for “Start of Authority”), `NS` (Name Server record) and `PTR` (as mentioned above, Pointer) resource records. This is an example of a reverse zone for `10.0.0/24`, a non-routable IP address range we’ll use to illustrate some examples.

@ IN SOA ns1.mydomain.example. hostmaster.mydomain.example. (
1 ; Serial
14400 ; Refresh
3600 ; Retry
2419200 ; Expire
1800 ) ; Negative Cache TTL
@ 3600 IN NS ns1.mydomain.example.
@ 3600 IN NS ns2.mydomain.example.
1 3600 IN PTR mail-01.mydomain.example.
2 3600 IN PTR ns1.mydomain.example.
3 3600 IN PTR ns2.mydomain.example.

Here you can see the serial (“1”), which is a value you should increment every time you change the zone, so that other name servers know that the zone has changed. The serial number indicates what
version of the zone file it is.

In this case, we were delegated a /24 (256 contiguous IP addresses) going from `` to ``. As you might know, the very first address from the range, where the _host bits_ are all zero is normally not used, for reasons of backward compatibility. Let’s create an rDNS entry pointing to `network.mydomain.example` just to document that fact.

The IP address that has all host bits set to 1 is called a ‘Broadcast Address’ and it cannot be used for host allocations either. Let’s create the corresponding entry `broadcast.mydomain.example` and see how our resulting zone file turns out:

@ IN SOA ns1.mydomain.example. hostmaster.mydomain.example. (
2 ; Serial
14400 ; Refresh
3600 ; Retry
2419200 ; Expire
1800 ) ; Negative Cache TTL
@ 3600 IN NS ns1.mydomain.example.
@ 3600 IN NS ns2.mydomain.example.
0 3600 IN PTR network.mydomain.example.
1 3600 IN PTR mail-01.mydomain.example.
2 3600 IN PTR ns1.mydomain.example.
3 3600 IN PTR ns2.mydomain.example.
255 3600 IN PTR broadcast.mydomain.example.

Take a careful look at that. First, the zone’s serial number was updated to make sure that all name servers that are supposed to provide service for this zone will pick up the changes right away. This is often cause of much head scratching, so make a habit of always updating the serial number of the zone.

There’s no need to keep the file in order (i.e., the entry for 255 could come before the entry for 0) however doing so will tend to make your life easier.

The entry for `0.0.0` completes a lookup for ``, which as we already learned is the query for the rDNS data for``. The case for `255.0.0` is similar.

system_prompt$ dig @localhost -x

;; ANSWER SECTION: 3600 IN PTR network.mydomain.example.

Now, let’s suppose we’re bringing online 10 new mail servers. Those will be assigned IP addresses starting at ``. For cases likethese, name servers such as BIND support the `$GENERATE` macro, which is a way to automatically produce large number of records that simply follow a rule.

So, instead of writing a bunch of entries as the ones below, a task that gets boring and error prone quite rapidly:

20 3600 IN PTR mail-02.mydomain.example.
21 3600 IN PTR mail-03.mydomain.example.

We can use a simple `$GENERATE` macro to produce all of the entries in a single line:

$GENERATE 20-29 $ 3600 IN PTR mail-${-18,2,d}.mydomain.example.

then, after updating the zone’s serial number and reloading, you’ll have all your new names: 3600 IN PTR mail-02.mydomain.example. 3600 IN PTR mail-03.mydomain.example. 3600 IN PTR mail-04.mydomain.example. 3600 IN PTR mail-05.mydomain.example. 3600 IN PTR mail-06.mydomain.example. 3600 IN PTR mail-07.mydomain.example. 3600 IN PTR mail-08.mydomain.example. 3600 IN PTR mail-09.mydomain.example. 3600 IN PTR mail-10.mydomain.example. 3600 IN PTR mail-11.mydomain.example.

Now it should be easier to add a specific name to the unused parts of our network. In this case, let’s use name `unused.mydomain.example` for those areas that we’re not actively using at the moment. We can do this by updating the serial and addingthis macro:

$GENERATE 30-254 $ 3600 IN PTR unused.mydomain.example.

Note however that each resource record will have an impact in the memory utilization of your DNS servers. For this reason, you likely do not want to attempt this on IPv6 delegation. Adding entries for the unused IP addresses in a `/64` block will likely exhaust all available memory in most name servers.

That said, your resulting zone will look like something along these lines:

@ IN SOA ns1.mydomain.example. hostmaster.mydomain.example. (
4 ; Serial
14400 ; Refresh
3600 ; Retry
2419200 ; Expire
1800 ) ; Negative Cache TTL

@ 3600 IN NS localhost.
0 3600 IN PTR network.mydomain.example.
1 3600 IN PTR mail-01.mydomain.example.
2 3600 IN PTR ns1.mydomain.example.
3 3600 IN PTR ns2.mydomain.example.
$GENERATE 20-29 $ 3600 IN PTR mail-${-18,2,d}.mydomain.example.
$GENERATE 30-254 $ 3600 IN PTR unused.mydomain.example.
255 3600 IN PTR broadcast.mydomain.example.

As you can see, managing your rDNS zone data is not that complicated. It’s just a matter of remembering these simple things:

  • When configuring a mail server, choose a suitable name and IP address.
  • When allocating a new IP address, add its rDNS at once.
  • Always remember to update the zone’s serial number.
  • Make sure your forward (i.e., name-to-IP-address) and reverse (i.e., IP-address-to-name) DNS resolution match.
  • Periodically go through your forward and reverse DNS zones and do some cleanup. Make sure that retired hosts are no longer in the DNS.
  • With a little practice these steps will take you no more than 10 minutes, and will help to minimize email deliverability issues, and save a lot of deliverabilty troubleshooting.

    Note that the discussion and examples dealt with IPv4 and the `` zone, but this is all applicable in exactly the same fashion to IPv6 and ``.

    Classless or RFC-2317 Delegation

    Many times your ISP will delegate IP addresses to your servers or network in chunks that are not large enough to warrant traditional delegation. Alternatively, some ISPs _always_ delegate the addresses they are assigning to you via RFC-2317 to ensure that they remain in the loop for DNS resolution.

    In this case, your ISP will delegate a zone such as `0/` to your name servers. This is simply the reversed CIDR notation for ``, which means the range of IP addresses from `` to ``. Your zone file could then look like this if we followed all the steps in the prior section:

    @ IN SOA ns1.mydomain.example. hostmaster.mydomain.example. (
    1 ; Serial
    14400 ; Refresh
    3600 ; Retry
    2419200 ; Expire
    1800 ) ; Negative Cache TTL

    @ 3600 IN NS localhost.
    0 3600 IN PTR network.mydomain.example.
    1 3600 IN PTR mail-01.mydomain.example.
    2 3600 IN PTR ns1.mydomain.example.
    3 3600 IN PTR ns2.mydomain.example.
    $GENERATE 20-29 $ 3600 IN PTR mail-${-18,2,d}.mydomain.example.
    $GENERATE 30-126 $ 3600 IN PTR unused.mydomain.example.
    127 3600 IN PTR broadcast.mydomain.example.

    In this case, you would configure your server as follows (where the zone file resides in `/etc/bind/db.10-0-0-0-25`):

    zone “0/” {
    type master;
    file “/etc/bind/db.10-0-0-0-25”;

    As you see, this use case is very similar to what we saw before.

    Note however that some ISPs don’t follow RFC-2317 precisely, so they often invent their own notation for the delegation. That is, instead of delegating `0/`, some may delegate variations such as `` or ``. This does not matter much as long as both the ISP’s name servers and your own name servers are in agreement.

    Testing the rDNS Resolution

    Testing is a very important part of maintaining your rDNS information. One of the unfortunate things about DNS is that because it is so robust, some errors require a lot of effort to find.

    The first check you can easily do is crafting an rDNS query against your own servers and insuring that all of them return what you expect. Here is an example using `dig`:

    system_prompt$ dig @localhost -x

    ; <<>> DiG 9.8.4-rpz2+rl005.12-P1 <<>> @localhost -x
    ; (1 server found)
    ;; global options: +cmd
    ;; Got answer:
    ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 54613 ;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 2 ... ;; ANSWER SECTION: 3600 IN PTR network.mydomain.example. ;; AUTHORITY SECTION: 3600 IN NS localhost. ... ;; Query time: 0 msec ;; SERVER: ;; WHEN: Tue Sep 3 02:38:17 2013 ;; MSG SIZE rcvd: 144 Look at `status` in the `->>HEADER<<-` line. A status code of `NOERROR` means that the server was able to fulfill my request with no problems. An `NXDOMAIN` would indicate that the server doesn't have the information we are querying. A code of `SERVERFAIL` means that the server failed while processing my query. In both cases, the name server logs are usually very helpful in determining what's wrong. For your name servers, the `flags` line should include `aa` which means that the answer is authoritative: the name server knows it is responsible for producing this information. If this flag is not present, this likely means that the queried server had to ask other servers for the information, which is not what we want. Then look at the contents of the answer section. Here, we should see a record matching precisely what was in the zone file. Any other value indicates a problem (such as a zone that failed to update because we forgot to update the serial number). Finally, look at the query time. A few milliseconds are ok. However, large values -- let's say, above 200 milliseconds -- might causeintermittent problems. Here's an example of a part of the response you'll get when querying for data that our name server cannot respond: ; <<>> DiG 9.8.4-rpz2+rl005.12-P1 <<>> @localhost -x 10.0.0.a
    ; (1 server found)
    ;; global options: +cmd
    ;; Got answer:
    ;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 797 Notice the `NXDOMAIN`. Make sure you test all of your name servers and obtain consistent results. Another good test is to ask for the `SOA` from all the servers in order to compare and make sure all of them have the same version of the zone. Giving one or two minutes after a zone update, you can issue commands such as these (substituting the names of your name servers of course) and check the results: dig +short soa @ns1.mydomain.example dig +short soa @ns2.mydomain.example With this information, you should be able to configure and maintain your rDNS, as well as troubleshoot the most common issues. NOTE: ISIPP SuretyMail can set up your rDNS for you if you would rather not do it yourself. For more information about this service, contact us here.

    Let us help YOU get to the inbox like we've helped these others!


    One response

    1. I missed the part where you said these were LINUX commands. Or is it that such a declaration was omitted?

      Well, it was educational nonetheless.

    Leave a Reply

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

    We are ISIPP SuretyMail, the original certified sender program and email deliverability service. Learn more here
    Generic selectors
    Exact matches only
    Search in title
    Search in content
    Post Type Selectors
    Search in posts
    Search in pages
    Filter by Categories
    Blocklists and Blacklists
    Content Issues
    Email Authentication
    Email List Building
    Feedback Loops
    Mailing List Hygiene
    Monitoring and Tracking
    Opt-in Practices
    Our News
    Privacy & Email Laws
    Sending Practices
    SMS Marketing
    Spam Complaints
    Technical Stuff
    The Industry
    Need Help Getting to the Inbox?
    If you need help getting out of the spam folder and into the inbox, we're here for you. Our deliverability services come with a personal touch, and we get results. That combination has created customer loyalty that's nearly unheard of. (testimonials)
    Read what we'll do for you here.

    Join our email community and get
    How to Stay Out of the Spam Folder 
    & How to Grow Your Email List free!

     Get to the Inbox by SuretyMail
    The Original Email Deliverability Company

    Free stuff!
    Skip to content