Multi-Domain Email Sending & Forwarding to Gmail for Free Here's how to send and receive encrypted emails from multiple domains to my Gmail account for free without worrying about spam or complex server setup.

on July 18, 2016
(7 minute read)

I’ve been running Postfix on my Ubuntu Server for a¬†couple years to forward all my website’s emails to my main Gmail account. It’s been working fine yet lately the spam has become unbearable to the point that Google started temporarily blocking email from some domains which would eventually cause my IP to go blacklisted and have some domains permanently banned.

Things I’m buying on Amazon this week

This article shows you how to configure everything so you have everything in the following list for free ($0.00):

  • Encrypted emails (TLS)
  • No Spam, both¬†sending and receiving
  • Send and receive emails
  • Multiple custom¬†domain and address, have as many domains and addresses as you want
  • Centralize everything into one Gmail¬†account… or do whatever you want with fully customizable forwarding, rules, filters, regular expressions, callbacks, webhooks, API and much more

A Mail Server¬†is a very complex thing¬†and you really need to know your stuff in order to avoid becoming an unintentional spammer. Even though I’ve followed tons of advice and tutorials around, I haven’t been able to really set up a 100% secure email server on my own, some spammers still managed to send spam through my servers.

The one that got me crazy¬†was someone sending me emails using my same address (e.g. [email protected] to [email protected]). This wouldn’t sound like¬†a big issue since it was just me sending¬†spam to myself and I could just ignore it, but the problem was that Postfix was forwarding those emails to my Gmail account so I¬†looked as the spammer to the eyes of Google. That’s really bad and can make some serious damage to your server and websites.

Some time ago I used Mandrill’s free plan yet they integrated it into MailChimp and made you pay a ridiculous amount of money for the occasional user.¬†I don’t send a lot of emails, most of them are¬†sent from my¬†personal and free projects I develop in my free time (for bigger projects and freelance work I get paid professional alternatives) and receive very few email too, mostly from my websites’ contact forms.

Finding out the best free way to send and receive from my custom domains

I spent many hours¬†looking for the best way to set everything up that did everything I needed. I love to have everything centralized into one Inbox, preferably web-based and in Gmail since it’s the best email client I’ve ever tried. So I tried a hundred different configurations with Postfix plus a few other mail servers in order to get everything into Gmail, checked what¬†services where out there to avoid maintaining¬†a Mail server and ended up removing any mail from my server¬†completely and signing up for the Free plan at Mailgun.

With Mailgun.org’s Free plan you can send unlimited emails and receive 10,000 emails per month (330 per day), more than enough for my needs.¬†It’s also got a nice API and regular expression filters that you can use to do pretty much anything from routes, webhooks, logs, HTTPS callbacks, etc.

If you need to send and receive many emails, I’d recommend Amazon Web Services or any other provider, Mailgun is not the cheapest one out there yet the best choice for the features they offer¬†and ease of set up.

Without further ado, here are the steps you need to follow in order to get everything up and running, you¬†can¬†skip some steps down below¬†if you don’t need them.

Setting up the DNS Records


Create a free account with them to be able to¬†receive¬†10,000 emails a month, you can also add your credit card details (recommended) so you can send unlimited emails and have 1,000 custom domains (instead of 10 only). Since I signed up, I haven’t paid a cent and, if you go over the limit it’s¬†$0.00050 or less per email.

Once you have your account, go to Domains > Add New Domain and type your domain name. I had no need for the “mg.” prefix since I send everything through them. If you want to send tons of emails (e.g. newsletters) you could add the “mg.” and use another service too.

mailgun add new domain

Once you’ve added it, go to Domain Settings and enable Inbound Spam Filter, this is going to be extremely useful in order to block about¬†90% of Spam to Gmail. Don’t worry, if you feel you’ve missed an email just open the Logs and it’ll show there.

Open the section Domain Verification & DNS, don’t close this tab.


I use Cloudflare, it’s also free and has many advantages apart from a really nice interface to manage your domains DNS. You can use whatever service you want really, as long as you can customize your DNS records.

With the DNS information in Mailgun settings I mentioned before, copy everything into Cloudflare so it looks something like this:

Mailgun-Cloudflare DNS records

Go back to Mailgun and click on¬†Check DNS Records Now so every feature that you need (sending, receiving and tracking) has a green check. If it doesn’t work, wait a few minutes in case anything is cached and try again. If that fails, you may have something wrong.

Forwarding rule to Gmail

There’s still one thing left in order to receive email into your Gmail. As we have it set up right now, all email coming to your domain will go to Mailgun, but Mailgun doesn’t know what to do with it. What we’ll do next is create Routes¬†in which we tell Mailgun what to do in every case. I have it set up so everything goes to a centralized email:

mailgun route forwarding

You can use regular expressions in there, haven’t tried them myself but the possibilities are endless. Right now we are adding rules to Match Recipient, in a bit I’ll show you about the Match Header which is very useful for combating Spam and for more complex setups.

Labelling emails in Gmail

If you have set it up just like me, you will receive tons of emails and it can be cumbersome. In order to tidy everything up, I’ve set up rules so whenever an email comes from *@xaviesteve.com, it adds the Label xaviesteve. This is easily done in Gmail by going to¬†Settings > Filter and Blocked Addresses.

apply label custom domain gmail

Sending from Gmail

Let’s¬†set your Gmail account so you can write and reply directly with¬†your custom domain. Go to Settings > Accounts and Import and click Add another email address you own. Follow the wizard and type in your info like this:

custom domain sending from gmail (step 1)

custom domain sending from gmail (step 2)

Google will send you an email with an activation link so make sure you are receiving emails. Once you have activated the address, you will be able to change the From: when writing an email in Gmail. You can also customize each email address signature!

gmail from field

Setting up PHP

We are receiving emails and sending them through Gmail. We probably want our web apps to send transactional emails too. Mailgun has got a really nice API and libraries for many languages including Ruby, Python, PHP, Java, C# and even simple command-line cURL.

You don’t need a library to do that, with a few lines of code you can also make your app send emails via Mailgun. Here’s a PHP example to send emails through SMTP:

function smtp_mail( $params ){
 ini_set('default_socket_timeout', 3);

 if ( $h = fsockopen($params['host'], $params['port']) )
 $data = array(
 "EHLO ".$params['host'],
 "MAIL FROM: <".$params['from'].">",
 "RCPT TO: <".$params['to'].">",
 "Subject: =?UTF-8?B?".base64_encode($params['subject'])."?=\r\n".
 "To: ".$params['to_name']." <".$params['to'].">\r\n".
 "From: ".$params['from_name']." <".$params['from'].">\r\n".
 "MIME-Version: 1.0\r\n".
 "Content-Type: text/html; charset=utf-8\r\n".
 "Content-Transfer-Encoding: base64\r\n\r\n".
 foreach($data as $c)
 $c && fwrite($h, "$c\r\n");
 while(substr(fgets($h, 256), 3, 1) != ' '){}
 fwrite($h, "QUIT\r\n");
 return fclose($h);
 return false;

var_dump( smtp_mail([
 'from' => '[email protected]',
 'from_name' => 'Xavi',
 'to' => '[email protected]',
 'to_name' => 'Peter Griffin',
 'subject' => 'Hello mate!',
 'body' => 'Hi Peter,<br>You are the best.<br>Yours,<br>Xavi',
 'user' => '[email protected]',
 'pass' => '232e2cda0805s65f84a22b38f8a8cdc2',
 'host' => 'ssl://smtp.mailgun.org',
 'port' => 465,
]) );

This code is a modified version of David Pennington‘s, released under a MIT License.

As I was telling you before I disabled Postfix completely, I presume that’s the reason why¬†the mail() function in PHP stopped working. You will probably need to either stop using mail() and send emails with this function (or library)¬†or try your luck and keep Postfix running, YMMV here.

Mailgun Header Filters to combat Spam

Mailgun’s got a pretty good system to fight Spam, yet sometimes you will get that pesky email that goes under the radar, here’s where Match Header¬†routes come into play to filter specific email subjects. Here’s an example of a few emails I’m blocking¬†from being processed:

Raw expression:

match_header("subject",".*hot chicks in your area") or match_header("subject","India Mobile Apps Development") or match_header("subject","employees needed")

No check Stop to cancel any action with that email.

You can also set up Routes to send an HTTP callback to your app and Webhooks that notify you of opens/clicks to build email-based apps pretty easily.

The End

Simple Cloud Hosting Built for Developers

So that’s pretty much it, if you have any doubts, comments, suggestions… Feel free to comment below and we’ll do our best to help you out.

All passwords and tokens look real yet have been modified¬†and don’t work. I am not affiliated with Mailgun, Cloudflare or any other company mentioned in this article, this is a personal and honest recommendation.

Free 100% online banking account

ūüí≥ Get your free debit Mastercard

No comments yet

Treasure Chest

Get notified of new projects I make
Usually one email every 3 months

Follow me for cool new products and interesting findings on graphic design, web development, marketing, startups, life and humor.

/*Twitter*/ !function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs"); /*Facebook (function(d, s, id) {var js, fjs = d.getElementsByTagName(s)[0];if (d.getElementById(id)) {return;}js = d.createElement(s); js.id = id;js.src = "//connect.facebook.net/en_GB/all.js#xfbml=1&appId=28624667607";fjs.parentNode.insertBefore(js, fjs);}(document, 'script', 'facebook-jssdk'));*/ /*Google+*/ window.___gcfg = {lang: 'en-GB'};(function() {var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;po.src = 'https://apis.google.com/js/plusone.js';var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);})();