Navigate

 

 

Article Links

 

 

Translate / i18n

 

 

Article Indexes

 

 

Advertisement

 

 

Article License

 

  • Creative Commons License
 

Designing Scalable SMTP Networks

This article looks at designing scalable SMTP networks. The main principle behind the design used in this article is a frontline group of SMTP relay servers that act as the public MX servers. Then a core set of servers on the backend that provide the local delivery and more in-depth processing. The relay servers skim the bulk of the junk, leaving less processing to be done on the core.

 

by  John Buswell     

 

 

The SMTP protocol is used for transferring email from clients to servers, and between servers. SMTP stands for Simple Mail Transport Protocol. This article looks at building scalable SMTP networks. While many small businesses and projects shy away from solutions with terms such as "scalable" and "enterprise", this is not the case here. Small businesses often equate scalable and enterprise with costly, due to the way expensive, and often less useful products are marketed. Before going in-depth, let's cover some of the SMTP basics.

 

DNS and MX records

DNS plays an important part in how email is delivered with SMTP. The SMTP servers are defined in A records. These are those DNS entries that assign an IP directly to a host name. DNS has a special record type called MX or Mail Exchange. These MX records tell a remote mail server how an email should be delivered to that domain. MX records consist of a preference number and a host name. The host name must point to an A record, not a CNAME (alias).

 

 

  • IN MX 10 mx2.smtp.splicednetworks.com.
  • IN MX 10 mx3.smtp.splicednetworks.com.
  • IN MX 10 mx4.smtp.splicednetworks.com.
  • IN MX 10 mx6.smtp.splicednetworks.com.

 

 

In the example above from o3magazine.com, you can see the IN MX defining the MX type. The preference number set here as 10 for each server. The final element is the host name. Also note the full stop that is required to terminate the host name in the zone file. Here the preference number is the same, so the DNS server will randomize the response list with each request. The remote server will then go down the list one by one. The server will stop when it successfully delivers the mail, or it receives an unreachable host or unknown user response from one of the servers in the mx list. If the preference numbers were different, then the highest priority (lowest MX preference value) would be tried first.

 

Looking up MX values

The host command (or nslookup) can be used to find the MX values for a particular domain. For example, host -t mx yahoo.com will yield:

 

 

  • yahoo.com mail is handled by 1 a.mx.mail.yahoo.com.
  • yahoo.com mail is handled by 1 b.mx.mail.yahoo.com.
  • yahoo.com mail is handled by 1 c.mx.mail.yahoo.com.
  • yahoo.com mail is handled by 1 g.mx.mail.yahoo.com.

 

 

Malicious Users

Spammers and those attempting to propagate viruses sometimes target the lowest priority servers on an MX list. These are often backup servers, sometimes at an ISP, which may not have the same anti-virus or anti-spam techniques employed as the primary servers. With modern high availability solutions, and the nature of MX records, it is not really necessary to utilize higher MX values. It is advisable to simply use the techniques employed above by o3 magazine and Yahoo, thus avoiding targeting of specific servers.

 

Sender Policy Framework

The experimental RFC 4408 defines SPF. SPF allows SMTP servers to identify and reject forged addresses in the MAIL FROM header during the SMTP exchange of mail. The forged addresses are often used in spam, as an attempt to get around filtering systems. SPF works by having the owner of a domain define a special DNS entry. The SPF DNS entry is a TXT entry which contains information about how email should be sent from that domain. The SPF entry contains the version and some other information.

 

 

  • mydomain.com. IN TXT "v=spf1 mx a:mx0.mydomain.com -all"

 

 

In the example above, the zone file for the domain is configured with an SPF version of 1, if it comes from one of the MX servers for that domain, or if it comes from mx0.mydomain.com. Anything received from any other sources will be rejected (-all). There is also a PTR entry which will check the reverse DNS of the senders IP address, to see if it resolves to the same domain as the sender domain.

 

SMTP Load Balancing

In addition to the round robin MX load balancing that DNS does by default, you could use a hardware load balancer to load balance each MX. There are several open source and commercial options available to do this. The advantage of using load balancing is scalability. Instead of having a large list of MX records, you can have a small number of MX records. Each one of those MX records would point to a virtual server on the load balancer. Each virtual server could have hundreds of servers behind it. If the deployment has only a handful of servers, using individual MX records will work perfectly fine, regardless of whether a server is down or not. Load balancing SMTP may also enable a finer level of control over load balancing, but the advantages would be marginal.

 

Relay and Core Servers

The scalable solution discussed in this article uses two type of servers, relay and core. The relay servers exchange mail with other SMTP servers on the Internet. Then the relay servers forward valid email to the core servers. This design enables N+1 relay servers, which are defined by the MX records for the domain. These relay servers will privately deliver mail to the core server(s). The core servers are only known to the relay servers, and only accept mail from the relay servers. The idea here is that the N+1 relay servers receive all email, whether it is legitimate or spam. The relay servers weed out as much spam as possible, before forwarding the mail on to the core servers. The core servers have more costly anti-spam and anti-virus measures, but as the relay servers have already trimmed the mail down substantially, there is less load to deal with. The MTA (Mail Transfer Agent) of choice for the rest of this article will be Postfix.

 

Relay Servers

The relay servers have no local delivery mechanism and they do not deliver mail to any users. Instead the relay servers perform specific anti-spam and other checks, before delivering mail to the core servers. The solution uses RBL (Realtime Blackhole Lists), Relay Domains, Relay Recipient Maps and header checks. There are no advance anti-spam measures on the relay servers, no dspam, no spam assassin, no postgrey. Those solutions need to gather data from multiple emails. The problem is that with N+1 relay servers, each relay server only receives 1/N of the traffic. The goal with this solution is to keep it simple, so the advanced processing occurs on the core servers, with reduced levels of mail.

 

Relay Servers: RBL

Realtime Blackhole Lists use DNS to determine if a particular SMTP server is on the list or not. There are several RBLs out there, we recommend Spamhaus (zen.spamhaus.org), Distributed Sender Blackhole List (list.dsbl.org) and RFC Ignorant (dsn.rfc-ignorant.org). Spamhaus deals with spammers, spam gangs and other parties that just spew junk mail in all directions. Spamhaus is a good way to block all those source IPs that are ripe for spam, and unlikely to contain serious business customers. Spamhaus references all the IP address blocks that are used for dynamic IP allocations for residential cable, dsl and dial up users at all the major ISPs. The distributed sender blackhole list, sends out test messages to see if a particular mail server will relay for something it shouldn't. For example, if you try to send email for someone@yahoo.com through the Google Mail servers, from someone@hotmail.com, it won't work. However, many users who setup things like Microsoft Exchange on their corporate networks, some of those users being IT consultants, create open relays. Spammers love open relays, and open relays today really should not exist, as they are simply a sign of incompetence. Finally, RFC Ignorant checks to see if a server is RFC compliant using some tests. Today, if a server is not RFC compliant, good chance it's some off the wall junk setup by someone who shouldn't be running a mail server. The RBL is a first line of defense, and will cut spam down considerably.

 

To configure RBL with Postfix, use the smtpd_recipient_restrictions command, along with the reject_rbl_client or reject_rhsbl_sender keywords.

 

 

  • smtpd_recipient_restrictions = reject_rbl_client zen.spamhaus.org reject_rbl_client list.dsbl.org reject_rhsbl_sender dsn.rfc-ignorant.org permit

 

 

This is just an example, a full smtpd_recipient_restrictions entry would reject on additional parameters, see the full configuration listed later in the article.

 

Relay Servers: Relay Domains

Postfix enables the configuration of a relay domain map. A relay domain is simply a list of domains that you will relay for, your domains. If a remote system tries to send to a domain not configured in the map, it won't work. This is easily configured with the relay_domains configuration option. For this article, we used mostly hashes, which are generated by running postmap against a text file in /etc/postfix. For example, postmap relay_domains will produce relay_domains.db from the relay_domains configuration text file. In the main.cf configuration file for Postfix, you would configure:

 

 

  • relay_domains = hash:/etc/postfix/relay_domains

 

 

The relay_domains file would consist of domain.com OK. Basically, the domain name followed by a tab separated OK. If a lot of domains require configuration, you can use a script. Assuming the list of domains are in a text file called domain-list.txt, the following script would get the job done.

 

 

  • #!/bin/bash
  • for i in $(cat domain-list.txt); do echo "$i OK" >> relay_domains; done

 

 

This would produce for example:

 

 

  • o3magazine.com OK
  • o3magazine.net OK
  • o3magazine.org OK

 

 

Relay Servers: Recipient Maps

The recipient map works on the same premise as the relay domains, but with users. The map is a simple hash, made up of user@domain.com followed by OK on the same line. Postfix enables you to get maps from all sorts of locations, mysql, ldap etc. The easiest form is a simple hash. For a small company, you have a set number of users, typically employees, some aliases and perhaps mailing lists. Even a large company has a set number of users, and this information is typically stored in some form of centralized database already, such as ldap. The recipient list enables you to create a sort of white list of permitted email addresses. This can drastically reduce the amount of alphabetical spam, especially if you use custom aliases, perhaps helpdesk@mycompany.com instead of support@mycompany.com.

 

To configure the recipient map, the relay_recipient_maps configuration option is used. Again postmap is run on the relay_recipients file to generate the hash database.

 

 

  • relay_recipient_maps = hash:/etc/postfix/relay_recipients

 

 

To generate a quick map, perhaps from a list of users (user-list.txt) and a list of domains (domain-list.txt), the following script will work:

 

 

  • #!/bin/bash
  • for i in $(cat domain-list.txt); do for y in $(cat user-list.txt); do echo "$y@$i OK" >> relay_recipients; done; done

 

 

Relay Servers: Header Checks

The idea behind header checks is to use regular expressions (regex) to find common strings in the header, and provide custom REJECT messages. For example, lets say nobody at your business can read chinese, there is little point in receiving messages with Chinese encoding. So you could do something such as:

 

 

  • /^Subject: =?big5?/
  • REJECT Chinese encoding not allowed.

 

 

Relay Servers: Transport Maps

With local delivery disabled, Postfix will need per domain transport maps to deliver the mail to the hidden core servers. Transport maps are similar to the other maps discussed in this article. The transport map uses the following format:

 

 

  • domain.com relay:[hidden.core.domain.com]

 

 

It is configured using transport_maps = hash:/etc/postfix/transport_map. Again for this hash we need to run postmap on the text configuration file. Keeping with our useful scripts, the domain-list.txt file can be used to generate the map.

 

 

  • #!/bin/bash
  • for i in $(cat domain-list.txt); do echo "$i relay:[upstream.mydomain.com]" >> transport_map; done

 

 

Relay Servers: Final Configuration

Using a very simple postfix configuration, with RBL, Regex based Header Checks and a couple of maps, we've just created a very secure relay. The final configuration for the relay is listed below. The configuration can be the same for each relay, just vary the myhostname and inet_interfaces to match the host name and IP of each individual server.

 

 

  • queue_directory = /smtp/queue
  • command_directory = /smtp/usr/sbin
  • daemon_directory = /smtp/sbin
  • mail_owner = test_postfix
  • myhostname = mx99.test.mydomain.com
  • myorigin = mydomain.com
  • inet_interfaces = 10.25.25.25, localhost
  • mydestination =
  • local_recipient_maps =
  • virtual_alias_maps = hash:/config/vamap
  • local_transport = error: local mail delivery is disabled
  • unknown_local_recipient_reject_code = 500
  • unknown_address_reject_code = 554
  • unknown_hostname_reject_code = 554
  • unknown_client_reject_code = 554
  • biff = no
  • smtpd_helo_required = yes
  • strict_rfc821_envelopes = yes
  • disable_vrfy_command = yes
  • smtpd_recipient_restrictions = permit_mynetworks reject_unauth_destination
  • reject_non_fqdn_hostname reject_non_fqdn_recipient reject_unauth_pipelining reject_invalid_hostname reject_unknown_sender_domain reject_rbl_client zen.spamhaus.org reject_rbl_client list.dsbl.org reject_rhsbl_sender dsn.rfc-ignorant.org permit
  • smtpd_data_restrictions = reject_unauth_pipelining, reject_multi_recipient_bounce, permit
  • relay_domains = hash:/config/relay_domains
  • relay_recipient_maps = hash:/config/relay_recipients
  • transport_maps = hash:/config/transport_maps
  • mynetworks_style = host
  • in_flow_delay = 5s
  • header_checks = regexp:/config/headercheck.regex
  • smtpd_banner = $myhostname ESMTP $mail_name
  • sendmail_path = /smtp/usr/sbin/sendmail
  • newaliases_path = /smtp/usr/sbin/newaliases
  • mailq_path = /smtp/user/sbin/mailq
  • setgid_group = test_postdrop

 

 

Core Servers

The core server(s) are defined in the transport map. Only the relay SMTP servers will know about the core server(s). As discussed in previous issues of o3 magazine, you could use a private VPN between servers and route the traffic over that encrypted link, if desired. To keep things simple you could use it as mx0.mydomain.com, but as it will never get email from an SMTP server outside of your control, make sure it never gets an MX record for any domain. The core server is where extra protection such as DSPAM, Postgrey and other anti-spam measures are placed. Such measures are discussed in other articles in this issue, so please refer to those articles for configuration and further information.

 

Protecting the Core Servers

The Core Servers could write to a shared storage medium such as NFS or iSCSI, or if the deployment is small, a pop3 / imapd solution such as dovecot may run on the core server. Dovecot could run as imapd, and Apache on another server could be running a web mail solution such as Roundcube, also discussed in this issue. The two servers could use a VPN link or a local private network, to access imapd. The most important protection for this SMTP solution is to use iptables. The iptables configuration needs to allow the relay servers, and deny all other traffic. If the server is being used for outbound internal mail, then iptables needs to allow new SMTP connections from local user networks, vpn networks, and allow the core server to send outbound SMTP to the world.

 

For Red Hat, CentOS, Fedora, the /etc/sysconfig/iptables would need the following added:

 

 

  • -A RH-Firewall-1-INPUT -p tcp --dport 25 -s 10.10.25.25 -d 10.25.25.25 -j ACCEPT
  • -A RH-Firewall-1-INPUT -p tcp --dport 25 -s 10.20.25.25 -d 10.25.25.25 -j ACCEPT
  • -A RH-Firewall-1-INPUT -p tcp --dport 25 -s 10.30.25.25 -d 10.25.25.25 -j ACCEPT
  • -A RH-Firewall-1-INPUT -p tcp --dport 25 -s 10.6.66.0/24 -d 10.25.25.25 -j ACCEPT
  • -A RH-Firewall-1-INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

 

 

Here 10.25.25.25 is the IP address of the core SMTP server, 10.10.25.25, 10.20.25.25 and 10.30.25.25 are the IP addresses of the relay SMTP servers and 10.6.66.0/24 is the local user network.

 

Conclusion

Building scalable SMTP networks with Postfix is not as difficult a challenge as it may initially seem. Using a combination of N+1 relay servers, and a small number of high powered core servers for advanced processing along with techniques that better define who should be receiving mail, one can easily enable a fast, and highly scalable SMTP network.

 

 

  •  
  • About o3:
  •  
  • o3 is a FREE online publication. o3 is published using open source software. The focus of o3 is on the use of Free and Open Source (FOSS) software in Enterprise and Business environments.
  •  
  •  
Sponsored by
Copyright © 2009 PRO OnCall Technologies LLC