SMTP Gateway for Multiple Domain Email Gateway with Postfix

Scope / Purpose

This article walks through the setup for a email gateway for multiple domains, rejects unknown email addresses, and uses a script to query valid email addresses via Active Directory.

Overview

This article describes the rationale and the setup of an external email firewall/gateway server with Postfix, a secure, high performance, and easily configurable alternative SMTP server to Sendmail.

The most common reason for this is to improve security (this applies even if you’re not running Exchange). Since the email gateway theoretically only exposes its SMTP port, and will not store any emails, so even in the (ideally unlikely) event that it is compromised, any sensitive or valuable data is held elsewhere. The worst that could happen is that the attacker obtains a list of vaild email addresses for your domain(s). It can also be used for offloading services from your main email server, tasks like rejecting and filtering spam, greylisting, scanning viruses, avoiding unnecessary bandwidth, etc.

There are “articles” on the Internet that make references to simplying using the “relayhost = internalsmtp.example.com” directive. The problem with this setup is that since the external email gateway knows nothing about the internal addresses (even when configured to only accept email to @example.com), that it has to accept and forward everything and depend on the internal host to handle rejecting and bouncing messages. This might be acceptable, except if/when your domain becomes the target of a flood of spam or viruses to invalid/generated email addresses. Especially since the source and reply-to addresses of these emails are typically spoofed, each message ends up being accepted at the email gateway, forwarded to your internal server, rejected and relayed back to your email gateway, queued by the email gateway for delivery, retried repeatedly until it exceeds the nominal timeout, then bounced back to the email admin account on your internal email server. Lather, rinse and repeat that for every single message and it should be clear why you should never just use the “relayhost” directive to do this.

The “correct(tm)” way to do this, is to set up the email gateway so that it has knowledge of valid email addresses. That way, any address that doesn’t exist is immediately rejected before the email gateway even gets to accept the data. This is important enough to worth being redudant. Rejecting unknown addresses not only avoids the whole loop described above, but avoids tying up your bandwidth receiving whatever data that would have been sent.

References / Links

Basically, this article is a restatement of Postfix email firewall/gateway found on Postfix.org’s online configuration examples, and additionally Using Postfix relay_recipient_maps.

Configuration

This article will not cover the compiling or installation of Postfix as it’s generally available or easily installed for most distributions.

/etc/postfix/main.cf

As the name implies, this is the main configuration file for Postfix. One main attribute with Postfix is that the defaults generally default to something sensible, so that for the most part, outside of the parameters that need to be customized to your setup, they can be completely omitted in main.cf.

Hint: The command below will show the configuration directives that have been altered from default.

 postconf -n
 
Since this is an email gateway only meant to forward email, disable local mail delivery by (Note: setting a configuration directive to empty disables it):

 mydestination =
local_recipient_maps =
local_transport = error:local mail delivery is disabled
 
Normally, emails that originate from a host will have a from address in the form of username@hostname.example.com. However, since the email gateway cannot receive mail for local users (as disabled above), you need to set the originating domain to something sensible:

 myorigin = example.com
 
mynetworks = define which networks are allowed to relay mail through this host. Although it’s meant for internal networks to be able to relay mail without having to authenticate, it can be used (abused) to include external IP addresses or networks. However, the proper solution is to set up your Postfix installation to do SASL authentication:

 mynetworks =
127.0.0.0/8,
172.16.42.0/24
 
This section below prevents addresses such as username@subdomain.example.com to match. Explicitly define domains you wish to accept using relay_domains below.

 parent_domain_matches_subdomains =
debug_peer_list,
smtpd_access_maps
 
relay_domains = define domains for which the email gateway will accept emails.

 relay_domains =
example1.com,
example2.com,
subdomain.example.com
 
smtpd_recipient_restrictions = controls what the Postfix server will accept during the RCPT TO command.

 smtpd_recipient_restrictions =
permit_mynetworks,
reject_unauth_destination
 
transport_maps = holds the mappings between domains and the SMTP server where the mail gets forwarded. See /etc/postfix/transport for details.

 transport_maps = hash:/etc/postfix/transport
 
relay_recipient_maps = points to a file that lists all of the email addresses for which the email gateway will accept mail. See /etc/postfix/relay_recipients.

 relay_recipient_maps = hash:/etc/postfix/relay_recipients
 
show_user_unknown_table_name = controls whether Postfix returns “User unknown in relay recipient table” (default – useful for debugging only) or “User unknown” (when set to no).  This configuration directive is only used in conjunction with relay_recipient_maps.

 show_user_unknown_table_name = no
 
ven though local mail delivery is disabled, the email gateway is still supposed to accept emails to postmaster and abuse. To do so, define a virtual alias map (we’ll populate the values later). See /etc/postfix/virtual for details.

 virtual_alias_maps = hash:/etc/postfix/virtual

/etc/postfix/master.cf

This file basically defines services that Postfix will provide. To completely disable local mail delivery, edit /etc/postfix/master.cf and insert a # symbol in front of the local service definition:
 #local  unix  -  n  n  -  -  local

/etc/postfix/virtual

In a typical setup, /etc/aliases is used  to forward mail to other account or external addresses.  However, since local mail delivery is disabled, modifying /etc/aliases has no effect. This file holds the alias mappings between local addresses and actual email addresses. Note: this is only necessary because there is no local mail delivery, and that some “local” addresses ought to exist for technical correctness.
 postmaster     postmaster@example.com
abuse abuse@example.com
root guru@example.com
Actually, you can use this file for more than local addresses.  You can forward emails from ex-users to their new emails addresses, create simple distribution lists, or copy an email to another user, etc.
 virtualuser@example.com      actualuser@example1.com
distribution@example.com user1@example.com,user2@example.com,user3@example.com
ex_user@example2.com forwarding_address@dom.ain
user@example.com user@example.com,spy@example.com

/etc/postfix/transport

This file defines the relationship between domains and the server(s) where mail is forwarded.
 example1.com              smtp:insidesmtp.example.com
example2.com smtp:insidesmtp.example.com
subdomain.example.com smtp:insidesmtp.example.com

/etc/postfix/relay_recipients

This file folds a complete list of email address for which the email gateway will accept mail. Even though you have to enter the values as a pair (key & value), the second part (the value) doesn’t actually matter as long as the email addresses are correct.
 user1@example1.com OK
user2@example1.com OK
user1@example2.com OK
user2@example2.com OK
user1@subdomain.example.com OK
user2@subdomain.example.com OK

Miscellany

Populating relay_recipients from Active Directory

Note that this script requires perl and Net::LDAP. However, this does NOT have to be on your email gateway.
   $VALID = "/etc/postfix/relay_recipients";
$dc1="domaincontroller1.example.com";
$dc2="domaincontroller2.example.com";
$hqbase="cn=Users,dc=example,dc=com";
$user="cn=user,cn=Users,dc=example,dc=com";
$passwd="password";
  • Note that if you have email distribution lists that need to be externally accesible, that you will also need the contents of:
 $hqbase="ou=Exchange Distribution Lists,dc=example,dc=com";

Hashing Databases

Postfix uses the db hash format by default. For this setup, we need to create the hashed db files by executing:
 postmap hash:/etc/postfix/virtual
postmap hash:/etc/postfix/transport
postmap hash:/etc/postfix/relay_recipients
Note: remember to rerun the above commands every time the contents of those files change.

Restarting Postfix

The preferred way of getting Postfix to reload its configuration files is simply execute:
 postfix reload

Testing the Setup

While it’s possible to just lob emails at your new email gateway, it might be easier to connect to it directly using telnet. Note: The following is a transcript. The lines not preceded by numbers (SMTP result codes) are commands that you would type. Also, make sure that you do not test from an IP address that belongs to a range defined by mynetworks = in /etc/postfix/main.cf. If it’s included in that range, the email gateway will simply accept the mail and try to deliver it. Also, to make troubleshooting easier, use your real email address instead of testadmin@example1.com so that the bounces will be delivered to you.

 telnet emailgateway.example.com smtp
220 emailgateway.example.com ESMTP Postfix
EHLO localhost
250-emailgateway.example.com
250-PIPELINING
250-SIZE 10240000
250-VRFY
250-ETRN
250 8BITMIME
MAIL FROM: <testadmin@example1.com>
250 Ok
RCPT TO: <unknown@unknowndomain.com>
554 <unknown@unknowndomain.com>: Relay access denied
RCPT TO: <unknown@example1.com>
554 <unknown@example.com>: Relay access denied
RCPT TO: <user1@example1.com>
250 Ok
DATA
354 End data with <CR><LF>.<CR><LF>
Subject: test
test 1 2 3
.
250 Ok: queued as 5152A39097
QUIT
221 Bye

0 comments:

Post a Comment

Please Enable JavaScript!
Mohon Aktifkan Javascript![ Enable JavaScript ]
close
close