Simple Mail Transfer Protocol (SMTP) is one of the more important services provided by the Internet. Almost all companies now have or rely upon email, and by extensions SMTP servers. There are many SMTP server packages available, the oldest and most tested is Sendmail (now commercially supported, etc.), and there are two new contenders, Postfix and Qmail, both of which were written from scratch with security in mind. Firewalling SMTP is straightforward, it runs on port 25, tcp:
ipfwadm -I -a accept -P tcp -S 10.0.0.0/8 -D 0.0.0.0/0 25 ipfwadm -I -a accept -P tcp -S some.trusted.host -D 0.0.0.0/0 25 ipfwadm -I -a deny -P tcp -S 0.0.0.0/0 -D 0.0.0.0/0 25
ipchains -A input -p tcp -j ACCEPT -s 10.0.0.0/8 -d 0.0.0.0/0 25 ipchains -A input -p tcp -j ACCEPT -s some.trusted.host -d 0.0.0.0/0 25 ipchains -A input -p tcp -j DENY -s 0.0.0.0/0 -d 0.0.0.0/0 25
Sendmail is another one of those services most of us have a love/hate relationship with. We hate to admin it and we'd love to replace it (actually I have started removing Sendmail from machines I admin and replacing it with Postfix).
Sendmail has earned itself a very bad reputation for security, however I find it hard to blame software when I find systems running ancient versions of Sendmail. The root of the problem (if you’ll pardon a bad pun) is that almost everyone runs Sendmail as root (and something like %70 of Internet email is handled by Sendmail machines, so there are a lot of them), so as soon as a bug is found, finding a system to exploit it on isn’t all that hard. The last few releases of Sendmail have been quite good, no root hacks, etc, and with the new anti spam features Sendmail is finally to come of age. More information on Sendmail and source code is available from: http://www.sendmail.org/.
Chroot'ing Sendmail is a good option, but a lot of work, and since it runs as root, rather debatable as to the effectiveness of this (since root can break out of a chroot'ed jail). I personally think switching to Postfix or Qmail is a better expenditure of effort.
Keeping Sendmail up to date is relatively simple, I would recommend minimally version 8.9.3 (the 8.9 series has more anti-spam features, 8.8.x has most of these features as well assuming you have a properly setup sendmail.cf). Most distributions ship 8.8.x, although the newer releases are generally shipping the 8.9.x. You can also get the source from ftp://ftp.sendmail.org/, but compiling Sendmail is not for the faint of heart or those that do not have a chunk of time to devote to it.
Sendmail only needs to be accessible from the outside world if you are actually using it to receive mail from other machines and deliver the mail locally. If you only want to run Sendmail so that local mail delivery works (i.e. a stand alone workstation, test server or other) and so mail can easily be sent to other machines, simply firewall off Sendmail, or better, do not run it in daemon mode (where it listens for connections). Sendmail can be run in a queue flushing node, where it simply 'wakes' up once in a while and processes local mail, either delivering it locally, or sending it off on its way across the 'net. To set Sendmail to run in queue mode:
edit your Sendmail startup script
and change the line that has:
sendmail -bd -q1h
Please note: if you use your system to send lots of email you may wish to set the queue flush time lower, perhaps “-q15m” (flush the queue every 15 minutes) now outbound and system internal mail will behave just fine, which unless you run a mail server, is perfect.
Now for all those wonderful anti-spam features in sendmail. Sendmail's configuration files consist of (this applies to Sendmail 8.9.x):
Primary config file, also tells where other config files are.
You can define the location of configuration files in sendmail.cf, typically people place them in /etc/ or /etc/mail/ (which makes it a little less cluttered).
Access list database, allows you to reject email from certain sources (IP or domain), and control relaying easily. My access file looks like this:
10.0.0 RELAY spam.com REJECT
which means 10.0.0.* (hosts on my internal network) are allowed to use the email server to send email to wherever they want, and that all email to or from *.spam.com is rejected. There are lists online of known spammers, typically they are 5-10,000 entries long, this can seriously impede sendmail performance (as each connection is checked against this list), on the other hand having your sendmail machine used to send spam is even worse.
aliases file, allows you to control delivery of mail local to the system, useful for backing up incoming user’s email to a separate spool. Most list serve software uses this file to get mail sent to lists delivered to the programs that actually process them. Remember to run the command “newaliases” after editing this file, and to then restart sendmail.
domain table (adding domains) that you handle, useful for virtual hosting.
configuration file for majordomo, I would personally recommend SmartList over Majordomo.
file containing names of hosts for which we receive email, useful if you host more then one domain.
location of help file (telnet to port 25 and type in "HELP")
Virtual user table, maps incoming users, i.e. maps firstname.lastname@example.org to email@example.com.
Sendmail 8.9.x (and previous versions) do not really support logging of all email very nicely (something required in today's world for legal reasons by many companies). This is one feature being worked on for the release of Sendmail 8.10.x. Until then there are 2 ways of logging email, the first is somewhat graceful and logs email coming IN to users on a per user basis. The second method is not graceful and involves a simple raw log of all SMTP transactions into a file, you would have to write some sort of processor (probably in Perl) to make the log useful.
Mail (incoming SMTP connections to be more precise) is first filtered by the access file, in here we can REJECT mail from certain domains/IP’s, and RELAY mail from certain hosts (i.e. your internal network of windows machines). Any local domains you actually host mail for will need to go into sendmail.cw. Assuming mail has met the rules and is queued for local delivery the next file that gets checked is virtusertable, this is a listing of email addresses mapped to the account name/other email address. i.e.:
firstname.lastname@example.org alias-seifried email@example.com listuser @seifried.org mangled-emails
The last rule is a catch all so mangled email addresses do not get bounced, and instead sent to a mailbox. Then the aliases file is checked, if an entry is found it does what it says to, otherwise it attempts to deliver the mail to a local users mailbox, my aliases file entry for seifried is:
alias-seifried: seifried, "/var/backup-spool/seifried"
This way my email gets delivered to my normal mailbox, and to a backup mailbox (in case I delete an email I really didn't mean to), or as a worst case scenario, Microsoft Outlook decides to puke someday and hose my mailboxes. This would also be useful for corporations, as you now have a backup of all incoming email on a per user basis, and can allow them (or not) to access the file containing the backed-up mail.
One caveat, when using a catch-all rule for a domain (i.e. @seifried.org) you must create an alias for EACH account, and for mailing lists. Otherwise when it looks through the list and doesn't find a specific entry (for say firstname.lastname@example.org) it will send it to the mailbox specified by the catch all rule. For this reason alone you might not wish to use a catch all rule.
The second method is very simple, you simply start sendmail with the -X option and specify a file to log all transactions to. This file will grow very large very quickly, I would NOT recommend using this method to log email unless you absolutely must.
Postfix is a mail transfer agent (MTA) aimed at security, speed, ease of configuration, generally things Sendmail fails miserably at. I would highly recommend replacing Sendmail with Postfix. The only portion of Postfix that runs as root is a master control program, aptly called “master”, it calls several other programs to process mail to the queue (“pickup”), a program to manage the queue, wait for incoming connections, deferred mail delivers and so on (“qmgr”), a program to actually send and receive the mail (“smtpd”) and so on. Each part of Postfix is very well thought out, and usually does one or two tasks, very well. For example instead of the sendmail model where queued mail simply gets dumped into /var/spool/mqueue, in Postfix there is a world accessible directory called “maildrop” which is checked by “pickup”, which feeds the data to “cleanup” which moves the mail (if it’s properly formatted and so on) to a secure queue directory for actual processing.
The primary configuration files are held in /etc/postfix, and there are several primary configuration files you must have:
Controls the behavior of the various “helper” programs, are they chroot’ed, maximum number of processes they may run and so forth. It’s probably best to leave the defaults on most mail servers unless you need to do some tuning for high loads or securing the server (i.e. chroot’ing it).
This file is as close to sendmail.cf as you’ll get (for purpose, as for layout it’s quite different). It is well commented and sets all the major variables, and the locations and format of various files containing information such as virtual user mappings and related information.
Here is a list of variables and file locations you will typically have to set, the /etc/postfix/main.cf file is usually heavily commented. Please note the following examples of main.cf entries are not a complete main.cf.
# what is the machines hostname? myhostname = mail.example.org
# what is the domain name? mydomain = example.org
# what do I label mail as “from”? myorigin = $mydomain
# which interfaces do I run on? All of them usually. inet_interfaces = all
# a file containing a list of host names and fully qualified domains names I # receive mail for, usually they are listed like: # mydestination = localhost, $myhostname, etc # but I much prefer to keep them listed in a file. mydestination = /etc/postfix/mydestination
# map of incoming usernames. “man 5 virtual” virtual_maps = hash:/etc/postfix/virtual
# alias mappings (like /etc/aliases in sendmail), “man 5 aliases” alias_maps = hash:/etc/postfix/aliases
# alias database, you might have different settings. “man 5 aliases” alias_database = hash:/etc/postfix/aliases
# where to deliver email, Mailbox format or Maildir (traditional /var/spool/mail). home_mailbox = Maildir/
# where to keep mail, usually /var/spool/mail/ but you can easily change it mail_spool_directory = /var/spool/mail
# what command do we use to deliver email? /usr/bin/procmail is the default but if # you want to use scanmail which is the AMaViS anti-virus tie in software simply put: mailbox_command = /usr/sbin/scanmails
# who do I relay email for, again you can list them, or keep them in a file (one # per line). relay_domains = /etc/postfix/relaydomains
# list of local networks (by default we relay mail for these hosts). mynetworks = 10.0.0.0/24, 127.0.0.0/8
# what do we display to people connecting to port 25? By default it displays the # version number which I do not. smtpd_banner = $myhostname ESMTP $mail_name
Generally speaking any files that simply list one item per line (like /etc/postfix/mydestination or /etc/postfix/relaydomains) are usually just stored as a flat text file. Files that contain mappings (i.e. aliases, where you have entries like “root: someuser”) should be turned into hashed database files for speed (you can specify the type of file as hash, dbm, etc.).
Like most IBM products, Postfix has a very funky license, but appears to be mostly open source and free. Postfix is available at: http://www.postfix.org/. You can binary postfix packages from:
Sendmail Pro is a commercial version of Sendmail with support, and is available at: http://www.sendmail.com/. I haven’t been able to get a demo or find anyone using it so I’m not 100% sure as to how close it is to the “original” Sendmail, although the company has told me it uses the same code base.
Qmail (like postfix) was created as a direct response to perceived flaws in Sendmail. Qmail is GPL with a no binary distribution clause meaning you must install it from source code. Very little code in Qmail runs as root, and it is very modular compared to Sendmail (which is a pretty monolithic piece of code). You can download it from: http://www.qmail.org/.
Zmailer is a GPL mailer available at: http://www.zmailer.org/. It has crypto hooks and generally looks like it is well built.
DMail is a commercial mail server, and is not open source. You can download a trial version from: http://netwinsite.com/dmail_first.htm.
nullmailer sends mail to smart hosts (relays) so that the local machine doesn't have to run any mail server software. It's at: http://em.ca/~bruceg/nullmailer/.
MasqMail queues mail while offline and then sends it when you connect to your ISP. It can be configured for multiple ISP's with return addresses and so on. You can download it at: http://merlin.uni-sw.gwdg.de/~okurth/masqmail/.
Dynamic Relay Authorization Control
Dynamic Relay Authorization Control (DRAC) ties into your POP/IMAP server to temporarily grant SMTP relay access to hosts that successfully authenticate and pick up mail (the assumption being these hosts will send mail, and not abuse this privilege. You can get it from: http://mail.cc.umanitoba.ca/drac/index.html.
WU IMAPD (contains the default popd for most distros)
POP and IMAP are fundamentally related but very different, so I have split them apart. POP stands for “Post Office Protocol” and simply allows you to list messages, retrieve them, and delete them. There are many POP servers for Linux available, the stock one that ships with most distributions if ok for the majority of users. The main problems with POP are similar to many other protocols; usernames and passwords are transmitted in the clear, making it a very good target for packet sniffing. POP can be SSL’ified, however not all mail clients support SSL secured POP. Most POP servers come configured to use TCP_WRAPPERS, which is an excellent method for restricting access. Please see the earlier section on TCP_WRAPPERS for more information. POP runs as root (since it must access user mailboxes) and there have been a number of nasty root hacks in various POP servers in the past. POP runs on ports 109 and 110 (109 is basically obsolete though), using the tcp protocol. The Washington University IMAPD server also comes with a pop server and is generally the ‘stock’ pop server that ships with most Linux distributions. You can get it from: http://www.washington.edu/imap/.
ipfwadm -I -a accept -P tcp -S 10.0.0.0/8 -D 0.0.0.0/0 110 ipfwadm -I -a accept -P tcp -S some.trusted.host -D 0.0.0.0/0 110 ipfwadm -I -a deny -P tcp -S 0.0.0.0/0 -D 0.0.0.0/0 110
ipchains -A input -p tcp -j ACCEPT -s 10.0.0.0/8 -d 0.0.0.0/0 110 ipchains -A input -p tcp -j ACCEPT -s some.trusted.host -d 0.0.0.0/0 110 ipchains -A input -p tcp -j DENY -s 0.0.0.0/0 -d 0.0.0.0/0 110
Cyrus is an imap (it also supports pop and kpop) server aimed at ‘closed’ environments. That is to say that the users will not have any access to the mail server other then by imap or pop protocols. This allows Cyrus to store the mail in a much more secure manner and allows for easier management of larger installations. Cyrus is not GNU licensed but is relatively “free”, and available from: http://andrew2.andrew.cmu.edu/cyrus/imapd/. There is also a set of add on tools for Cyrus available from: ftp://ftp.hr.vc-graz.ac.at/cyrus-tools/.
IDS (It Doesn’t Suck) POP is a lighter popd replacement aimed at smaller installations. It is GPL and available from: http://www.nodomainname.net/software/ids-pop/.
A pop daemon written to be small and fast, GNU licensed. Available from: http://www.nodomainname.net/software/gnu-pop3d.shtml.
Qpopper is freeware produced by Qualcomm (the makers of Eudora). I would not recommend it (the source code is not available). You can get it from: http://eudora.qualcomm.com/freeware/qpop.html.
WU IMAPD (contains the default imapd for most distros)
IMAP is POP on steroids. It allows you to easily maintain multiple accounts, have multiple people access one account, leave mail on the server, just download the headers, or bodies and no attachments, and so on. IMAP is ideal for anyone on the go or with serious email needs. The default POP and IMAP servers that most distributions ship (bundled together into a single package named imapd oddly enough) fulfill most needs.
IMAP also starts out as root, although imapd typically drops to the privilege of the user accessing it, and cannot be easily set to run as a non-root user since they have to open mailboxes (and in IMAP’s case create folders, files, etc. in the user’s home directory), so they cannot drop privileges as soon as one would like. Nor can they easily be chroot'ed (IMAP needs access to /var/spool/mail, and IMAP needs access to the user’s home directory). The best policy is to keep the software up to date. And if at all possible, firewall pop and imap from the outside world, this works well if no-one is on the road and needs to collect their email via the Internet. Washington University (WU) IMAPD is available from: http://www.washington.edu/imap/.
IMAP runs on port 143 and most IMAPD servers support TCP_WRAPPERS, making it relatively easy to lock down.
ipfwadm -I -a accept -P tcp -S 10.0.0.0/8 -D 0.0.0.0/0 143 ipfwadm -I -a accept -P tcp -S some.trusted.host -D 0.0.0.0/0 143 ipfwadm -I -a deny -P tcp -S 0.0.0.0/0 -D 0.0.0.0/0 143
ipchains -A input -p tcp -j ACCEPT -s 10.0.0.0/8 -d 0.0.0.0/0 143 ipchains -A input -p tcp -j ACCEPT -s some.trusted.host -d 0.0.0.0/0 143 ipchains -A input -p tcp -j DENY -s 0.0.0.0/0 -d 0.0.0.0/0 143
Cyrus is an imap (it also supports pop and kpop) server aimed at ‘closed’ environments. That is to say that the users will not have any access to the mail server other then by imap or pop protocols. This allows Cyrus to store the mail in a much more secure manner and allows for easier management of larger installations, and I highly recommend it. Cyrus is not GNU licensed but is relatively “free”, and available from: http://andrew2.andrew.cmu.edu/cyrus/imapd/. There is also a set of add on tools for Cyrus available from: ftp://ftp.hr.vc-graz.ac.at/cyrus-tools/.
Scanning email for viruses
AMaViS uses third party scanning software (such as McAfee) to scan incoming email for viruses. You can get AMaViS at: http://aachalon.de/AMaViS/. Make sure you get the latest version, previous ones have a root compromise. As of July 19 the latest is: http://aachalon.de/AMaViS/amavis-0.2.0-pre5.tar.gz.
Using AMaViS with Sendmail is relatively simple, it has a program called “scanmail” that acts as a replacement for procmail (typically the program that handles local delivery of email). When an email comes in instead of using procmail to deliver it, Sendmail calls scanmail which decompresses and decodes any attachments/etc. and then uses a virus scanner (of your choice) to scan the attachments. If no virus is found mail delivery goes ahead as usual. If a virus is found however, an email is sent to the sender informing them that they have sent a virus, and an email is sent to the intended recipient informing them about the person that sent them a virus. The instructions for this are at:
Since Postfix can make use of procmail to do local mail delivery it should work in theory without any trouble. In practice it takes a few minor tweaks to work correctly. To enable it replace the line in main.cf:
mailbox_command = /usr/bin/procmail
with the line:
mailbox_command = /usr/sbin/scanmails
and restart postfix. For the local warning to work (a warning is sent to the intended recipient of the message) the hostname of the machine (sundog, mailserver01, etc.) must be listed in the “mydestination” in main.cf, otherwise the warning does not get delivered. You should (and most sites generally do) redirect root’s email to a user account using the aliases file, otherwise warnings will not be delivered to root properly. By default as well mail to “virusalert” is directed to root, you should also redirect this mail to a normal user account.