The two most widely used protocols on the Internet are http, hypertext transfer protocol (ie. the WWW) and smtp, simple mail transfer protocol (ie. email). We've just dealt with serving web content with Apache. Now we'll deal with managing an email system. The bulk of the behind-the-scenes email tasks are carried out by the MTA or mail transfer agent. This is the primary software working on a machine set up to be an email server. Your email client software (Evolution, Kmail, Mozilla's mail client, etc.) will send your email message to the MTA which will then send it out into the Internet and to its intended recipient. So, effectively, the MTA transfers your email message to another MTA, the one that handles the account of its recipient, which then stores it in a file known as a mailbox or a mail spool. Your recipient's client software will then request messages from the his/her server and the mail spool's contents will be transferred to his/her client's mailbox. That is essentially how email works in a nutshell. There can be other programs mixed in there as well. I personally use a program called fetchmail, which is a mail retrieval agent which just "picks up" my email and passes it through a program called procmail which filters it according to some rules I have created. Procmail places it in mailboxes and then I read it with a mail client called mutt. Then I compose mail with emacs and send it to Mutt which then sends it to the MTA. My system is really not the norm. The typical user will go through a simpler route - perhaps something like this: Evolution --> MTA (sender) --> MTA (recipient) <-- Evolution. As you can see, the objective is to keep this simple, so the burden is on you as the system administrator to make sure that it is. That, however, is not going to be simple for you. At the time of this writing, email is a battlefield filled with land-mines. Spam is the principal problem, but there are others. It's your job to make sure that the people in your organization can safely assume that their email is going to arrive at its destination. Sometimes that's easier said than done. Postfix MTA Postfix is a mail transfer agent created by Wietse Venema for IBM. Its principal virtues are that it's easy to administer and its pretty secure. I have also found that it plays very, very nicely with other complementary programs and you can use it to set up pretty elaborate email systems. I have used it to set up interesting email schemes for a few companies so they can offer email accounts to a large number of users without the need to have user accounts on the machine. You can set up Postfix to work with MySQL to keep track of the users and with Courier-IMAP to provide authentication for mail pickup. Though the configuration of the system like this is not difficult, it is not trivial either so we won't be dealing with it here. Information on how to set up a system like this is freely available on via how-tos on the Internet, if you're interested. Why not sendmail? sendmail is the oldest and most widely-used mail transfer agent. However, in the author's opinion it suffers from two flaws. One is that it is difficult to administer. The cryptic sendmail configuration file is just not a good place to be for the budding system administrator to be hanging out. Secondly, exploitable bugs are frequently found in it. That's why I've chosen to use Postfix as my mail transfer agent of choice. Postfix was developed around 1998, so Wietse Venema already had a pretty good idea about what nasty stuff could be done to a mail server. This is not to disparage the efforts of sendmail's developers. Being the most widely used MTA says a lot about it, or, as Spanish speakers say: quien tuvo retuvo. In the end, I think our teaching/learning interests are best served with Postfix. Installation of Postfix Most major Linux distributions offer the possibility to install Postfix, though in my experience, it is not the one installed by default. Debian prefers to install software that's licensed under the GPL. Postfix is not (it carries the IBM Public License), so you need to tell Debian's dselect installer that you want it instead of Exim, which is Debian's preferred MTA. RedHat will install Sendmail by default. Again, you need to adjust this either at install time or by removing Sendmail and substituting it with Postfix. Postfix configuration files Postfix places its configuration files in /etc/postfix. The main configuration file is appropriately namedmain.cf. You will be dealing primarily with this file to make changes in your Postfix configuration. What's nice about Posfix is that this configuration file is not particularly difficult to comprehend. The options are pretty straightforward. Here is a sample main.cf Code: # Do not change these directory settings - they are critical to Postfix # operation. command_directory = /usr/sbin daemon_directory = /usr/lib/postfix program_directory = /usr/lib/postfix smtpd_banner = $myhostname ESMTP $mail_name (Debian/GNU) setgid_group = postdrop biff = no # appending .domain is the MUA's job. append_dot_mydomain = no mydomain = domain.ork myhostname = mail.domain.ork alias_maps = hash:/etc/aliases myorigin = /etc/mailname mydestination = $myhostname, $mydomain, ,localhost relayhost = mynetworks = 192.168.0.0/16, 127.0.0.0/8 #mailbox_command = procmail -a "$EXTENSION" mailbox_size_limit = 0 recipient_delimiter = + As you can see, the first part tells you not to change the directory settings for where the program is. That's a good idea! Next you'll see a setting known as smtpd_banner. This is a mailserver's way of identifying itself to the outside world. Ours looks like this: Code: smtpd_banner = $myhostname ESMTP $mail_name (Debian/GNU) Here you'll see that we tell them who we are ($hostname). This is mandatory according to the SMTP specification. $mail_name is the name of our MTA (Postfix). Though Postfix is not configured to to this by default, we could add $mail_version between $mail_name and (Debian/GNU) to announce our Postfix version to the world. Postfix has its own user group, named postdrop, which you can see in the following line. After this, we have a line that we can change if you want postfix to pass notification to a 'biff' program that notifies when there is new mail. Let's go to the next section. There's a lot of brain-dead mailing software out there. Sometime it doesn't bother to check if you've put a proper From: address in your mail. There is also a lot of software that purposely doesn't do it. It's mostly used by people who don't want you to know who the mail's from. Yes, you guessed it - spammers! Hence, the comment at the beginning of this line. If you want to add your own domain to mail of this kind coming and going, just change the 'no' to 'yes'. Code: # appending .domain is the MUA's job. append_dot_mydomain = no The next lines are pretty self-explanatory: Code: mydomain = domain.ork myhostname = mail.domain.ork The next line: Code: myorigin = /etc/mailname is the contents of the file it mentions. This is normally the same as your hostname minus the host itself, or in our case, domain.ork. The next lines lets us handle mail for more domains. If you have to do that you can add them here: mydestination = $myhostname, $mydomain, trinkets.bis, ,localhost The next line: Code: relayhost = gives you the possibility of using the mail server on a machine for the sole purpose of sending mail to another mail server. The other server is the one that really sends it out into the Internet. This might be used in large organizations where there may be divisions of the company that work in remote locations with different types of Internet connection. There are cases where workers are accessing Internet from some type of broadband connection. If the mail were to go out directly, new anti-spamming techniques might tag this mail as spam (and often do!). This way, a branch office of an organization might configure Postfix to have a relay host which is at the main office with a permanent high-speed Internet connection. So you could use a hostname or IP address here as well. Code: relayhost = mail.parentco.con The 'mynetworks' setting is one of the most important. This is a list of IPs or hostnames that are allowed to use your mail server. In this day and age where spammers could put out signs inspired by McDonalds, bragging about 'billions served', then you've got to be extremely careful about this. If you're not an ISP, the setting below should be the only one you use, namely, your local network and the machine itself. You may also have a local network of 10.0.0.0/8 or 172.16.0.0/12. I just use the 192.168.0.0/16 out of habit. Code: mynetworks = 192.168.0.0/16, 127.0.0.0/8 In certain, very special circumstances you could add an IP or a host name here, but this would have to be a fixed IP or hostname of a trusted person. The potential for abuse of mail servers is enormous. I spoke to a system administrator who performed an experiment where he modified a script formmail.pl that once contained a flaw which is used a lot by spammers. The script he prepared appeared to be the flawed script but it actually never send any mails through it - it just logged the IP of spammers. Within 20 minutes of putting the script on a server, the first spammer tried it. By the end of the day, one spammer had tried to send over 200,000 messages through it. You can uncomment this line if you want the Postfix to pass received mail automatically through procmail filters before it is delivered. Code: #mailbox_command = procmail -a "$EXTENSION" We can also put a size limit on the our users' mailboxes. If you want to restrict your users to mailboxes of say, 200 MB, where disk space isn't a problem, you would use: Code: mailbox_size_limit = 200000000 (Sizes are in bytes). You could also add a line to restrict the size of mails that are allowed to be sent. This would restrict them to a 3MB limit. Code: message_size_limit = 3000000 The last line in our example: Code: recipient_delimiter = + is there to resolve some issues with mailing list software and is best left alone unless you run into problems with something that doesn't like it. That is a bare-bones example that will do all right on a simple mail server. You may want to tweak it a bit so that instead of just an "all right" job - it does a damn fine one! Let's look into some additional options. Anti-virus and anti-spam measures Viruses and spam are killing the "killer app" of the Internet, which is email. Individuals, business and organizations rely on it for communication but that reliability is fading fast. As a system administrator, you can do a lot in order to see that a good deal of spam and most viruses never reach any user. Here we are going to see a few examples of methods to block spam and viruses at the server level. Blocking viruses at the server I can't find a compelling reason why people should be sending email with potentially dangerous attachments and I personally think it's a good policy not to allow these mails to enter your server. After all, your server is either your property or it is the property of your employer and you're within your rights to restrict access to it. Postfix will perform a check on the body of the email message and it can either reject or quarantine mails with certain files attached to them. First, you need to have the Perl compatible regular expression (PCRE) package installed that works with Postfix. Postfix will use this package to parse the email messages for these nasty gifts that are sometimes included in them. First, we need to create a file with the expressions we are to look for. The file is normally called body_checks, so we know what we're doing with it. It will include lines like this: Code: /^(.*)name="(.*).vbs"$/ REJECT Mail contains banned attachment /^(.*)name="(.*).pif"$/ REJECT Mail contains banned attachment /^(.*)name="(.*).scr"$/ REJECT Mail contains banned attachment /^(.*)name="(.*).exe"$/ REJECT Mail contains banned attachment /^(.*)name="(.*).com"$/ REJECT Mail contains banned attachment /^(.*)name="(.*).lnk"$/ REJECT Mail contains banned attachment /^(.*)name="(.*).dot"$/ REJECT Mail contains banned attachment These are particularly notorious attachments. You may able to think up some of your own. What we have done here is reject these and send them back to where they came from with our reason for rejecting them. There's no need to get particularly verbose here. We've made our point. You may also skip the message and just silently reject it. If your company has a particular need to be receiving certain attachments that might be considered potential hazards, like *.zip files which after being unzipped can cause harm, you can also quarantine mails. Here's a sample rule: Code: /^(.*)name="(.*).zip"$/ HOLD The HOLD option will place mails in a security queue and you can deal with them later. You can then look at the hold queue with the postcat. Mail can then be deleted or passed on to its intended recipient with postsuper. You can save your body_checks file and place it in /etc/postfix. Now you need to open the main.cf file and add the following line: Code: body_checks = pcre:/etc/postfix/body_checks You can keep track of developments and add more rules as you see fit. Anti-spam measures with Postfix As mentioned before, the flood of Unsolicited Commercial Email, or "spam" is slowly killing the communication value of email. Until a replacement is found, all that we can do is use sandbags against the torrent. Luckily, it's fairly easy to implement anti-spam measures with Postfix. In the past, the use of poorly configured mail servers was the main way of moving spam around the Internet. That is becoming less and less of an option for spammers. Administrators are getting smarter and those open relays that are still left are quickly blacklisted. Spammers have essentially moved on to other forms, mostly illegal, to peddle their Viagra and male member enlargement schemes. It's still a good idea, though, to have Postfix query a spam blacklist server before it picks up the mail. Spam blacklists are a bit like religious denominations. There are fairly tolerant ones and then there are fire and brimstone fundamentalists. At times, legitimate domains have ended up on blacklists because of misconfiguration or even false reports. I have seen cases where people have forged IP addresses in mail headers to get a particular domain on a spam blacklist. Your tolerant blacklist maintainer will listen to reason. Then there are those who are run by the modern-day equivalent of Jonathan Edwards, who wrote Sinners in the Hands of an Angry God. A well-run open relay database will overlook mistakes and forgeries and get you quickly off their list. You should probably do some looking around on Usenet via Google to see if people are talking well or ill of a particular spam blacklist. I would avoid any that has the term 'Nazi' associated with it. The Open Relay Database - ordb.org is a well-known, free list of open relays. To use its services, add the following line to your main.cf Code: smtpd_client_restrictions = reject_rbl_client relays.ordb.org Other anti-spam measures.There are other ways besides open relay databases to try to keep spam from getting into your mail queues. Referring back to the introduction to this section, the new trend in spam is to plant trojans on unsuspecting broadband users Windows machines. These trojans have an SMTP engine incorporated into them to the cracked Windows box becomes a mail server under control of the spammer. Postfix is designed to try to differentiate between a normal user trying to send legitimate mail and a spammer doing anything he can to move his junk around the net. In order to separate the spam from the sirloin, you can add these to the end Code: your smtpd_client_restrictions = line smtpd_sender_restriction = reject_unknown_sender_domain, reject_non_fqdn_hostname, reject_non_fqdn_sender, reject_invalid_hostname Let's have a look at what these do. First, reject_unknown_sender_domain will reject any mail coming from a domain that doesn't have a registered MX DNS record. This means that the machine that this mail is coming from is not "authorized" (for lack of a better term) to send mail.reject_non_fqdn_hostname means that we will reject any server trying to connect to yours that doesn't identify itself as representing a Fully Qualified Domain Name. That is, some lousy spam spewer connects to your server and says: 'I am X.X.X.X' instead of 'I am mail.domain.com' and you tell it to take a hike. The nextone refers to the sender's address having an FQDN in the From: address. A lot of spam just flows out of horrendously made software that doesn't seem to be 'From' anybody. The last one makes sure that the mail comes from a valid domain. You can also add some anti-spam rules to your body_checks and add another line to our main.cf to do some Perl checks on the headers as well. First, let's add a line to main.cf Code: header_checks = pcre:/etc/postfix/header_checks Now we can create the corresponding file header_checks and add some rules to it. Code: /^Subject: FREE OFFER!!/ REJECT /^From: email@example.com/ REJECT /^X-Mailer:.*Some Spamware Tool/ REJECT These are probably the best headers to use in your anti-spam rules. If you keep adding to your header_checks and body_checks you will be able to get a handle on a lot of undesired mail. This is, of course, not 100% effective - but then again, nothing ever is. Other Postfix administrative tasks Using mail aliases It's very common for organizations to have aliases. Let's say you're doing system administration work at an accounting firm. Your firm announces that all queries having to do with tax filing should be sent to firstname.lastname@example.org. Now, you have a bright young intern named Bob Ledger who handles all these questions and he already has an account: email@example.com. There's no reason for Bob the intern to have to be monitoring two accounts. We can just create firstname.lastname@example.org as an alias for his personal account like so: First, there is a file in /etc called aliases. This is where we can define this alias for Bob. First of all, we would add a line in the file that looks like this: Code: taxes: bledger Now, we invoke the postalias program to add this to our alias database Code: postalias /etc/aliases As we can assume that Postfix is configured to handle the mail for the creativeacct.com domain, anything that comes for email@example.com gets bounced to Bob's mail spool. Then it would be up to Bob to configure his personal email program to filter these messages and deal with them as he sees fit. Removing mail from the queue At times, you may have to remove mail from the send queue. This normally happens when you send mail to some host that may have gone down for some period of time. Your mail logs will get cluttered up with periodic tries to re-send. If you see this and you really think the chances are slim that the mail is going to reach its destination, you can remove it from the queue. Each message has a unique queue-id. Here is an example: Code: Jan 15 13:01:30 mailserver postfix/smtp: 182D312D5F: to=<firstname.lastname@example.org>, relay=none, delay=375562, status=deferred (Name service error for hotnail.com: Host not found, try again) So, if you see messages that aren't going anywhere, then you can remove them from the queue using this ID number. First, shut down Postfix, to be safe. Then do the following Code: find /var/spool/postfix -name [queue-id] -print | xargs rm find will (pardon the redundancy) find the mail with that ID number and pass it along to be removed. Then restart Postfix again. Study, study and more study We have really only scratched the surface of what running an email server entails. It's now up to you to take this basic, general knowledge and improve your skills at handling such an important task as email management. There are thousands of pages dedicated to running Postfix more efficiently. I'd advise you to take a look at Postfix's documentation very closely before you attempt to set up a mail server of your own. Also, look at sample configurations that people have posted on their websites. You can get some really excellent ideas from them - ideas that will save you a lot of time and trouble.