Unified Linux and Exchange Delivery (with Anti-Spam and Anti-Virus)

In the current configuration, doctors and nurses are getting e-mail from the Postfix MTA on linserv1.corp.com . Their addresses are similar to nurse1@corp.com .

image from book
Figure 6.6: In Outlook setup, enter the name of the Exchange server and the user 's name .
image from book
Figure 6.7: Use the Global Address List to locate Exchange-enabled users.

The Sales, Human Resources and Marketing staffs are getting e-mail from Exchange on Exchange2003.corp.com . Their addresses are similar to salesperson1@ad.corp.com .

Even though we want the majority of our users on Exchange, we need to keep the Linux Postfix mail server serving our doctors and nurses.

It's time to unify the e-mail domains, so we need a new server that can route incoming e-mails from the Internet and route them to the correct e-mail server. Incoming e- mails will go to Exchange2003.ad.corp.com or linserv1.corp.com or get bounced back to the sender because there is no valid recipient on either system.

In Figure 6.8, you can see the new system we want to introduce outside the firewall. We want this system, named mail.corp.com , to both route e-mail to the mail server (Exchange or Postfix) that hosts the recipient's mailbox and prescrub incoming e-mail for spam and viruses.

image from book
Figure 6.8: We'll create mail.corp.com outside the firewall to clean incoming mail and route mail to the correct e-mail server.

To do this, we'll need to take several steps:

  1. We'll reconfigure Exchange a bit. Right now Exchange thinks its users have addresses @ad.corp.com , but we want everyone to have an @corp.com address. Also, right now Exchange assumes any e-mail address in its own domain that it can't find in Active Directory is a bad address. We need to tell Exchange to forward such messages to the mail.corp.com server for possible delivery to the Linux departmental server.

  2. Similarly, we'll reconfigure Postfix on the departmental Linux server a bit. So far, the Postfix departmental server assumes any e-mail address in its own domain that it can't find in LDAP or /etc/passwd is a bad address. We need to tell Postfix to forward such messages to the outside mail.corp.com server for possible delivery to the Exchange server.

  3. We'll bring up our new mail.corp.com server outside the firewall. Of course, we'll install it with the services we want to configure such as having its own Postfix MTA. We'll discuss the role of mail.corp.com in more detail in the next section.

  4. We'll install anti-spam and e-mail anti-virus packages on mail.corp.com . That way, we kill the bad e-mail as soon as it gets sent to our company, before it even makes it inside.

  5. Finally, we'll make sure that when mail comes in to mail.corp.com , it is specifically routed to the e-mail server where the users can pick up their mail. Mail for Exchange users must be recognized as such and forwarded to Exchange. Mail for users on the Linux departmental server must be correctly forwarded to that server.

What a Front-End MTA Does for Us

We already have perfectly good Linux and Exchange MTAs. Why do we need a front-end MTA?

We could, if we wanted, set up anti-virus and anti-spam services on both the departmental Postfix server and the Exchange server. But we don't have to. Instead, we'll create a front-end server that collects all the incoming e-mail, scrubs it of viruses, labels spam as spam, and sends the clean e-mail to our internal back-end e-mail servers. This has three major benefits:

  • It greatly reduces the load on the back-end mail servers. You'll be able to stuff more users on any given server because you won't have to worry about the overhead of running antispam or anti-virus on your internal mail servers.

  • A clean Exchange MTA is a healthy Exchange MTA. To that end, it's best to scrub e-mail before it hits the Exchange MTA, to maximize MTA health and maximize uptime.

  • If you pay for anti-spam or anti-virus, you're reducing your costs because you only have to load it one timeon the front-end server.

In addition, we can set up mail.corp.com to verify that mail has legitimate addresses before forwarding messages to the back-end servers. In other words, if the mail is going to bounce anyway because the user doesn't exist, we'll have it bounce right away instead of making one of our back-end servers process it.

Besides setting up anti-spam and anti-virus, the main goal of the front-end MTA is to solve the problem of coexistence between Exchange and Linux back-end mail servers in the same organization. Both back-end mail servers think they serve users with @corp.com e-mail addresses. And they do. But we need a way to route the incoming mail from the outside world to the back-end server that actually has the correct mailbox for the specific @corp.com user. We also need to be able to route mail from our Exchange users to our Linux users and vice versa.

We'll do all this using four main components :

  • The Postfix mail server We've already met this piece of software. In this case we'll use Postfix as an e-mail router and cleaner instead of delivering messages directly to mailboxes on the server.

  • The SpamAssassin spam filter SpamAssassin is a mail filter that "identifies spam using a wide range of heuristic tests on mail headers and body text," according to the SpamAssassin home page at http://spamassassin.apache.org .

  • The ClamAV e-mail virus filter ClamAV is a virus detection and removal tool supported by an active open source community. You can learn more about ClamAV from the ClamAV home page at www.clamav.net .

  • MailScanner This bridges the gap between Postfix, SpamAssassin, and ClamAV. SpamAssassin and ClamAV include their own simple methods of integration with Postfix, but these methods assume you won't be using both. MailScanner provides the ability to integrate any number of mail-scanning programs with Postfix. For good measure, it has some spam and virus detection capabilities of its own. For more information, visit the MailScanner home page at www.mailscanner. info / .

All of the above are free, open-source software packages.

However, we still have one bridge to cross. We need a way for mail.corp.com to "know" which users have mailboxes on Exchange and which users have mailboxes on the Linux mail server. We need a way for mail.corp.com to route to our back-end servers appropriately. To that end, we custom-wrote a Perl script to determine the correct back-end server for any given recipient. And that script can be used to route mail to any combination of Exchange and Postfix back ends, not just the specific configuration shown in this chapter.

Warning 

This script will work great only if you're using LDAP-based accounts on linserv1.corp.com . Otherwise, there's no way for mail.corp.com to find out which addresses belong to the Linux back-end MTA. LDAP is the key to sharing that information between the servers. If you didn't set up LDAP- based authentication in Chapter 2, this is the time to go back and do so. Specifically, check out the "Setting up an OpenLDAP Server on Linux" section of Chapter 2.

Here's one big word of caution: you must complete all the steps in this section and through the end of this chapter. These guidelines are provided to you as a whole package and shouldn't be performed piecemeal. During these steps, mail will stop routing properly until you're finished because we're about to tell both the Postfix departmental server and the Exchange server to route mail to mail.corp.com before it even exists.

Exchange Reconfiguration Tasks

To meet our aforementioned goals, we need to reconfigure Exchange a little bit differently than it comes out of the box. Here's what we're going to do:

  • Make the Exchange Server send and receive mail as if it were corp.com As it stands, all users on Exchange have e-mail addresses like salesperson1@ad.corp.com . We need to train Exchange to allow users to have e-mail addresses that show just @corp.com .

  • Force Exchange to send all mail to our mail.corp.com server We could allow Exchange to send outgoing e-mail directly to the Internet. But by forwarding these messages to the mail.corp.com front-end MTA, we gain the benefits of virus scanning for our outgoing mail. If an outbreak of e-mail viruses occurs within the local network, it's nice to know it won't be propagated to other companies and customers. Scanning your outgoing mail for viruses is good PR!

  • Force Exchange to send e-mail for unrecognized addresses in corp.com to the mail.corp.com server When an Exchange user (such as salesperson1 ) sends out an e-mail, it might be destined for someone on the Linux Postfix departmental mail server (such as nurse1 ). The mail.corp.com server will be configured to automatically distinguish between e-mail for Exchange users and e-mail for Linux users. So we'll forward messages for users in the corp.com domain that the Exchange server doesn't recognize to mail.corp.com and let mail.corp.com figure out whether they are intended for the Linux departmental server or simply invalid addresses. Without this change, Exchange assumes it is the one and only arbiter of who can get e-mail in the corp.com domain and drops messages for non-Exchange users.

Making Exchange Server Pretend to Be corp.com

As it stands, Exchange thinks it's sending and receiving mail as ad.corp.com . But when salesperson1 hands a business card to people she meets, it says salesperson1@corp.com . Therefore, we need to teach Exchange to send and receive mail as if it were responsible for message routing in corp.com .

To configure Exchange to do this, the tool you'll use is the Exchange System Manager. To make Exchange send and receive mail as corp.com :

  1. Select Start image from book Program Files image from book Microsoft Exchange and select System Manager.

  2. Drill down to Corp (Exchange) image from book Recipients image from book Recipient Policies and find Default Policy in the right-hand pane.

  3. Right-click Default Policy and select "Properties."

  4. Click the "E-mail Addresses (Policy)" tab, and click "New."

  5. In the "New E-mail Addresses" dialog, select "SMTP Address" and click "OK."

  6. In the "SMTP Address Properties" dialog, in the "Address" field, enter @corp.com , select "This Exchange Organization is responsible for all mail delivery to this address," and click "OK."

  7. Back at the "E-Mail Addresses (Policy)" tab, click the new @corp.com address you just created and select "Set as Primary." @corp.com will be bolded to let you know it's now the primary address, as shown in Figure 6.9. Click "OK" to continue.

  8. You'll be asked to update your current batch of users with e-mail addresses. You should select "Yes," as you've already assigned e-mail @ad.corp.com addresses to salesperson1 and salesperson2 . Note that this doesn't always take effect right away. Be patient. Within a few minutes, the new addresses will appear in Active Directory Users and Computers.

image from book
Figure 6.9: Add a primary and alternate destination address in the Default Policy Properties.

Making Exchange Server Use a Smart Host

In our world, we want to ensure that all mail the Exchange server sends and receives goes through the mail. corp.com front-end server. To do this, we'll tell Exchange to only send via a smart host .

To configure Exchange to send e-mail via a smart host:

  1. Select Start image from book Program Files image from book Microsoft Exchange and select "System Manager."

  2. Drill down to Corp (Exchange) image from book Servers image from book <your server name> image from book Protocols image from book SMTP.

  3. Right-click the "Default SMTP Virtual Server" entry and select "Properties."

  4. In the "Default SMTP Virtual Server Properties" page, select the "Delivery" tab.

  5. On the "Delivery" tab, select "Advanced." In the "Advanced Delivery" page, as shown in Figure 6.10, enter mail.corp.com in the "Smart host" field.

  6. Click "OK" on the "Advanced Delivery" page.

  7. Click "OK" on the "Delivery" tab, to close that as well.

image from book
Figure 6.10: Setting mail.corp.com as a smart host forces all mail to be routed out to mail.corp.com .

Making Exchange Forward Mail It Cannot Process

All of our internal Active Directory users will use Exchange to process their e-mail. However, as we've stated, some users in our organization won't be using Exchange; they'll be using linserv1.corp.com as a Linux Postfix e-mail server.

This presents a problem. Everyone in the organization has an e-mail address in the form of user @corp.com . What happens if an Exchange user sends e-mail to someone at corp.com but they aren't an Exchange user? That is, we need to tell Exchange what to do if it doesn't have the e-mail address for the user. In our case, we'll want to send all mail to mail.corp.com our gateway machinewhich will then figure out which server the e-mail is destined for and route it appropriately.

To set this up, just click the "Messages" tab in the "Default SMTP Virtual Server Properties" page. In the last entry, "Forward all mail with unresolved recipients to host" enter mail.corp.com , as shown in Figure 6.11.

image from book
Figure 6.11: Enter mail.corp.com as the destination address for forwarding unresolved e-mail.

Postfix Departmental Server Reconfiguration Tasks

Right now, the Postfix departmental server thinks it is the one and only mail server for corp.com . We need to adjust the departmental server's configuration a bit so that it can coexist with the Exchange server. We also want to configure the departmental server to take advantage of the spam-and virus-filtering capabilities of our front-end MTA, mail.corp.com for outgoing messages as well. We'll do most of this using Webmin. One final step is not supported by Webmin's Postfix module, so we'll just edit the Postfix configuration file directly for that one change.

First, we'll change the way outgoing mail is delivered. Right now, linserv1.corp.com delivers e-mail destined for domains other than corp.com directly to other MTAs. However, since we plan to create a front-end mail server that can filter out spam and viruses, it makes sense to subject our own outgoing e-mail to the same scans . After all, if internal workstations are compromised by viruses and become virus transmitters themselves , there's no reason to allow those machines to damage the organization's reputation by allowing their messages through. So we'll set the "Set outgoing e-mail via host" option in Webmin to mail.corp.com , the hostname of the front-end mail server we will configure later in this chapter.

Second, we'll tell the Postfix departmental server what to do with e-mail messages for addresses in the corp.com domain that do not have corresponding valid Linux accounts. For instance, when a Linux Postfix user, such as nurse1 , tries to send e-mail to an Exchange user, such as salesperson1 , we want that message to be forwarded to our new box mail.corp.com . This server handily solves the routing problem because mail.corp.com will be configured to correctly deliver messages to the right back end, either Linux or Exchange. Passing the messages through mail.corp.com also permits mail.corp.com to limit the spread of spam and viruses, stopping them at the gate between Linux and Exchange, in case of an outbreak of e-mail-virus-afflicted workstations in either camp.

We'll arrange this using the "Optional transport for unknown recipients" option of Webmin. A transport in Postfix is a way to deliver e-mail to a specific destination. A complete transport involves a protocol and, if delivery is not to the local server itself, a mail server (MTA) name. In this case, the protocol we want to use is SMTP (the Simple Mail Transfer Protocol, used by all MTAs to communicate with one another). The mail server we want to pass the message on to is mail.corp.com . Postfix configuration files separate these two things with colons, like this:

 smtp:mail.corp.com 

That's exactly how we'll describe the transport we want when we set that option in Webmin.

Finally, we need to let the Postfix departmental server know that it is not the sole and final authority on who has a valid e-mail address in the corp.com domain. Unless we do that, setting up the "Optional transport for unknown recipients" feature does us no good, because the server will discard e-mails for unknown recipients as junk mail.

By default, Postfix checks a list of "local recipient maps" to figure out what addresses are valid. Instead of allowing it do this, we'll set this option to an empty value. That tells Postfix not to discard e-mails for addresses it doesn't recognize. We'll set this directly in the Postfix configuration file, /etc/postfix/main.cf because this option cannot be set via Webmin.

Now we're ready to reconfigure Postfix based on what we just described. To reconfigure the Postfix departmental server to use mail.corp.com as a front-end MTA, follow these steps:

  1. Log into Webmin as usual at https ://linserv1.corp.com:10000/ .

  2. Click "Servers."

  3. Click "Postfix Configuration."

  4. Click "General Options."

  5. Scroll down and locate "Send outgoing mail via host." Select the right-hand radio box and enter mail.corp.com .

  6. Scroll down and click "Save and Apply."

  7. Click "Local delivery."

  8. Locate the "Optional transport for unknown recipients" option. Select the right-hand radio box and enter smtp:mail.corp.com in the text entry field.

  9. Scroll down and click "Save and Apply."

  10. With your favorite text editor, open /etc/postfix/main.cf and replace any existing setting for the local recipient maps option with the following, or add it at the end of the file if it does not already appear:

     local_recipient_maps = 
  11. Effect this change /etc/postfix/main.cf by restarting the Postfix server with the following command, as root:

     service postfix restart 

Setting Up a DNS MX Record for mail.corp.com

Before the outside world can deliver mail to anyone @corp.com , we'll need to set up an MX (mail exchanger ) DNS record for the front-end MTA. This is the DNS record that allows other hosts on the Internet to figure out where to send e-mail intended for the corp.com domain.

When someone outside of corp.com wants to send e-mail to, for instance, salesperson1@corp.com , they transmit the message to their own outgoing MTA. But exactly how does their MTA figure out what MTA to deliver the mail to? That's where MX records come in: MX records in DNS allow MTAs to use a DNS query to figure out where e-mail should go.

We'll add an MX record for the corp.com domain and set the MTA in that record to mail.corp.com .

Webmin can help us out with this task. All we have to do is use the Webmin module BIND DNS Server to add a new MX record. There's not much to it, just two things to know:

  • The domain to which e-mail is being delivered is referred to, a bit confusingly, as the "Name" field.

  • We'll need to set a priority for the MX record. This is very useful when there are multiple MX records for a domain because MTAs will automatically try the highest-priority MTAs first. In our case, there's just one MX record, so we'll arbitrarily choose a priority of 100 .

To add an MX record for mail.corp.com in the corp.com domain, follow these steps:

  1. Log into Webmin on linserv1.corp.com (the DNS server) as usual, at https://linserv1.corp.com:10000/ .

  2. Click "BIND DNS Server."

  3. Click " corp.com " under "Existing DNS Zones."

  4. Click "Mail Server (MX)".

  5. The "Mail Server Records" page appears with the subheading "Add Mail Server Record."

  6. In the "Name" field, enter corp.com .

  7. In the "Mail Server" field, enter mail.corp.com .

  8. In the "Priority" field, enter 100 .

  9. Leave "Time-To-Live" set to the default.

  10. Click "Create."

  11. Click "Return to Zone List."

  12. Click "Apply Changes."

Our MX record is ready! You can verify this with the dig command, which can be used to make a variety of DNS queries. Use the following command:

 dig -t mx corp.com 

The response should be, in part:

 ;; ANSWER SECTION: corp.com.              3600    IN      MX      100 mail.corp.com. 

If not, make sure you clicked "Apply Changes" to restart the DNS server.

Now we're ready to actually create the mail.corp.com system.

Installing Fedora on the Front-End Mail Server with the Postfix and SpamAssassin Packages

For Fedora installation instructions, follow those given in Chapter 1 for linserv1.corp.com , with the following changes:

  1. The hostname should be mail.corp.com

  2. The IP address of the server will be a valid, fixed Internet IP address, not part of an internal network such as 192.168.2.x . In our examples, we'll use the IP address 10.1.1.10 . Of course, you will use a real Internet IP address assigned to your organization.

  3. The DNS server name will be 192.168.2.202 (the IP address of linserv1.corp.com ). This ensures that mail.corp.com will be able to resolve hostnames within the local network.

  4. When you reach the package selection step, for the mail server option, click the "Details" link to display a full list of available packages.

  5. Make sure the optional SpamAssassin and Postfix packages are selected. If not, check the box next to each.

  6. Uncheck the box next to the Sendmail server. We are using Postfix instead of Sendmail.

When you have completed the initial installation, make sure you also fetch security updates and other fixes by running up2date. Mail servers are particularly vulnerable to security risks and should be kept up to date to guard against newly discovered attacks. Double-click the exclamation point icon the upper-right corner and follow the steps given in Chapter 1 to update your system.

Now we're ready to install the ClamAV virus filter.

Installing Clam Anti-Virus

The best way to obtain the ClamAV anti-virus software for Fedora Core 3 is to visit the ClamAV website at www.clamav.net . This way, you can seek out providers of rpms whose work has been acknowledged by the ClamAV team and used by many others.

We will also take the time to download a cryptographic key that verifies the identity of the person who packaged the rpm. This helps us to verify that the rpm has not been tampered with.

We followed these steps to obtain an rpm of ClamAV compatible with Fedora Core 3:

  1. Go to the URL www.clamav.net/ .

  2. Under the "Downloads" heading, click "binary packages and ports."

  3. Under the "Red Hat Fedora" heading, follow the "Fedora3" link, which currently leads to http://crash.fce.vutbr.cz/crash-hat/3/clamav/ .

  4. Click "clamav-0.83-1.i386.rpm" (the version number will vary; this is the current version number as of this writing, but you should download the latest available or latest stable release).

  5. Save or copy that file to /tmp on mail.corp.com .

We could install the rpm now, but we would receive a warning like this one:

 warning: clamav-0.83-1.i386.rpm: V3 DSA signature: NOKEY, key ID 6cdf2cc1 

This is because the rpm file was cryptographically signed with a key that mail.corp.com doesn't already have on file. So RPM can't verify the origin of the software. We can improve on this situation by downloading the author's cryptographic key, which we can locate by browsing the top directory of the http://crash.fce.vutbr.cz site. To install the key of the person who packaged this rpm, Petr Kristof, just use the rpm --import [URL] command to fetch the key and install it:

 rpm --import http://crash.fce.vutbr.cz/Petr.Kristof-GPG-KEY 

When successful, this command produces no output in the terminal window. If you receive warnings or errors, try opening the same URL with your web browser. If you don't have success doing that, we recommend that you visit http://crash.fce.vutbr.cz/ and check whether the key file's name has been changed.

Now we're ready to install the rpm, and any other rpm signed by Petr Kristof, without warning messages:

 rpm -i clamav-0.83-1.i386.rpm 

As mentioned before, your version number will most likely differ because ClamAV development is ongoing.

ClamAV is now installed on your system. Earlier, we installed SpamAssassin as part of the process of installing Fedora on mail.corp.com . Now, we'll install MailScanner, the software that integrates SpamAssassin and ClamAV with Postfix.

The default installation of ClamAV works perfectly for our needs and doesn't require any configuration changes, so we don't use Webmin to modify the ClamAV configuration in this book. However, a ClamAV module for Webmin is available. For more information, visit http://wbmclamav.labs.libre-entreprise.org/ .

Installing MailScanner

We have an MTA, a spam filter, and a virus filter. Aren't we finished? Well, no. Like most Linux applications, SpamAssassin and ClamAV attempt to do just one job and do it well. That job is reading the e-mail you hand off to them and deciding whether it contains spam or viruses.

These packages do not provide a robust, high-performance interface to various specific MTAs. That's where MailScanner comes into the picture. MailScanner can integrate any number of different e-mail filters with the MTA of our choicein this case, Postfix.

Note 

There are ways to integrate SpamAssassin or ClamAV with Postfix without using MailScanner or a similar program, but these methods assume you only need one or the other. When you want to use them together with good overall performance, you need MailScanner or a comparable program such as amavis.

MailScanner is easy to install. It's written in Perl and requires an assortment of Perl modules. The authors have packaged those with an installation script that automatically installs all of these requirements.

To install MailScanner, follow these steps:

  1. Browse the MailScanner website, at:

    • http://www.sng.ecs.soton.ac.uk/mailscanner/

  2. Click "Downloads."

  3. Under the "Stable" heading, click "Version 4.39.6-1 for RedHat and Mandrake Linux (and other RPM-based Linux distributions)." The version number you see will probably be newer ; download the latest stable version.

  4. Move the downloaded file, MailScanner-4.39.6-1.rpm.tar.gz (the version number will vary), to /tmp on mail.corp.com .

  5. As root, change your current directory to /tmp :

     cd /tmp 
  6. Unpack the gzipped tar file with the following command, which we've seen before:

     tar -zxf MailScanner-4.39.6-1.rpm.tar.gz 
  7. Change directories into the newly created MailScanner-4.39.6-1 directory (the version number you see will probably be different):

     cd MailScanner-4.39.6-1 
  8. Using a text editor, skim the README file for newer instructions, just in case the installation process has changed.

  9. Install the software with the following command:

     ./install.sh 

At the end of the process you will see instructions to activate the software. Those are intended for Sendmail; however, so don't try to follow them. We'll take care of configuring MailScanner for use with Postfix later.

Configuring Postfix As a Front-End MTA

Postfix has many, many configuration options. It's well beyond the scope of this chapter to attempt to cover them all. For a complete treatment of Postfix, see The Book of Postfix: State-of-the-art Message Transport by Ralf Hildebrandt and Patrick Koetter (No Starch Press, 2005, ISBN 1-59327-001-1). Also, see the Postfix website at www.postfix.org.

Fortunately, a standard installation of Postfix on Fedora Core 3 includes reasonable default settings for most options. Here we will concern ourselves only with those that must be changed from the default configuration to create our front-end MTA. However, we'll present our entire, working Postfix configuration file at the end of this section for completeness, with the options we added or changed listed first.

All Postfix configuration files are found in the directory /etc/postfix . The "master" configuration file for Postfix is /etc/postfix/main.cf . This is where all of the configuration choices are made. Some options refer to additional files or databases that contain, for instance, lists of domains to reject mail from, aliases to accept mail for, and so on.

The main.cf file has a very simple format. Blank lines and lines beginning with a # are ignored. All other lines take the following form:

  option  =  value  

Some options accept multiple values, separated by commas. In many cases the value will be a reference to another text file or to a database that we'll create a bit later using a Postfix command called postmap You'll see examples of this next.

inet_interfaces

By default, Fedora sets this option to localhost . That means that mail is only accepted from the server itself. We, of course, are creating a front-end MTA that accepts mail from the rest of the world, so we'll want to accept mail on the Ethernet interface also. We can do this by setting inet_interfaces to all .

mydestination

This option determines the domains and hostnames that the server accepts incoming mail for. If we were building a typical standalone mail server that delivered mail to local POP mailboxes, we would want our domain, corp.com , to be on that list. However, in this case, we intend to relay mail for corp.com to the Exchange server behind the firewall after we clean it of viruses and spam, of course. The only addresses we should regard as local are localhost, localhost.localdomain , and localhost.corp.com . These are typically used to deliver notices of system activity to the local system administrator. We'll set this option to localhost.$mydomain, localhost.localdomain, localhost . Postfix automatically replaces $mydomain with corp.com without our changing the configuration file if our domain name changes.

relay_domains

Once upon a time, most mail servers cheerfully forwarded e-mail for third parties. The mail server for corp.com , for example, would have typically accepted a message "From:" jane@examplecompany.com , addressed "To:" doug@exampleschool.edu , and simply forwarded it on to the mail server for exampleschool.edu . Nowadays, this behavior is known as open relay . Because an open relay can be used to forward unlimited amounts of spam, many sites have harsh filtering policies that refuse all e-mail from servers known to be open relays. That's why we must be very careful to specify which domains we really do want to relay e-mail for. By default, postfix relays mail only for hosts it is the final destination for. Since our front-end MTA is not the final destination (the Exchange server or departmental Postfix server is), we must explicitly state that mail for corp.com should be relayed. This is one of the areas where the Webmin GUI for Postfix is currently inadequate for our purposes.

transport_maps

By default, Postfix is configured as the final destination for e-mail, delivering it to POP mailboxes on the server's hard drive. We, of course, are forwarding mail to the Exchange server and departmental Postfix server instead. How exactly do we do that? By creating a transport map , a text file that specifies where mail for corp.com should be delivered. We introduced the idea of a Postfix transport in the previous section. Though we used Webmin in that section, transports are described in the same way in the configuration file.

We'll create the text file /etc/postfix/transport , which should contain "rules" in this format, one per line:

 emailaddress smtp:hostname 

Rules like this specify that mail for emailaddress should be forwarded via SMTP (the Simple Mail Transfer Protocol) to hostname . A typical rule for a user on the Exchange back-end server would be:

 salesperson1@corp.com smtp:exchange2003.ad.corp.com 

and a typical rule for a user on the Linux Departmental Mail Server back end would be:

 nurse1@corp.com smtp:linserv1.corp.com 

Postfix uses map files like this for many purposes. Notice that the rule consists of a key (the domain name) on the left and a value (the mail delivery instructions) on the right. All Postfix map files are made up of key/value pairs like this. Once we create or edit an existing map file, we'll need to publish it using the postmap command. Publishing the file creates a database in which Postfix can look up the value for any key much more quickly than scanning a text file over and over would allow. We use the postmap command this way:

 postmap /etc/postfix/transport 

We then use the transport_maps option in main.cf to point to the /etc/postfix/transport file as our source of transport map information, by setting the value for this option to hash:/etc/postfix/transport . The term hash indicates that the actual data should come from a .db file published by the postmap command. The filename specified, /etc/postfix/transport , is that of the text file, but the hash: prefix allows Postfix to locate the actual data in

 /etc/postfix/transport.db. 

Does this mean we'll have to maintain /etc/postfix/transport by hand? Thankfully, no! We've written a Perl script which does that job automatically, rebuilding /etc/postfix/transport every hour . The script, build-transport-maps.pl , fetches information about valid e-mail accounts from both the Linux-based Departmental Mail Server and the Active Directory server and builds a complete map file that allows our front-end MTA to correctly deliver mail to both sets of users. We present this script in detail later in this section.

relay_recipient_maps

We'd like Postfix to take care of discarding e-mail for bogus addresses that don't actually exist on Exchange or on our departmental Postfix server. This will save wear and tear on our back end servers. But if our front-end MTA isn't the final destination for e-mail, how can we tell good addresses apart from bad?

Postfix has an option, relay_recipient_maps , which allows us to specify all of the valid e-mail addresses for the ad.corp.com . By setting this option to point to a file containing a database of valid e-mail addresses, we enable our front-end MTA to correctly recognize legitimate recipients. E-mail for all other recipients is bounced back to the sender without forcing the Exchange server to deal with it. No matter how good our spam filters are, there will always be junk mail that slips by them, but many (if not most) of these messages will be intended for bad e-mail addresses, and we can completely eliminate the need for Exchange to deal with those messages.

We set this option to hash:/etc/postfix/recipients . But how can we keep an up-to-date list of every valid e-mail address in that file? Surely that's impractical ! Again, fortunately, we don't have to do it by hand. As explained, we've written a Perl script which does that job automatically, rebuilding both /etc/postfix/transport and /etc/postfix/recipients every hour. The script, build-transport-maps.pl , fetches information about valid e-mail accounts from both the Linux-based departmental mail server and the Active Directory server and builds a complete list of valid e-mail recipients, as well as a transport map that allows our front-end MTA to correctly deliver mail to either set of users.

header_checks

Postfix provides several ways to check e-mails for telltale signs of spam and other important markers. One of these is the header_checks option; this option points to a map file. Each rule in the map file consists, as usual, of a key and a value. Each key is a regular expression , a pattern that matches something that may or may not appear in the header lines of an e-mail message. Each value indicates what should be done with a message that matches the regular expression.

We'll set the header_checks option to point to a map file called /etc/postfix/header_checks :, as follows :

 header_checks = regexp:/etc/postfix/header_checks 

In that file, we'll place a single rule which requires Postfix to place any messages that contain a Received: header "on hold" by moving them to the hold queue. Since all e-mail messages contain a Received: header, this is really a way of placing all messages on hold. We do this so that every incoming message finds its way to the hold queue, where we will configure MailScanner to pick up messages and scan them for spam and viruses. The single rule we'll place in /etc/postfix/header_checks is

 /^Received:/ HOLD 

Unlike /etc/postfix/recipients , we don't publish this file with the postmap command. That's because Postfix needs to look at all of the rules in the file, not just one, so there's no performance benefit to be gained by creating a database index.

Most of this regular expression is fairly obvious: the pattern to be matched appears between the slashes . The ^ character matches the beginning of a line. For complete information about regular expressions, see Mastering Regular Expressions, 2nd Edition by Jeffrey E. F. Friedl (O'Reilly Press, 2002, ISBN: 0-596-00289-0.) Also see the excellent Wikipedia entry at http://en.wiki- pedia.org/wiki/Regular_expression .

MailScanner will take care of moving good messages from the hold queue to the incoming queue so that Postfix can continue the process of delivering them.

Listing 6.1: /etc/postfix/main.cf for the mail.corp.com front-end MTA
image from book
 queue_directory = /var/spool/postfix command_directory = /usr/sbin daemon_directory = /usr/libexec/postfix mail_owner = postfix inet_interfaces = all mydestination = localhost.$mydomain, localhost, localhost.localdomain unknown_local_recipient_reject_code = 550 relay_domains = corp.com alias_maps = hash:/etc/aliases alias_database = hash:/etc/aliases header_checks = regexp:/etc/postfix/header_checks debug_peer_level = 2 debugger_command =     PATH=/bin:/usr/bin:/usr/local/bin:/usr/X11R6/bin     xxgdb $daemon_directory/$process_name $process_id & sleep 5 sendmail_path = /usr/sbin/sendmail.postfix newaliases_path = /usr/bin/newaliases.postfix mailq_path = /usr/bin/mailq.postfix setgid_group = postdrop html_directory = no manpage_directory = /usr/share/man sample_directory = /usr/share/doc/postfix-2.1.5/samples readme_directory = /usr/share/doc/postfix-2.1.5/README_FILES transport_maps = hash:/etc/postfix/transport relay_recipient_maps = hash:/etc/postfix/recipients 
image from book
 

We're almost ready to move on. But first, we need to configure a script that will provide us with regularly updated /etc/postfix/recipients and /etc/postfix/transport files.

Warning 

Although we have configured Postfix itself as a front-end MTA, we did so in a way that requires us to also configure MailScanner and the rest of the tools described in the sections that follow. Be sure to follow through and complete the remaining sections before expecting your front-end MTA to operate properly.

Installing and Configuring the build-transport-maps.pl Script

To review, the ultimate goal is to have incoming e-mail on mail.corp.com and for that e-mail to be routed to either linserv1.corp.com or exchange2003.ad.corp.com depending on where the real destination mailbox is.

To that end, we've written a Perl script entitled build-transport-maps.pl . It does three things:

  • It identifies valid Exchange e-mail addresses by fetching a list of valid e-mail addresses from Active Directory.

  • It identifies valid Postfix departmental server e-mail addresses by fetching a list of valid LDAP accounts from the OpenLDAP server on linserv1.corp.com .

  • It uses this information to rebuild the /etc/postfix/recipients and /etc/postfix/transport files, then rebuilds the relevant Postfix databases using the postmap command. This allows the Postfix server on mail.corp.com to recognize an updated list of valid e-mail addresses and forward messages to the correct back-end mail server for each.

The script is presented at the end of this section as Listing 6.3 and can also be found on our website at www.winlinanswers.com/ .

To begin, copy the script and put it in a file named to /etc/postfix/build-transport-maps.pl on mail.corp.com .

Next, using a text editor, we'll need to set up a configuration file for the script. The configuration file name is /etc/postfix/build-transport-maps.conf . This file should have three section headings: [global], [Exchange Mail Server] , and [Linux Mail Server] . The complete configuration file is presented in Listing 6.2.

Listing 6.2: /etc/postfix/build-transport-maps.conf
image from book
 [global] domain = corp.com [Linux Mail Server] name = Linux Mail Server #May be specified more than once uri = ldaps://linserv1.corp.com/ base = dc=ldap,dc=corp,dc=com filter = (&(objectclass=account)) smtpserver = linserv1.corp.com attr = uid [Exchange Mail Server] name = Exchange Mail Server #May be specified more than once uri = ldaps://windc1.ad.corp.com/ base = dc=ad,dc=corp,dc=com binddn = cn=dirsearch,cn=Users,dc=ad,dc=corp,dc=com bindpw = p@ssw0rd filter = (&(sAMAccountName=*)(mail=*)) smtpserver = exchange2003.ad.corp.com attr = name 
image from book
 
Tip 

Options in build-transport-maps.conf are set using a familiar name = value syntax. Option names are not case-sensitive.

Global Options (Designated with a [global] Heading)

The first line in your /etc/postfix/build-transport-maps.conf file should have a line that reads:

 [global] 

The global category contains just one option, domain . This is the domain name to be added to valid account names to produce an e-mail address. In our case, the correct setting is corp.com , so that line of the configuration file looks like this:

 domain = corp.com 

Back-End Options (Designated with [Exchange Mail Server] and [Linux Mail Server] Headings)

Here is what the [Linux Mail Server] heading should look like in /etc/postfix/build-transport-maps.conf :

 [Linux Mail Server] name = Linux Mail Server #May be specified more than once uri = ldaps://linserv1.corp.com/ base = dc=ldap,dc=corp,dc=com filter = (&(objectclass=account)) smtpserver = linserv1.corp.com attr = uid 

Here is what the [Exchange Mail Server] heading should look like:

 [Exchange Mail Server] name = Exchange Mail Server #May be specified more than once uri = ldaps://windc1.ad.corp.com/ base = dc=ad,dc=corp,dc=com binddn = cn=dirsearch,cn=Users,dc=ad,dc=corp,dc=com bindpw = p@ssw0rd filter = (&(sAMAccountName=*)(mail=*)) smtpserver = exchange2003.ad.corp.com attr = name 

Two options, bindpw and binddn , are optional for Linux but required for Active Directory. This is because Active Directory requires authentication before making directory service queries.

Here's a breakdown of each value and how it can be set:

  • name The name option specifies the name of the back end as it will appear in any error messages from build-transport-map.pl . We set it to Linux Mail Server for the Linux option group and to Exchange Mail Server for the Exchange option group.

  • uri The uri option, which may be given more than once for a single back end, specifies the LDAP server address to connect to. It's similar to the uri option in /etc/ldap.conf , as discussed in Chapters 2 and 3.

    For the Linux back end, the correct setting is ldaps://linserv1.corp.com ; which establishes a secure connection on the secure LDAP port, port 636.

    For the Windows back end, the correct setting is ldaps://windc1.ad.corp.com if the mail.corp.com front-end server meets the requirements for secure LDAP connections from Fedora Linux to Active Directory, as explained in Chapter 3, specifically the section titled "The Extra Mile: SSL Encryption of LDAP Traffic between Linux and Active Directory."

    If the version of OpenLDAP installed on mail.corp.com is too old, use ldap://windc1.ad.corp.com (not ldaps:// ) to establish a nonencrypted connection on port 389. Since only account names are being transmitted, this is an acceptable risk (but encryption is preferable).

    Giving this option more than once on separate lines provides fault tolerance. That is, the script will contact the first URI, then the second, and so on until a successful connection is made. If all URIs fail for any back end, the script will produce an error message and exit without updating maps.

  • base The base option specifies LDAP search base beneath which the search for accounts should be conducted . This is identical to the base option in /etc/ldap.conf . See Chapters 2 and 3 for extensive coverage of this subject.

  • filter Not every object in an LDAP database is an e-mail account. The filter option, similar to the filter option in /etc/ldap.conf , is used to limit the search to relevant objects. For Linux, we set this to (objectclass=account) , which matches all account objects in the LDAP database because accounts are always part of the account LDAP object class. For Exchange, we set it to (&(sAMAccountName=*)(mail=*)) , which matches accounts in Active Directory that possess both a logon name and an e-mail address. * matches any value, and & specifies that all of the additional conditions within the enclosing parentheses must be true. A detailed discussion of LDAP filters is beyond the scope of this book; see Randy Franklin Smith's article, "LDAP Filters," on the Windows IT Pro website for more information at www.windowsitpro.com/Windows/Article/ArticleID/38949/38949.html .

  • smtpserver What is the final destination of the mail? The smtpserver option answers this question. We set this to linserv1.corp.com for the Linux back end and to exchange2003.ad.corp.com for the Windows back end.

  • attr The attr option specifies the name of the LDAP attribute that holds the account name. This is the logon name that can be followed with @corp.com to arrive at an e-mail address. This is needed because the different back ends have different LDAP schemas, as you saw in Chapters 2 and 3. For Linux, the correct setting is uid . For Windows, it is name .

  • binddn The binddn option specifies the distinguished name of the LDAP user to authenticate to the LDAP server as. This is used with the Active Directory server, where we configured a low- security user named dirsearch for this purpose in Chapter 3. For the Exchange back end, we set this option to cn=dirsearch,cn=Users,dc=ad,dc=corp,dc=com . We don't use this option with the Linux LDAP server because it is configured to allow anonymous queries.

  • bindpw The bindpw option specifies the password of the LDAP user we will authenticate to the LDAP server as. This is used with the Active Directory server, where we configured a low- security user named dirsearch for this purpose in Chapter 3. For the Exchange back end, we set this option to p@ssw0rd . We don't use this option with the Linux LDAP server because it is configured to allow anonymous queries.

We've finished configuring build-transport-maps.pl . We're almost ready to test it. But first, we need to install the Net::LDAP Perl module from CPAN, which build-transport-maps.pl needs to communicate with Active Directory and the OpenLDAP server on linserv1.corp.com . We've used the cpan command to install such modules before. Follow these steps to install Net::LDAP:

  1. Make sure mail.corp.com has Internet access. The cpan command installs modules over the Net from the central Perl module repository.

  2. As root, enter the command:

     cpan 
  3. At the cpan > prompt, enter

     install Net::LDAP 

    and press Enter.

  4. If CPAN detects that other modules on which Net::LDAP depends are also not installed, it will offer to add them to the list of modules to install. Say yes to any such prompts. If CPAN detects that Net::LDAP is already up to date, skip to step 6.

  5. The installation will begin and will take about a minute or so.

  6. When the cpan > prompt reappears, type:

     quit 

    Press Enter to return to the shell prompt.

Just one task left before we can test the script. We must make the script executable with the following command, executed by root:

 chmod 700 /etc/postfix/build-transport-map.pl 

While we're at it, we will also limit access to the script's configuration file to the root user. There shouldn't be other users running free on a dedicated front-end server like mail.corp.com , but "defense in depth" is always the best strategy:

 chmod 600 /etc/postfix/build-transport-maps.conf 

Now we can test it by executing it:

 /etc/postfix/build-transport-map.pl 

If all goes well, this will produce no output at the shell prompt . That's because build-transport-map.pl is typically run from cron, and programs that generate output when run from cron result in e-mail to the user. We don't want root to be bombarded hourly by e-mails indicating that everything is fine. We do want root to get e-mail when things don't work, and build-transport-map.pl does complain in such situations.

If you see error messages, or if the script does not end and return to the shell prompt within two minutes, check all of the following:

  1. Do you have both the Linux mail server back end and the Exchange mail server back end up and running? If not, start them now.

  2. Did you follow the LDAP exercises in Chapter 2 as part of creating the Linux server linserv1.corp.com ? If not, you won't be able to set up a separate front-end MTA because a list of valid addresses can't be easily obtained over the network.

  3. Are you using an ldaps: URL to communicate securely with Active Directory? If you are, did you verify that your version of OpenLDAP is new enough as described in Chapter 3? If not, use an ldap: URL instead.

If the script completes successfully, you can verify that the /etc/postfix/transport and /etc/postfix/recipients files were updated by examining them with a text editor. /etc/ postfix/transport should look like this:

 Administrator@corp.com  smtp:exchange2003.ad.corp.com salesperson1@corp.com   smtp:exchange2003.ad.corp.com salesperson2@corp.com   smtp:exchange2003.ad.corp.com salesperson3@corp.com   smtp:exchange2003.ad.corp.com salesperson4@corp.com   smtp:exchange2003.ad.corp.com doctor1@corp.com        smtp:linserv1.corp.com doctor2@corp.com        smtp:linserv1.corp.com nurse1@corp.com smtp:linserv1.corp.com nurse2@corp.com smtp:linserv1.corp.com 

And /etc/postfix/recipients should look like this:

 Administrator@corp.com  OK salesperson1@corp.com   OK salesperson2@corp.com   OK salesperson3@corp.com   OK salesperson4@corp.com   OK doctor1@corp.com        OK doctor2@corp.com        OK nurse1@corp.com         OK nurse2@corp.com         OK 

Finally, we need to install a cron job to run this script once each hour. The crontab entry we'll need is

 0 * * * * /etc/postfix/build-transport-maps.pl 

We introduced cron jobs and how to install them in Chapter 4. See the "Scheduling Tasks with cron" sidebar in that chapter for details.

We've completed the configuration of Postfix. Now we're ready to configure MailScanner to bridge the gap between Postfix and the two virus and spam filter programs.

Listing 6.3: /etc/postfix/build-transport-maps.pl
image from book
 #!/usr/bin/perl -w #All settings appear in #/etc/postfix/build-transport-maps.conf, #nothing to change here. use strict; my %options; if (!open(IN, "/etc/postfix/build-transport-maps.conf")) {    die "Can't open /etc/postfix/build-transport-maps.conf";    } my $label = '[global]'; my $line; while ($line = <IN>) {    # Remove comments...    $line =  ~  s/\#.*$//;    # And skip blank lines, including lines made blank by    # removing comments    if ($line =  ~  /^\s*$/) {       next;    }    # Start new labeled section    if ($line =  ~  /\[([\w\s\.\-\+]+)\]/) {       $label = ;       $label =  ~  tr/A-Z/a-z/;       next;    }    my ($name, $val) = split(/\=/, $line, 2);    $name =  ~  s/^\s+//;    $name =  ~  s/\s+$//;    $name =  ~  tr/A-Z/a-z/;    $val =  ~  s/^\s+//;    $val =  ~  s/\s+$//;    if ($label eq "") {       die "All options must appear within a section, did you forget [global]?\n";    }    push @{$options{$label}{$name}}, $val; } close(IN); my $domain = @{$options{'global'}{'domain'}}[0]; my @serverTypeNames = keys(%options); my @serverTypes; my @required = ("name",    "base",    "filter",    "addr",    "smtpserver",    "uri"); my %required; my $r; for $r (@required) {    $required{$r} = 1; } my @scalar = ("name",    "base",    "binddn",    "bindpw",    "filter",    "attr",    "smtpserver"); my @list = ("uri"); my $sn; for $sn (@serverTypeNames) {    if ($sn eq "global") {       next;    }    my $s = { };    my $item;    for $item (@scalar) {       if (defined($options{$sn}{$item})) {          $$s{$item} = (@{$options{$sn}{$item}})[0];       }       if ($required{$item} && (!defined($$s{$item}))) {          die "Required option $item missing for $sn";       }   }   for $item (@list) {      $$s{$item} = $options{$sn}{$item};      if ($required{$item} && (!defined($$s{$item}))) {          die "Required option $item missing for $sn";       }    }    push @serverTypes, $s; } # Talk to both OpenLDAP and Active Directory to create # a transport map forwarding mail for Linux users to # one destination and Exchange users to another. # Also build a combined list of all valid recipients # for easy filtering of unsolicited junk mail without # troubling the internal servers. use Net::LDAP; my $s; open(RECIPIENTS, ">/etc/postfix/recipients.new"); open(TRANSPORT, ">/etc/postfix/transport.new"); for $s (@serverTypes) {    my $ldap;    my $uri;    for $uri (@{$$s{'uri'}}) {       $ldap = Net::LDAP->new($uri);       if ($ldap) {          last;       }    }    if (!$ldap) {       die "Could not contact any LDAP URIs for ",          $$s{'name'} , "\n" ,          "To avoid inconsistencies no maps will be updated.";    }    my $bind;    if ($$s{'binddn'}) {       # Bind as a specific user (simple authentication)       $bind = $ldap->bind(dn => $$s{'binddn'},          password => $$s{'bindpw'});    } else {       # Anonymous bind       $bind = $ldap->bind;    }    if ($bind->code()) {       die "Bind error: error:", $bind->code(), "\n",          "No maps will be updated on this pass.\n";    }    my $search = $ldap->search(base => $$s{'base'},                       filter => $$s{'filter'},          attrs => $$s{'attr'});    my $entries = $search->count;    if ($entries < '1') {       print STDERR "Warning: zero accounts found for ", $${'uri'}, "\n";    }    my @entries = $search->entries;    my $e;    for $e (@entries) {       my $m = $e->get_value($$s{'attr'});       # Ignore orphaned Exchange mailboxes with       # raw SIDs instead of user names       if ($m =  ~  /\{/) {          next;       }       my $smtpServer = $$s{'smtpserver'};       print RECIPIENTS "$m\@$domain\tOK\n";       print TRANSPORT "$m\@$domain\tsmtp:$smtpServer\n";    }    # Unbinding    $ldap->unbind; } close(RECIPIENTS); close(TRANSPORT); unlink("/etc/postfix/recipients"); rename("/etc/postfix/recipients.new",  "/etc/postfix/recipients"); system("/usr/sbin/postmap /etc/postfix/recipients"); unlink("/etc/postfix/transport"); rename("/etc/postfix/transport.new", "/etc/postfix/transport"); system("/usr/sbin/postmap /etc/postfix/transport"); 
image from book
 

Configuring MailScanner: Anti-Spam and Anti-Virus Capabilities for Your Front-End MTA

MailScanner's job is to scan e-mail messages using filter programs like SpamAssassin and ClamAV. When we configured Postfix, we added a rule to move all incoming mail to the hold queue. Now we need to configure MailScanner to pick up mail arriving in that queue, scan it for spam and viruses, and return clean e-mail back to the Postfix incoming queue for delivery to the Exchange server or departmental Postfix server.

image from book
Why We Didn't Use Webmin for MailScanner

A Webmin module for MailScanner is currently in beta and can be found at http://lushsoft.dyndns.org/mailscanner-webmin/ .

We chose not to rely on this module because it is still in beta, it is not one of the official Webmin modules on www.webmin.com , and as of this writing, the author recommends making backups of the MailScanner configuration file before using it. Also, the configuration changes needed in the MailScanner configuration files really aren't that difficult to make manually. Still, the MailScanner Webmin module is under active development and certainly worth taking a look at.

image from book
 

MailScanner's file has far too many configuration possibilities to list in detail here, and the default settings are reasonable. We'll cover only the options that need to be changed in order to use MailScanner with Postfix, SpamAssassin, and ClamAV. Consult the MailScanner documentation at www.sng.ecs.soton.ac.uk/mailscanner/ for additional information.

All MailScanner configuration files are found in the directory /etc/MailScanner/ . The main configuration file for MailScanner is called /etc/MailScanner/MailScanner.conf . All of the settings we need to change can be found here.

Similar to other configuration files, MailScanner.conf has a simple format: blank lines and lines beginning with a # are ignored, and all other lines take the following form:

  option  =  value  

Now, we'll examine each option that must be changed or set for the first time.

Run As User In Linux, as in Windows, programs always run as a particular user. Since we want MailScanner to pick mail up from and return it to Postfix queues, we'll need to run MailScanner as the postfix user, so we'll set this option to equal postfix .

Run As Group Similarly, we want to run the program with the correct group ID so that files are created with the correct group ownership for Postfix, so we also set this option to postfix .

Incoming Queue Dir We need to pick up mail from the Postfix hold queue. We accomplish this by setting this option to /var/spool/postfix/hold .

Outgoing Queue Dir When we have successfully scanned an e-mail message, we need to return it to Postfix. We do that by dropping it off in the incoming queue, so we'll set this option to /var/spool/postfix/incoming .

MTA The rules for picking up and dropping off messages in mail queues vary from MTA to MTA, so we need to specifically tell MailScanner we are using Postfix by setting this option to postfix .

SpamAssassin User State Dir SpamAssassin is often run on behalf of particular Linux users. In this configuration, MailScanner will be running it only as the Postfix user to filter all mail before it ever reaches individual users. However, we don't want to clutter up the Postfix user's home directory, /var/spool/postfix , with SpamAssassin- related data files. To avoid this, we'll specify an alternative location, /var/spool/MailScanner/spamassassin , and we'll use the mkdir and chown commands to make sure this directory exists and belongs to the Postfix user and group.

Use SpamAssassin By default, SpamAssassin is turned off in MailScanner. We activate it by setting this option to yes .

Spam Actions What should MailScanner do when it believes it has detected spam? By default, MailScanner delivers the message anyway and tags the message with an extra header line to make it easy for client software to sort spam messages into a separate bulk folder or delete them if the end user chooses. The extra header line looks like this:

 X-yoursite-MailScanner-SpamCheck: spam,  (additional text, which varies)  

Since no spam detection software is perfect, and there is always a possibility that real e-mail will occasionally be mislabeled as spam, we recommend that you stick with this default approach. However, if you prefer, you can set the Spam Actions option to delete . This causes e-mails that are considered highly likely to be spam to be deleted entirely and not delivered at all.

Configuring MailScanner to Use ClamAV

MailScanner is compatible with a wide variety of virus scanners . We'll need to specify the virus scanner we wish to use, ClamAV.

MailScanner has a separate configuration file with specific settings for each virus scanner. This file is called /etc/MailScanner/virus.scanners.conf . In this file, one line for each virus scanner determines what script should be run to scan for viruses and under what directory the virus scanner can be found. The first field on each line is the name of the virus scanner. The second is the path to a script, usually a wrapper installed by MailScanner that runs the real virus scanning tools in turn . The third is the parent directory under which the actual virus scanning programs can be found.

We will need to make one small change to this file. MailScanner assumes by default that the ClamAV tools are installed in subdirectories of /usr/local , such as /usr/local/bin , but the ClamAV rpm installed those programs in subdirectories of /usr , such as /usr/bin . So we'll need to edit /etc/MailScanner/virus.scanners.conf and change the following line:

 clamav   /usr/lib/MailScanner/clamav-wrapper/usr/local 

to read as follows:

 clamav   /usr/lib/MailScanner/clamav-wrapper/usr 

We have successfully created a front-end MTA. Now we're ready to start it up!

Launching MailScanner and Postfix

Now we can launch MailScanner and Postfix at the same time. Since the startup script for MailScanner also automatically launches Postfix, we'll tell Fedora not to separately launch Postfix and MailScanner.

Use these commands to configure Fedora to automatically launch MailScanner and Postfix together at startup and to start them now:

 chkconfig --del postfix service postfix stop chkconfig --add MailScanner chkconfig MailScanner on service MailScanner start 

We're up and running! Time to send some test messages.

Testing Our Front-End MTA

Our front-end MTA serves several purposes. We should test it in all three roles:

  • As an e-mail router that directs messages to the correct back end

  • As an anti-virus filter that strips out virus attachments

  • As a spam filter that marks spam for convenient filtering by clients .

Testing the Front-End MTA As an E-mail Router

Using an Exchange client such as Outlook on xppro1.ad.corp.com , send a test e-mail to nurse1@corp.com . This is the simplest way to test the front-end MTA from within the local area network. That's because the nurse1 account is not an Active Directory/Exchange account. It is an OpenLDAP account with a mailbox that lives on linserv1.corp.com .

If you have:

  • Correctly configured Exchange to forward messages for unrecognized addresses in corp.com to mail.corp.com

  • Correctly configured mail.corp.com to act as a front-end MTA

  • Verified that linserv1.corp.com has LDAP users

then the e-mail message should arrive at the Exchange server but be immediately forwarded to mail.corp.com (as Exchange cannot deliver it to anyone it knows about). mail.corp.com then recognizes it as a valid recipient on the linserv1.corp.com Linux Postfix server and delivers it there.

You can verify this by checking your e-mail with the IMAP client you configured in the "Linux as a Departmental Mail Server" section of this chapter.

Now let's try it in reverse! Just click "Reply" to that e-mail from your Active Directory/ Exchange user. The reply should arrive at the linserv1.corp.com Postfix server but be immediately forwarded to mail.corp.com . mail.corp.com then recognizes it as a valid recipient on the Exchange server and delivers it there.

You can verify this by checking your e-mail with the Outlook client on xppro1.ad.corp.com .

Troubleshooting E-mail Routing Problems

What if it doesn't work? Well, you have three MTAs: the Linux back end, the Linux front end, and the Exchange back end. Every one of them produces useful error logs that you can examine to learn more about the nature of the problem. For Exchange, take a look at the Application log in the Windows event viewer tool.

For the Linux MTAs, look at the file /var/log/maillog . Similar to /var/log/messages, /var/log/maillog contains errors, warnings, and event notifications specifically from MTAs and the POP/IMAP server. Use the tail command, as used in Chapter 4, to view the most recent entries in the file. That will give you the information you need to determine which of these categories the problem falls into:

  • If the Linux back end rejects messages for Exchange users Double-check the relay_recipient_maps option setting in /etc/postfix/main.cf on linserv1.corp.com and make sure that "Optional transport for unknown recipients" was set correctly in Webmin (or just set it as the fallback_transport option directly in /etc/postfix/main.cf ).

  • If the Exchange back end rejects messages for Linux users Make sure you followed the steps in the "Making Exchange Forward Mail It Cannot Process" section.

  • If the Linux front-end MTA rejects messages for either back end Make sure you followed the debugging suggestions at the end of the "Installing and Configuring the build-transport-maps.pl Script" section.

  • If messages get stuck on the mail.corp.com front-end server Double-check that you have fully configured ClamAV, SpamAssassin, and especially MailScanner. If MailScanner is not running, then mail will never move out of the hold queue and become eligible for delivery.

Even if all goes well in your tests, you may wish to examine /var/log/maillog on mail.corp.com to verify that you see indications of MailScanner scanning messages, as shown below:

 Apr  1 20:09:25 mail MailScanner[3724]: New Batch: Scanning 1 messages, 877 bytes  Apr  1 20:09:28 mail MailScanner[3724]:  Virus and Content Scanning: Starting Apr  1 20:09:30 mail MailScanner[3724]:  Requeue: 79ACFC1C0.2682C to 5E9F4C1DB Apr  1 20:09:30 mail postfix/qmgr[3626]: 5E9F4C1DB: from=<root@localhost.localdomain>, size=718, nrcpt=1 (queue active) Apr  1 20:09:30 mail MailScanner[3724]: Uninfected: Delivered 1 messages 

Testing the Front-End MTA As an Anti-Virus Filter

How can we verify that our anti-virus scanner is working properly? We could infect one of our workstations with a virus that generates outgoing virus e-mails. But to quote the European Institute for Computer Antivirus Research (EICAR), that's "rather like setting fire to the dustbin in your office to see whether the smoke detector is working." The results are meaningful, but the risks are not worth it.

Fortunately, there's a better way. EICAR, a nonprofit alliance of organizations concerned about computer viruses, offers a "test virus." The EICAR virus is a simple Windows executable called eicar.com , which just prints a message and exits.

Technically, of course, that means it's not a virus at all because it doesn't attempt to propagate itself. So what is the EICAR virus good for? Well, all good anti-virus scanners include the EICAR virus in their database of viruses to watch out for. And that means that a correctly configured anti-virus scanner should detect the eicar.com file and remove it when it is attached to an e-mail message. If your scanner detects eicar.com , it is correctly configured and should also detect known malicious viruses.

Let's try it out and see what happens! All we have to do is send a message from an Exchange user to a Linux user and attach a copy of the test virus file. That forces a round trip to mail.corp.com where the anti-virus scanner resides. Messages between Exchange users are immediately delivered by the Exchange server and don't see the anti-virus scanner. Similarly, e-mail messages between the departmental Postfix server are immediately delivered by the Postfix MTA. After all, the primary purpose of the anti-virus scanner is to detect viruses sent by users in the outside world.

Here are the steps to follow to test the ClamAV anti-virus scanner:

  1. Log on to the xppro1 workstation as salesperson1 .

  2. Temporarily disable any virus scanning software you might have installed on xppro1 .

  3. Using Internet Explorer, download the file www.eicar.org/download/eicar.com to xppro1 and save it to disk as eicar.com .

  4. Using Outlook, send an e-mail message to nurse1@corp.com , sending the file eicar.com as an attachment.

  5. Using an e-mail client configured to check the nurse1 account via POP or IMAP, check for new messages for nurse1 . The message should arrive after approximately one minute, without the virus attachment.

  6. Use the tail command to peek at the /var/log/maillog file on mail.corp.com . You should see output similar to the following:

     Apr  2 21:21:06 mail MailScanner[17816]: Virus and Content Scanning: Starting Apr  2 21:21:09 mail MailScanner[17816]: /var/spool/MailScanner/incoming/ 17816/./94A78C1C4.24FF5/eicar.com: Eicar-Test-Signature FOUND Apr  2 21:21:10 mail MailScanner[17816]:   Virus Scanning: ClamAV found 1 infections   Apr  2 21:21:10 mail MailScanner[17816]: Infected message 94A78C1C4.24FF5 came from 192.168.2.202 Apr  2 21:21:10 mail MailScanner[17816]: Virus Scanning: Found 1 viruses Apr  2 21:21:10 mail MailScanner[17816]:   Filename Checks: Windows/DOS     Executable (94A78C1C4.24FF5 eicar.com)   Apr  2 21:21:10 mail MailScanner[17816]: Other Checks: Found 1 problems Apr  2 21:21:10 mail MailScanner[17816]: Requeue: 94A78C1C4.24FF5 to DB63FC1EE Apr  2 21:21:10 mail postfix/qmgr[3626]: DB63FC1EE: from=<nurse1@corp.com>, size=1343, nrcpt=1 (queue active) Apr  2 21:21:10 mail MailScanner[17816]: Cleaned: Delivered 1 cleaned messages 
  7. Re-enable the anti-virus software on xppro1 , if any.

Congratulations, your anti-virus scanner is successfully removing virus attachments!

Note 

A one-minute delay to receive an e-mail message might reasonably make you wonder if MailScanner is fast enough. The answer is that MailScanner is capable of scanning many messages quickly in a single batch. While the delay before the scanning of a new batch begins is approximately one minute, MailScanner doesn't use a whole minute to scan each e-mail message.

If eicar.com is not correctly detected as a virus, consider the following issues:

  1. Did you install ClamAV?

  2. Did you edit /etc/MailScanner/virus.scanners.conf to enable the use of ClamAV?

Testing the Front-End MTA As a Spam Filter

We can use a similar method to test whether the spam-detection capabilities of SpamAssassin and MailScanner are operating properly. Quality spam detection software includes support for a special string of characters called the GTUBE (Generic Test for Unsolicited Bulk E-mail). Any e-mail message that contains this string of characters should be recognized as spam.

In our default configuration of MailScanner, that means your message will have added the following header line:

 X-  yoursite  -MailScanner-SpamCheck: spam, <  additional text, which varies>  

To see this additional header line, you will need to turn on display of all e-mail message headers in your e-mail client.

If you chose to set the "Spam Action" option in /etc/MailScanner/MailScanner.conf to delete , then messages containing the GTUBE should not be delivered at all.

Here are the steps to follow to test your anti-spam configuration with the GTUBE:

  1. Log on to the xppro1 workstation as salesperson1 .

  2. Using Outlook, send an e-mail message to nurse1@corp.com . You should include the following line in your e-mail:

     XJS*C4JDBQADN1.NSBN3*2IDNEN*GTUBE-STANDARD-ANTI-UBE-TEST-EMAIL*C.34X 

    You can also conveniently copy and paste the GTUBE from http://spamassassin.apache.org/gtube/ .

  3. Using an e-mail client configured to check the nurse1 account via POP or IMAP, check for new messages for nurse1 . The message should arrive after approximately one minute with the extra header identifying it as spam. If you set the Spam Action option in /etc/MailScanner/MailScanner.conf to delete , the message will not arrive at all.

  4. Use the tail command to peek at the /var/log/maillog file on mail.corp.com . You should see output similar to the following:

     Apr  2 22:15:18 mail MailScanner[18910]: New Batch: Scanning 1 messages, 1282 bytes Apr  2 22:15:19 mail postfix/smtpd[20459]: disconnect from unknown[192.168.2.203] Apr  2 22:15:20 mail MailScanner[18910]:  Spam Checks: Found 1 spam messages  

We have now verified that the spam-filtering capabilities of MailScanner and SpamAssassin are working properly.

If the GTUBE is not detected as spam, look into the following issues:

  1. Did you install SpamAssassin?

  2. Did you set "Use SpamAssassin" and "SpamAsssassin User State Dir" correctly in /etc/MailScanner/MailScanner.conf ?

  3. Did you type all the right characters of the GTUBE e-mail correctly? If you're unsure, copy and paste the e-mail found at http://spamassassin.apache.org/gtube/gtube.txt .



Windows and Linux Integration. Hands-on Solutions for a Mixed Environment
Windows And Linux Integration Hands-on Solutions for a Mixed Environment - 2005 publication.
ISBN: B003JFRFG0
EAN: N/A
Year: 2005
Pages: 71

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net