How to Setup Your Own Mail Server that Will Deliver

There are many reasons why you might want to have your own SMTP server. But there are also many reasons why lots of businesses outsource email sending to third party services. One of the big problems with having your own SMTP server is that it is quite hard to set the whole thing up to get a solid delivery rate. What does it mean? It means that if you just naively install an SMTP server and try to send emails through it, many of your emails will not be delivered. Moreover, you will not even know that your emails did not reach their recipients. If you have decided that you want your own SMTP server, this article will help you reach a solid delivery rate – i.e. your emails will be delivered to existing mail boxes and will not get deleted as spam. If something is not configured perfectly, your emails can be lost completely without a notice, moved to Junk folders, or not accepted for a delivery. So, if you are asking following questions: How to deliver an email? How to setup MX server? How to increase the delivery rate? Just keep reading.

Note that the methods described in this article will work for you only if you are a legitimate business and do not intend to send spam. If you do send spam, it is a good thing that your emails are not delivered, and even if you set everything properly, many of your mails will get deleted.

This article only discusses sending emails. Receiving emails with your own mail server is another wide topic. We will use the term mail server universally for all roles and names such as mail exchanger, MX host, MTA (mail transfer agent), or mail relay.

Choose the Right Software – DKIM Support is Required

You would think that every professional mail server software will simply support all features that are needed to deliver emails today. While this is true for most of the mail server software out there, this is not the case of Microsoft IIS SMTP Server. This SMTP server by itself does not include a crucial feature called DKIM (we will discuss it in a greater detail later in this article) and you can search the Internet to find many third party products that will add this feature to your IIS SMTP Server, but these are not cheap. If you are on Windows OS and unless you want to pay for having DKIM feature in your server, you want to avoid IIS SMTP Server. You can try hMailServer for example. It is free, open source, mail server and it works well, DKIM included.

Recommendation: Whatever mail server software you choose, make sure it does support DKIM.

Connection to the Internet – You Need Dedicated IP Address and PTR Record

In order to fight spam, people developed number of ways and heuristics to distinguish between trustworthy mail servers and servers used for sending spam. To have a long term excellent delivery rate and thus being able to deliver emails today, means to comply with most of these techniques. One of the feature that good mail servers do have is that they are sending emails from IP addresses with a valid reverse DNS record (PTR record).

If your mail server wants to send an email, it finds a target mail server, which is responsible to deliver messages to the given recipient’s address, and attempts to send the email through it. If the target mail server sees that the request comes from IP address without a valid PTR record, it can refuse to accept any messages from you. Many mail servers also require that the domain name in PTR record corresponds with the domain name part of the source email address of the message to be sent. For example, if you are about to send an email from, you might need to have your PTR record set to

Moreover, some email systems go even further than that. They do not accept any email if the PTR record does not contain or start with mail, smtp, or mx. Although this limitation is not very common, you can only increase your chance to deliver your emails if your PTR record complies with it. This is sometimes called reverse hostname naming convention or rDNS naming convention. In our example with an email from, you would need to set your PTR record to to increase your chance of delivery. In case of two mail servers, you can go with and and it will work just fine.

In order to be able to set a PTR record for your IP address, it is usually required that you have a dedicated IP address for your server provided by your hosting or ISP. It is highly recommended that a single IP address has at most one PTR record and this is why a shared IP address is not a good idea.

Recommendation: Make sure your server’s IP address has a valid PTR record, and that its domain name corresponds with the source email address from which you send emails. If you want to further increase your delivery rate, you may want to set your PTR record’s FQDN to start with mail, smtp, or mx.

Do Have Sender Policy Framework (SPF) Configured

Another action that the target mail server can do to verify your trustworthiness is to check your SPF record. SPF record is a TXT record in DNS that defines which hosts are allowed to send emails with source address set to a particular domain.

A SPF record is a TXT DNS record that starts with v=spf1. Then there is a list of parameters separated by spaces. The full list of parameters is described in SPF Record Syntax. There are also applications, such as SPF Wizard that will help you create your SPF record correctly.

Whatever way you construct your SPF, make sure that it is restrictive. This means that it defines a limited number of servers that are allowed to send emails on behalf of your domain, and forbids all other servers to do so. This is done by having -all as a part of your SPF record (usually at its end). What happens if you do not restrict your SPF record with -all? A minority of mail servers mail not accept your emails at all, but more likely scenario is that while counting a total spam score of your email, it will simply score worse. Another reason for having this restriction is that if someone attempts to send email pretending to be from you, it will not be delivered. If the restriction is not implemented, the attacker is more likely to succeed and have their fake mail delivered.


Let’s assume again that your domain name is, and that you want to send email from address Let’s further assume that IP address of is Here are some examples of good SPF records:

v=spf1 a -all

This record allows your emails to be delivered by hosts which IP address is contained in A DNS records of Since we assume that its IP address is only, your mail server will have to run from this IP address.

v=spf1 a ip4: -all

This record allows your mail server to run from, or from The .123 address is allowed by the a mechanism in the SPF record, while the .124 address is explicitly allowed by the ip4 mechanism.

v=spf1 a ip4: -all

In this example, we have extended the list of allowed servers even further. In this case, we allow Hotmail email service to send emails on our behalf too. The include mechanism requires the included domain to have its own valid SPF record. Hotmail complies with this requirement and thus email servers that can deliver emails for domain will also be allowed to deliver emails from

Recommendation: Configure your SPF record properly and restrictively.

DKIM and DomainKeys

You have probably heard about DKIM and DomainKeys. Good news is that you do not have to worry about DomainKeys. It has been replaced with DKIM entirely and not having DomainKeys is not a disadvantage today. Not having DKIM, however, is a very serious problem which will kill your delivery rate. So what is DKIM?

DKIM stands for DomainKeys Identified Mail, a protocol that introduces digital signatures to email delivery systems. It is just another mechanism that the target mail server can use to verify that the incoming message is being sent by someone who is authorized to do so. If the sender passes the DKIM check, it is almost certain that the source email address is not forged. The mechanism works as follows.

  • First, you need to generate a public and a private key that will be used to sign and verify messages from your mail server.
  • Then you configure your mail server software to sign all messages it sends out with the generated key.
  • You also need to create DKIM DNS record, in which you publish your public key.
  • When your server is sending an email to the target mail server, the target mail server sees that your email is signed using DKIM, it performs DNS lookup to obtain your public key and uses it to verify the signature in the email message. If it matches, the email is more likely to be delivered.

So, how do you generate the keys? There is very simple DKIM Wizard on Just fill in your domain name and something that is called DomainKey Selector. The selector is just any simple string you want – e.g. dkim. The wizard generates you public and private keys. Other way to generate the keys is using OpenSSL’s genrsa command.

If you have your keys, you need to configure your mail server to use the private key to sign the messages. How this is done depends entirely on which mail server software you use. So check up its manual or try to ask Google. If your mail server software supports DKIM, it should be easy to find. It should be noted here that there are two so called canonicalization algorithms called simple and relaxed. You are likely to see them as options to choose from in the configuration of your mail server software. Possibly, you might be asked to decided which algorithm to use for email headers and which for email body. These algorithms refer to a way how your email messages are signed. You do want to use the relaxed algorithm for both headers and body. The simple algorithm allows almost no modifications to the email message on its way from the sender to the recipient. This sounds great except that in the email delivering world, the message is quite likely to be modified. Various headers can be added through various anti-spam and anti-virus mechanisms or proxies, minor reformatting of the body is also possible. This means that if you choose the simple algorithm, your email is less likely to be delivered.

Now you need to create the DKIM DNS record. It is a TXT record that is usually identified with v=DKIM1. Assuming your domain is and your DomainKey Selector is dkim then the name of the TXT record must be Its value can be something as simple as the following:


The only required parameter here is p with your public key. What you need to make sure, however, is that your record’s value does not contain t=y as this would make your record say that you are only testing DKIM and that it does not need to be respected.

If you need to know more about DKIM, continue to

Recommendation: Configure your mail server to sign outgoing emails using DKIM. Use relaxed canonicalization algorithm.

Create postmaster Account or Alias

RFC 5321 prescribes that every domain must have postmaster mailbox and accept emails to it. There exist mail systems that do check this before accepting an email from you. So, make sure that you create a postmaster account or at least an alias on your mail server.

Use of no-reply Address

If you use a no-reply address, from which you send emails that recipients should not reply to, your messages might have trouble to reach some mailboxes. This is because some mail servers require the source email address to exist, otherwise they refuse to deliver the message. The email verification is done using an SMTP protocol to your incoming email servers (defined in MX DNS records).

There is a discussion on whether or not it is good for your business to use no-reply address. But if you choose to use this mechanism, then you want to create a mailbox for that no-reply email address, so that it appears to be a valid address if someone checks it.

Recommendation: If you use no-reply address, create a mailbox or an alias for it.

Do Not Be Open Relay or Open Proxy

Make sure your mail server software is not configured to be an open relay or an open proxy. This would mean that you let anonymous users to send emails from your mail server. Always require users to be authenticated before they can send email through your SMTP server. The Internet is scanned by robots all the time and you can be sure that if you open your server to anonymous senders, your email server will be misused soon after it is installed. You will end up on blacklists and will be forced to restrict the access to your server.

Test Your Settings

If you have everything ready, it is time for testing your configuration. Start with checking your DKIM record, simply using DKIM Record Checker. Just fill in your selector value and your domain and submit the form.

If everything is OK, you can try to send an email to a very handy verification tool by In order to perform the check, you need to send an email either to or to The verification result is going to be sent to you to the address specified in MAIL FROM SMTP command, if you use If you use the second variant – – the result will be sent to the address specified in From header of the email message.

The most important part of the result email that you receive will look like this:

Summary of Results
SPF check:          pass
DomainKeys check:   neutral
DKIM check:         pass
Sender-ID check:    pass
SpamAssassin check: ham

If this is the case then you just passed the tests and your configuration is correct. Do not worry about neutral DomainKeys check result, we have mentioned already that DomainKeys is not used anymore, DKIM is neutral result means that you do not implement that mechanism. If you fail a test, there is a detailed information included in in the result email.

However, even if you pass verifier test, it does not mean that all mail systems will consider your DKIM/SPF records as valid. This may sound weird but Microsoft’s services such as or are actually much more sensitive to the actual syntax of DNS record values. This is why it is a good idea to make extra tests – tests with real world mail servers. You should be able to pass test with Gmail easily. Simply create an account on Gmail and send a mail to it from your mail server. Then wait until the email appears in your Gmail account and view its source (how to do this is described in Google’s help center).

In the email headers, look for the Authentication-Results header, which should look like this:

       spf=pass ( domain of designates as permitted sender);

If you see there spf=pass and dkim=pass you passed the test. Other values means that something is wrong.

Now let’s do this once again, but with Hotmail account. There are many recipients that use Microsoft email services, so it is very important to make and pass this test. Send an email to your Hotmail account and view its source. Look for the Authentication-Results header. If you do not see pass values, your configuration is almost OK, just not in the format accepted by Microsoft. In that case, review values in your SPF and DKIM DNS records and make sure that you use only one space as a delimiter after semicolon, no tabs, no new lines, just one space. Also make sure there are no quotes in your record value.

Recommendation: Use verifier to check your SPF and DKIM settings, but also make a test with a real Hotmail account.

Avoid Blacklists

There exist many blacklists, commonly called DNSBL or RBL, that attempt to list servers known to send spam. Blacklists are used for automatic filtration by some mail servers, so once your IP address is on a blacklist, it may have very negative consequences to your ability to deliver your emails.

Even if you are not a spammer, it is possible that IP of your mail server appears on some blacklists. How is this possible? One of the common situations is that a network of legitimate business is infected with malware that sends spam from within their computers. One or two days of infection can easily lead to be blacklisted. Another scenario is that the static IP address, which your hosting has assigned to you, has previously been assigned to a client who sent spam. Your IP address thus could be blacklisted even before you install an operating system to your server.

Fortunately, it is easy today to know whether your IP address is blacklisted or not. You can use free mail server blacklist checker to perform a check against over a hundred of blacklists at once. If it is crucial for your business to be able to deliver an email, you might be interested in automated blacklist monitoring service that alerts you if an IP address of your mail server appears on a blacklist.

If you are not sure whether your message that you want to send out can cause you a problem or not, you might be interested in reading Controlling the Assault of Non-Solicited Pornography and Marketing Act – aka CAN-SPAM. This is United States law that regulates the sending of commercial email. Even if you are not a US business, you want to comply with this law because you can be blacklisted otherwise.

Recommendation: Check whether your IP address is blacklisted after your hosting assigns it to you, and then check it from time to time or have it monitored. Comply with CAN-SPAM.

Commercial Certification

Optionally, you can get yourself a certification from a commercial authority that will maximize your delivery rate. You will still need to implement the steps mentioned above, so you can not just buy it. If you care a lot about your delivery rate to Microsoft and Yahoo email services, you might consider buying Return Path Certification. It’s not cheap, so really consider if those emails you need to deliver to your customers using Microsoft and Yahoo services are worth a couple of thousands dollars per year. If so, go for it.

Note that without a certification, you will still be able to deliver emails to both Microsoft and Yahoo. However, some of your emails may be lost from time to time, or reach the recipient’s junk folder instead of their inbox; especially when you start sending emails from a new IP address that does not have a good long reputation yet.

Your Emails Will Be Delivered Now

That’s it! If you configured everything as recommended, you should now be able to deliver emails to most of the mail systems in the world.

Here is a quick summary of what is necessary to achieve an excellent delivery rate:

  1. Choose mail server software that supports DKIM.
  2. Run the mail server on a machine with dedicated IP address and set a valid PTR record for it that starts with “mail”, “smtp” or “mx”.
  3. Create a restrictive SPF DNS record.
  4. Generate DKIM keys, configure your mail server to use the private key to sign outgoing emails and publish the public key in DKIM DNS record.
  5. Do have postmaster account or alias.
  6. If you use no-reply address, create a mailbox or alias for it.
  7. Make sure your server is not configured to be an open relay or a proxy.
  8. Test your DKIM/SPF settings, do not forget Hotmail test.
  9. Regularly check your mail server’s IP address against blacklists. Ask for removal if you are blacklisted. Comply with CAN-SPAM.
  10. Optionally, consider buying Return Path Certification if you need high delivery rate to Microsoft and Yahoo emails.

Web development in C






fast C HTTP server library comparison & wishlist


Trying to choose an embeddable HTTP server library for a project, and
also considering writing my own special-purpose code, I came up with
the following comparison of libonion vs. other C libraries that include
high-performance HTTP support and are currently maintained.


libevhtp+libevent – 3-clause BSD
libmicrohttpd – LGPL 2.1
libonion – Apache 2 (except for some examples) or GPLv2+
mongoose – GPLv2 (and commercial)

Build environment:

libevhtp+libevent – cmake+autotools
libmicrohttpd – autotools
libonion – cmake
mongoose – none (one large file, like SQLite)

Code size (“text” as reported by the size(1) command on the library or
on a tiny sample program if statically linked, on Scientific Linux 6.6
on x86_64):

libevhtp+libevent – ~500 KB, or ~200 KB without unicode.c.o and reg*.c.o
libmicrohttpd – ~100 KB default, ~55 KB with most ./configure –disable-*
libonion – ~100 KB with most ONION_USE_* set to false
mongoose – ~100 KB including JSON-RPC

For the smaller builds of libmicrohttpd and libonion, I kept threads
support enabled, but disabled pretty much everything else that could be
disabled without patching the code.  It looks like libmicrohttpd wins
this test.  Maybe there’s more code in libonion to disable (make into
compile-time options) – I haven’t checked yet.

Built-in JSON support:

libevhtp+libevent – none
libmicrohttpd – none
libonion – JSON builtin, JSON-RPC in Apache 2 licensed example
mongoose – JSON-RPC builtin (simple JSON parser not exported?)

All of this is for current versions on GitHub or in recent release
tarballs as of a few days ago.

Maybe someone else will find this useful.  I’d appreciate corrections.
It is very likely that I overlooked something.

On a related note, I found the list of alternate implementations on the
libmicrohttpd homepage very helpful.  That’s classy.  Thanks.

My wishlist:

A processes (pre-fork) + [e]poll mode, like nginx has.  Processes have
pros and cons vs. threads: more reliable, faster malloc/free (no lock
contention risk), but OTOH slower context switches (if running process
count exceeds number of logical CPUs).  I would likely prefer this mode,
but all four libraries appear to be missing it.

Ability to accept not only HTTP, but also raw TCP connections, and
handle them in application code along with the library-handled HTTP.
Such as for implementing JSON-RPC directly over TCP, while also having
it over TCP+HTTP, and without having to manage an own/separate
threads/processes pool.  Do any of the four have this?  I found no such
examples with any of them.

Easily and cleanly embeddable into an application’s source tree, while
also allowing easy updates to new upstream versions.  mongoose almost
achieves this, but at the expense of sacrificing meaningful separation
into multiple translation units within the library itself.  I think we
don’t have to pay this price.  We could have multiple files (10 or so?),
in a subdirectory, which are also easy to list in a project’s Makefile.
Maybe I’d do that for libonion, freeing it from cmake, but then updating
to new upstream versions would be harder.  Do I really have to bite the
cmake or/and autotools bullet for something as simple as accepting HTTP?

I’d prefer a more permissive license like 2-clause BSD or MIT.  But I
guess I’ll have to settle on Apache 2 or such.  mongoose’ use of GPLv2
is understandable – need to make money – but is otherwise a disadvantage
(even for a commercial project that could pay, and even when publishing
any source code changes is not a problem and would be planned anyway; we
just don’t want to put our time into something that we would not always
be able to reuse in other projects).

Optional JSON from the same upstream is a plus, ideally exported both as
a generic JSON parser and as JSON-RPC support.  Looks like only libonion
sort of delivers both (but the code might not be production quality).

Ability to exclude more of the functionality – for example, to include
only the POST method (and not compile in code for the rest).  I am
concerned not so much about code size per se, as I am about attack
surface, and about ease of code reviews (not having to determine if some
compiled-in code is actually dead code in a given case, but to know
reliably that it’s not compiled in).

On a related note, David’s use of Coverity for libonion is commendable,
but it looks abandoned since 2014, and many “defects” (even if false
positives) remained unfixed back then.

Mark’s use of Coverity for libevhtp is also commendable… and looks
abandoned since May 10, 2015.  It shows “48,919 Lines of Code Analyzed”,
only “4 Total defects” and “0 Outstanding” – I guess it means that
everything detected by Coverity before (which must have been many more
“defects”) had been eliminated prior to that run.  That’s impressive.
But we don’t know how many new “defects” may have appeared in the 9
months that passed.  Also, I haven’t looked into whether libevent has
been subjected to similar static analysis or not (although being
initially written by Niels Provos speaks in its favor, given Niels’
other work), and accepting TCP connections isn’t as much risk as parsing

I don’t give a lot of weight to the Coverity results for my
decision-making, but it shows whether the maintainers care, and there
are few other somewhat-meaningful metrics I could use before having
spent time to analyze and try to use the code myself.

Why am I posting this to the onion mailing list specifically?  I find it
likely that libonion wins for me, although not by a large margin (and
there’s a lot that I dislike about it).  This is not a final decision
yet.  I might as well end up reverting to writing special-purpose code
from scratch.



setup reverse tunnel with stunnel

Unlike ssh,  stunnel dosen’t support the reverse tunnel by it’s self.

With the help of tgcd ( TCP/IP Gender Changer Daemon ), we are able to setup a reverse tunnel by chain the tgcd and stunnel:

For example:

We try to access the corp server from home,  but due to the NAT firewall of the corp, only out going 80/443 port are opened:

client  ==> tgcd LL node (home server)  ==> tgcd CC node (corp agent) ==> corp server:

Home Server:

Launching tgcd daemon in LL mode:

   tgcd -L -q 2222 -p 22222

Listen on port 2222 for client access

Listen on port 22222 for tgcd CC access


Launching stunnel in server mode:

       /usr/local/bin/stunnel /etc/stunnel/stunnel_server.conf

Listen on port 443 for incoming ssl connection

Forward link with sni=tgcd to port 2222

cat /etc/stunnel/stunnel_server.conf

accept =
connect =

sni = tls:tgcd
connect =


Corp Agent Server:

Launching tgcd daemon in CC mode:

tgcd -C -s -c

Connect to tgcd LL node at:

Connect to sshd server at:

Launching stunnel in client mode:

/usr/local/bin/stunnel /etc/stunnel/stunnel_client.conf

Listen on port from tgcd CC, and

Access Home server via port 443 behind NAT and http proxy

cat /etc/stunnel/stunnel_client.conf


accept =
protocolHost = home.serverip:443

connect = http_proxy_ip:http_proxy_port
protocol = connect
sni = tgcd



With such configuration, we can login into the corp server by means of:

ssh -p 22222   home.server.ip

ESXi6 kernel log (dmesg)

Understanding SCSI device/target NMP errors/conditions in ESX/ESXi 4.x and ESXi 5.x/6.0 (1030381)

2016-10-27T12:50:47.496Z cpu7:32798)ScsiDeviceIO: 2651: Cmd(0x439d80358400) 0x1a, CmdSN 0x1d1f2 from world 0 to dev “mpx.vmhba33:C0:T0:L0″ failed H:0x0 D:0x2 P:0x0 Valid sense data: 0x5 0x24 0x0.

Host Status = 0x0 = OK
Device Status = 0x2 = Check Condition
Plugin Status = 0x0 = OK

Sense Key = 0x5 = ILLEGAL REQUEST
Additional Sense Code/ASC Qualifier = 0x24/0x0 =INVALID FIELD IN CDB
For a complete list of possible Sense Keys, see SCSI Sense Keys
For a complete list of Additional Sense Code/ASC Qualifier pairings, see ASC-NUM.TXT

How ESXi identify disk

Identifying disks when working with VMware ESXi/ESX (1014953)


These are the definitions for some of identifiers and their conventions:
  • naa.<NAA>:<Partition> or eui.<EUI>:<Partition>

    NAA stands for Network Addressing Authority identifier. EUI stands for Extended Unique Identifier. The number is guaranteed to be unique to that LUN. The NAA or EUI identifier is the preferred method of identifying LUNs and the number is generated by the storage device. Since the NAA or EUI is unique to the LUN, if the LUN is presented the same way across all ESXi hosts, the NAA or EUI identifier remains the same. For more information on these standards, see the SPC-3 documentation from the InterNational Committee for Information Technology Standards (T10).

    The <Partition> represents the partition number on the LUN or Disk. If the <Partition> is specified as 0, it identifies the entire disk instead of only one partition. This identifier is generally used for operations with utilities such as vmkfstools.


mpx.vmhba<Adapter>:C<Channel>:T<Target>:L<LUN> or mpx.vmhba<Adapter>:C<Channel>:T<Target>:L<LUN>:<Partition>

Some devices do not provide the NAA number described above. In these circumstances, an MPX Identifier is generated by ESXi to represent the LUN or disk. The identifier takes the form similar to that of the canonical name of previous versions of ESXi with the mpx. prefix. This identifier can be used in the exact same way as the NAA Identifier described above.