![]() Setting Up a high performance IMAP serverThe aim of this article is to describe how to configure a reliable and high performance email server for a 5-100 employees company. The constraint here is not to send/receive millions of messages a day but to allow users to keep their emails on the server and use IMAP to retrieve them from wherever they are, and for however long they want to keep them. This type of server is particularly suited for companies whose employees deal with a lot of emails, such as an Engineering, Project Management or a Law firm. ObjectivesThe basic objective of this project is to enable authorised users to securely send, retrieve and manage lots of emails from anywhere. Security is enforced from different angles:
Additionally, the technical objectives are:
ImplementationFor this project, I chose the following implementation:
AssumptionsIn this document, the FQDN? (Fully Qualified Domain Name) of the server is also its hostname mail.example.com and its domain name is thus example.com. I assume that you have setup a MX DNS record for mail.example.com and that mail sent to joe@example.com will be attempted to be delivered to the server we're setting up. This setup is meant for a company wanting to host its own email server, so the focus is on single domain only. If you want to manage mupltiple domains, you will have to adapt this setup. Note: if you need to setup your domain name and take control of your email, I suggest that you take an account with ZoneEdit: the first 5 zones are free, and extra services are quite cheap. You have total control over you domains, subdomains, and can of course create Mail eXchange records. They also have a service to buffer your email should your server be offline. when things return to normal, any email they kept will be delivered as usual. In the whole insallation and configuration process, I assume that you are logged in under the InstallationThe initial installation process is not critical here. Simply avoid installing too much stuff that you don't need (like X, Gnome or KDE and anything graphical) and limit the number of services that run on the server. It's easy enough to add missing packages afterwards. Buy your hard-drives in double or triple and mount your partitions as RAID1 or RAID5 arrays: this is quite critical as it means that you won't lose everything if one of the drives fails. I won't discuss backup solutions for this system, but you should have one. In the future, I plan to describe a mail to database solution that could be used as a specific mail backup/archiving/retrieval system. When deciding your disk partitions, allow a rather large one that you will mount as During the installation process, make sure that you choose After you've rebooted, use Check partition indexesBy default, Fedora Core 4 uses indexes when creating Why are indexes so important you ask? It doesn't hurt to double check that our partition supports indexes. Let's suppose that your tune2fs -l /dev/hda3 | grep features You should see a reference to umount /dev/hda3 tune2fs -O dir_index /dev/hda3 e2fsk -fD /dev/hda3 mount /dev/hda3 If your system complains about not finding This bit was taken from the Dovecot site.
UsersThere are plenty of different ways to authenticate users for mail access. Using LDAP, virtual users, MySQL databases, NIS, SMB or any other scheme is of course possible but in our case I wanted to keep things simple and allow this server to later become say a file server as well without too much hassle. Changing the authentication scheme can be necessary if you're managing virtual email accounts with lots of different domains (if you're and ISP for instance). Having said that, there are a few of drawbacks to using standard user accounts:
I will assume that all our users will not need to login onto the machine by default. If you need such users, you can still override these settings. Edit the # useradd defaults file GROUP=100 HOME=/mail INACTIVE=-1 EXPIRE= SHELL=/bin/nologin SKEL=/etc/skelmail Note: the normal way of doing this is to use Now create the skeleton directory: # mkdir -p /etc/skelmail/email/{cur,new,tmp} # chmod 700 -R /etc/skelmail/email Now, whenever we use the Note: It's very important that the email folder is not world-accessible: Postfix will otherwise refuse to write any email in it as it would be a security hazard. That's why we set it to Should you need to add normal login users accounts, you can override the default settings of # adduser -m -k /etc/skel -s /bin/bash -d /home/susan susan Will add the normal login user susan to the system.
Switch to PostfixWe need to switch from the To switch, do the following: # yum -t install postfix # yum -t install system-switch-mail # /usr/sbin/system-switch-mail The first 2 You will be presented with a choice on screen, go for Configuring Postfix
Let's first make a backup copy of these config files, just in case: # cp master.cf master.cf.ORIGINAL # cp main.cf main.cf.ORIGINAL main.cf parametersNow, edit the myorigin = $mydomain This says that mail sent from your server will take the form xxx@example.com. Note that by default, $myhostname and $mydomain are automatically derived from your machine's name. This name should be a Fully Qualified Domain Name (FQDM) like mail.example.com. mydestination = $myhostname localhost.$mydomain localhost $mydomain Defines which domains you want to receive mail for. We should always allow the variations of localhost so the server can accept mail sent to itself, and $myhostname and $mydomain ensure that you will get mail sent to both mail.example.com and example.com. mynetworks_style = subnet Allows people on the local network to be able to use the server to relay their emails. People from outside the subnet (outside of the IP addresses defined by your network's netmask, such as 255.255.255.0) will not be able to use the server to send email. This is safe, you never want unknown people from the Internet to be able to relay their mail through your server: it would only take a few minutes for your machine to become a spam hub. relay_domains = $mydestination Authorises people from the outside to send email that is supposed to be for us. notify_classes = resource, software Defines what sort of information should be sent to the postmaster when there is a problem. There are more options to that, but using too many could flood your mailbox. relayhost = Confirms we're not using any external relays as we want the server to deliver our emails directly to other servers. If your ISP doesn't let you send emails by yourself (some block port 25), then you can put their own email server there [mail.isp.com] (including the brackets). Any mail you sent through your server will be given to your ISP's email server for delivery. Note that this is not very reliable as ISP have usually no guarantee that your email will be delivered to its destination: you're in effect sending your mail through a black hole. proxy_interfaces = 1.2.3.4 Is only needed if your server is not directly connected to the Internet but is for instance behind a firewall that uses Port Forwarding to redirect traffic to it on a local subnet (for instance, your server address is 192.168.0.1 or another reserved LAN IP Class). In that case, you have to tell Postfix what is the outside address of the mail server (replace 1.2.3.4 by whatever is your real IP). Note though that if you don't have a fixed IP, this can be a bit annoying and you may be better off with connecting the server directly to the Internet and using iptables as a good internal firewall. inet_interfaces = all Makes Postfix listen to all interfaces for email. message_size_limit = 20971520 Limits the size of emails. Here we set it to 20MB which should be more than enough for most systems. It's a good idea to set a limit. I've have users trying to send 150MB emails to people who only had a dial-up connection (since delivery to the server from the local network is fast, people tend not to notice much the size of the emails they send). masquerade_domains = $mydomain Ensures that mail from other hosts being sent through the server gets rewritten with our domain name correctly appended. this means that if elise@accounts.example.com sends an email through the server, it will be rewritten as elise@example.com. mail_name = MyOwnPostOffice Optional and replaces the default name returned by Postfix. It's not a bad idea to replace the default string as it is par of the messages exchanged every time an email is being delivered. Potentially, it could allow someone to use that information to exploit a known security hole (the default string contains the full version number of Postfix). home_mailbox = email/ If that directive is present, it will tell Postfix to deliver messages to the Note: you do not need to create the directories: Postfix will do that for you if they don't exist. SASL AuthenticationAs we've discussed before, ensuring that your server is locked down is vital if you don't want to become the next spam relay. SASL is a way of authenticating users when they are trying to send mail. It uses a variety of methods and it's fairly flexible, at the expense of being simple. To ensure proper SASL authentication, add the following to your smtpd_sasl_auth_enable = yes broken_sasl_auth_clients = yes smtpd_recipient_restrictions = permit_mynetworks permit_sasl_authenticated reject_unauth_destination reject_invalid_hostname reject_unknown_sender_domain The first line enables authentication for email being sent through the server from the outside (allowing roaming users to send email from the Internet). For security reasons, Postfix runs as an unprivileged user, meaning that it doesn't have access to your password files. Fortunately, this is already installed on Fedora and probably on most distributions as well. Just to be sure, do the following from the prompt: # yum -t install cyrus-sasl # chkconfig saslauthd --levels 235 on There is nothing else to do: the default configuration takes care of everything. pwcheck_method: saslauthd mech_list: plain login Note: on other Linux systems, this file may be missing or may be located under AliasesThe minimum alias that must be set-up is for the postmaster who will receive errors and warnings issued by Postfix: Edit postmaster: administrator root: administrator The administrator user must have been created and you should probably the one using that account regularly to check for issues. Note: after every modification of the alias file, you must run To add more aliases, just add them to
suzan.smith: susan s.smith: susan suzansmith: susan ssmith: suzan smith.suzan suzan accounts: boss marketing: boss sales: boss joe.doe boss joedoe boss Don't forget to run Virtual mapAliases are ok, but not very powerful, especially if you're hosting multiple domains and want a mail sent to sales@example.com be redirected to john while a mail to sales@myhome.com should go to suzan. In that case, edit the suzan.smith: susan@example.com s.smith: susan@example.com suzansmith: susan@example.com ssmith: susan@example.com smith.suzan susan@example.com sales@example.com: suzan@example.com sales@myhome.com: john@example.com @example.com: john@example.com Here, anything sent to any variation of Susan's email address will be redirected to Susan's account, regardless of the domain they were sent to: s.smith@example.com and s.smith@myhome.com will be dropped into Susan's mailbox. For email sent to sales, Suzan will be the recipient for example.com and John for myhome.com. Any other email sent to invalid addresses (one that does not have a defined account, alias or virtual entry defined on the system) at example.com will be sent to John. This is a catch-all definition, but it is generally preferable to use a separate account for it as it will receive all spam sent to the servers to accounts that do not exist. After editing After any change it's also a good idea to run
Dovecot for POP3 and IMAPDovecot is a good and flexible POP3 and IMAP mail server. It is very performing and can manage large amounts of emails. If you haven't got it on your system, you can build it from source or just use the ubiquitous yum: # yum install dovecot # chkconfig dovecot --levels 235 on First, we need to tell Dovecot where to fin our emails: as you remember, we told Postfix to use maildirs in the user directories instead of the default mbox. Edit the protocols = imap imaps pop3 pop3s ssl_disable = no ssl_cert_file = /etc/pki/dovecot/certs/dovecot.pem ssl_key_file = /etc/pki/dovecot/private/dovecot.pem protocol imap { imap_max_line_length = 65536 login_greeting_capability = yes imap_client_workarounds = outlook-idle netscape-eoh } protocol pop3 { pop3_uidl_format = %08Xu%08Xv pop3_client_workarounds = outlook-no-nuls oe-ns-eoh } default_mail_env = maildir:/mail/%u/email mail_full_filesystem_access = no Restart Dovecot ( SSL for IMAP and POPIn the older article for Fedora Core 4 we used stunnel to encrypt our seucred POP and IMAP channels. You can access that article on the SecureAccess page where we still use stunnel for securing email we send to the server.. To change a bit, we're going to follow Dovecot standard configuration and allow it to use SSL directly for POP3S and IMAPS. First, remove the existing cert files, we're going to replace them later: # rm /etc/pki/dovecot/certs/dovecot.pem Then edit the [ req ] default_bits = 1024 encrypt_key = yes distinguished_name = req_dn x509_extensions = cert_type prompt = no [ req_dn ] # country (2 letter code) C=HK # State or Province Name (full name) ST=Hong Kong # Locality Name (eg. city) L=Central # Organization (eg. company) O=ACME Publishing Ltd # Organizational Unit Name (eg. section) OU=Main Office # Common Name (*.example.com is also possible) CN=mail.example.com # E-mail contact emailAddress=postmaster@example.com [ cert_type ] nsCertType = server Now we need to correct the small script that the dovecot people have nicely provided to generate the key. ... SSLDIR=${SSLDIR-/etc/pki/dovecot} ... Now all we need is to run it. # /usr/share/doc/dovecot-1.0/examples/mkcert.sh That's it, you should now be able to connect to the server after configuring your client to use SSL.
Installing Amavisd-NewAmavisd is a mail filtering interface that allows an MTA such as Postfix to talk to specialzed external add-ons such as SpamAssassin or ClamAV amongst others. On its own, it doesn't do anything useful, but it will make our anstispam and antivirus tools work well together. First thing to do is to add a user for running Amavisd-New: # useradd -c "amavisd-new daemon" -u 999 -M -s /bin/false amavis # mkdir -p /var/amavis/{tmp,var,db} # chown amavis.amavis -R /var/amavis # chmod 750 /var/amavis # mkdir /var/virusmails # chown amavis.amavis /var/virusmails # chmod 750 /var/virusmails We make sure that the user is unpriviledged and that its home directory is under Now install Amavisd-New by doing the following from the command line (check the latest version number of Amavisd-New and replace it, this is just an example): # cd /usr/local/src/ # wget http://www.ijs.si/software/amavisd/amavisd-new-2.3.2.tar.gz # tar xzvf amavisd-new-2.3.2.tar.gz # cd amavisd-new-2.3.2 # cp amavisd /usr/local/sbin/ # chmod 755 /usr/local/sbin/amavisd # cp amavisd.conf /etc/ # chmod 644 /etc/amavisd.conf To manage Amavisd-New like any other service, do the following: # cp /usr/local/src/amavisd-new-2.3.2/amavisd_init.sh /etc/init.d/amavisd # chmod 744 /etc/init.d/amavisd # ln -s /usr/local/sbin/amavisd /usr/sbin/amavisd # chkconfig --add amavisd # chkconfig --levels 235 amavisd on Now we can use Since Amavisd-New is written in Perl and is built aupon the work of many other individuals, we need to install some prerequisites: # perl -MCPAN -e shell
The first time you use this command, you will be prompted with a number of questions about your system. Just keep reading and answering, but most -if not all- of the time, just pressing Enter will use an appropriate default. At the Perl shell prompt, type the long line of prerequisites for Amavisd-New: cpan> install Archive::Tar Archive::Zip Compress::Zlib Convert::TNEF Convert::UUlib MIME::Base64 MIME::Parser Mail::Internet Net::Server Net::SMTP Digest::MD5 IO::Stringy Time::HiRes Unix::Syslog BerkeleyDB You can of course break that into multiple Now we need to make sure that some other optional software needed by Amavisd-New is correclty installed on our machine (they are used to extract content in archived attachments): # yum -t install unarj # yum -t install unrar # yum -t install cabextract # yum -t install Configuring Amavisd-NewConfiguring Amavisd-New is simply a matter of editing its $max_servers = 5; $daemon_user = 'amavis'; $daemon_group = 'amavis'; $mydomain = 'example.com'; $MYHOME = '/var/amavis'; Here we tell Amavisd-New that it will be running under the @local_domains_maps = ( [".$mydomain", "example2.com", "example3.com"] ); If you are scanning mail for more than one domain, list them in here. $max_servers = 5; This tells Amavisd-New to always fork 5 children waiting for our mails. This means that, at any time, we'll be able to process 5 emails simultaneously. If you don't have much RAM, you can lower this figure to Ensures that we always get X-Spam-Status and X-Spam-Level in our email headers, whatever the spam score, that anything above a spam score (see SpamAssassin) will be flagged as spam. $sa_spam_subject_tag = '[SPAM] '; This is what will be shown in the subject of an email detected as spam. $final_virus_destiny = D_DISCARD; We will quarantine messages containing viruses so they are not delivered to the user (when our antivirus will be installed). @bypass_virus_checks_maps = (1); We also disable virus checking for now because we haven't installed the antivirus yet and Amavisd-New will not let mail through if this option is disabled and there is no Antivirus. $final_banned_destiny = D_BOUNCE; $banned_filename_re = new_RE( qr'\.[^./]*[A-Za-z][^./]*\.(exe|vbs|pif|scr|bat|cmd|com|cpl|dll)\.?$'i, qr'^application/x-msdownload$'i, qr'^application/x-msdos-program$'i, qr'^application/hta$'i, [ qr'^\.(rpm|cpio|tar)$' => 0 ], [ qr'^\.(zip|rar|arc|arj|zoo)$'=> 0 ], qr'.\.(ade|adp|app|bas|bat|cmd|com|cpl|crt|exe|fxp|grp|hlp|hta| inf|ins|isp|js|jse|lnk|mda|mde|mdw|mdt|mdz|msc|msp|mst| ops|pcd|pif|prg|reg|scr|sct|shb|shs|vb|vbe|vbs| wsc|wsf|wsh)$'ix, qr'.\.(mim|b64|bhx|hqx|xxe|uu|uue)$'i, qr'^\.(exe-ms)$', ); Here we make sure that emails containing attachments with banned extensions get bounced. While we'll probably end up trying to bounce viruses and spam, it's better to use this option to let legitimate senders who are sending us banned attachements that their messages did not get through. We now have a couple of choices: sending our spam to the user with the modified subject line, or quarantine the message by sending it to a special user account. Basic setup: spam email sent to userThe most basic setup is to let the user deal with the spam. The good thing about that is that they can judge if there is a false positive, and can still separate the spam by using filters in their mail clients to automatically move marked spam to a local folder. In $sa_kill_level_deflt = 10000; This will make Amavisd-New ignore any action for spam scores below this figure, which is normally beyond the highest possible spam score. Advanced setup: quarantine to a special accountIf instead of cloggin the users with spam messages we want to move them to a special user account on the server, we need to modify the following in $sa_kill_level_deflt = 6.31; $final_spam_destiny = D_DISCARD; Edit your virusalert : administrator spam.police : administrator Again, don't forget to rebuild the aliases database with Configuring Postfix to use Amavisd-NewNow we need to let postfix know about Amavisd-New. Postfix communicates with external programs through TCP/IP ports. This method allows a clear separation of processes and their priviledges as each is running under its own account. Edit the smtp-amavis unix - - y - 5 smtp -o smtp_data_done_timeout=1200 -o smtp_send_xforward_command=yes -o disable_dns_lookups=yes 127.0.0.1:10025 inet n - y - - smtpd -o content_filter= -o local_recipient_maps= -o relay_recipient_maps= -o smtpd_restriction_classes= -o smtpd_helo_restrictions= -o smtpd_sender_restrictions= -o smtpd_recipient_restrictions=permit_mynetworks,reject -o mynetworks=127.0.0.0/8 -o strict_rfc821_envelopes=yes -o smtpd_error_sleep_time=0 -o smtpd_soft_error_limit=1001 -o smtpd_hard_error_limit=1000 -o receive_override_options=no_header_body_checks Note: if you reduced the number of And edit content_filter = smtp-amavis:[127.0.0.0]:10024 Amavisd-New White and Black listsIf you want to make sure that some addresses always get through and that some always get banned, you will need to create a white list and a black list. # touch /var/amavis/white.lst # touch /var/amavis/black.lst # chown amavis.amavis -R /var/amavis/ You need to make Amavisd-New know about those files. Edit @whitelist_sender_maps = read_hash("$MYHOME/white.lst"); @blacklist_sender_maps = read_hash("$MYHOME/black.lst"); Now simply add each email address you want to unconditionnaly allow (white list)/block (black list) on a single line inside the relevant file. OK, now we're ready to install the antispam and antivirus that will make use of Amavisd-New.
SpamAssassinSpamassassin is a very versatile and complete spam fighting solution. It uses statistical techniques as well as external blacklist and can be configured to use add-on tools to make its detection more refined. SpamAssassin uses a rating system whereby each email goes through a list of tests and the mail is flagged for every positive test, increasing the number of spam points it is allocated. Each test allocates a variable number points or fraction of a points depending on how useful and reliable it is at detecting spam. Once the email has gone through all the tests have been performed an action is taken based on the total number of points: if the score is high enough, we're sure that this is spam, if not, we can let the message through. To install SpamAssassin, just use # yum -t install spamassassin Edit the bayes_path /var/amavis/.spamassassin/bayes auto_whitelist_path /var/amavis/.spamassassin/auto-whitelist lock_method flock trusted_networks 1.2.3.4 internal_networks 1.2.3.4 The last 2 lines are only necessary if your server is using NAT to hide being a firewall and has a local LAN address: you need to tell SpamAssassin about it or it might consider as trusted emails coming from the outside. Change the Now we need to make some changes to ensure that what we do as # spamassassin --lint -D # cp -ir /root/.spamassassin /var/amavis # cd /root/.spamassassin/ # rm -f user_prefs # ln -s /var/amavis/.spamassassin/user_prefs user_prefs # chown -R amavis.amavis /var/amavis Now, make sure SpamAssassin will run when we boot: # chkconfig --levels 235 spamassassin on # service spamassassin start Initialise the Bayesian database: # sa-learn --sync Test our config by running: # amavisd debug-sa If what you did above was done properly, you should see debug: using "/var/amavis/.spamassassin/user_prefs" for user prefs file in the middle of all those spewed by Amavisd-New (scroll back or use Shift+PageUp keys). Testing antispamJust send an email with the following in the body: This is a standard fake spam signature used to test antispam software. You should get the email with the Baysian filteringSpamassassin includes a powerful statistical analysis that can help toward refining the score given to emails passing through it. The only drawback with baysian analysis is that it needs a set of good (ham) and bad (spam) emails large enough to be accurate, and you need to sort these emails and manually train spamassassin. To avoid any aggravation, I created a simple MissedSpam folder in one of the IMAP mail accounts that I use. I then simply have to move any spam that made its way to an inbox into that folder. To train spamassassin as to what is spam and what is ham, make sure you have enough segregated emails (between 150-3000) in each mailbox being trained then issue the following: # sa-learn --spam --sync /mail/postmaster/.MissedSpam/cur/ That would train spamassassin to recognise spam better. # sa-learn --ham --sync /mail/emily/cur/ # sa-learn --ham --sync /mail/john/cur/ ... Make sure that the database ownership has not been reclaimed by # chown amavis.amavis -R /var/amavis If you do this regularly the amount of spam that managed to get through should reduce.
Improving spam filteringSpamAssassin comes with the ability to use custom-rules used to add/remove points to each message passing through. On interesting project is Rules Du Jour at Exit0Wiki, a SpamAssassin-dedicated site. InstallationTo install Rules Du Jour is simple enough and here is a quick recap. # cd /usr/sbin # wget http://sandgnat.com/rdj/rules_du_jour # chmod 755 rules_du_jour # mkdir /etc/rulesdujour # touch /etc/rulesdujour/config This will have downloaded the script and made it executable by SA_DIR="/etc/mail/spamassassin" MAIL_ADDRESS="spam.police@example.com" SA_RESTART="killall -HUP spamd" TRUSTED_RULESETS="TRIPWIRE ANTIDRUG SARE_EVILNUMBERS0 SARE_EVILNUMBERS1 SARE_EVILNUMBERS2 BLACKLIST BLACKLIST_URI RANDOMVAL BOGUSVIRUS SARE_ADULT SARE_FRAUD SARE_FRAUD_PRE25X SARE_BML SARE_BML_PRE25X SARE_RATWARE SARE_SPOOF SARE_BAYES_POISON_NXM SARE_OEM SARE_RANDOM SARE_HEADER SARE_HEADER0 SARE_HEADER1 SARE_HEADER2 SARE_HEADER3 SARE_HEADER_ENG SARE_HEADER_X264_X30 SARE_HEADER_X30 SARE_HTML SARE_HTML0 SARE_HTML1 SARE_HTML2 SARE_HTML3 SARE_HTML4 SARE_HTML_ENG SARE_HTML_PRE300 SARE_SPECIFIC SARE_OBFU SARE_OBFU0 SARE_OBFU1 SARE_OBFU2 SARE_OBFU3 SARE_REDIRECT SARE_REDIRECT_POST300 SARE_SPAMCOP_TOP200 SARE_GENLSUBJ SARE_GENLSUBJ0 SARE_GENLSUBJ1 SARE_GENLSUBJ2 SARE_GENLSUBJ3 SARE_GENLSUBJ_X30 SARE_GENLSUBJ_ENG SARE_HIGHRISK SARE_UNSUB SARE_URI0 SARE_URI1 SARE_URI2 SARE_URI3 SARE_URI_ENG SARE_WHITELIST SARE_WHITELIST_PRE30" My config file contains all available rules. Just remove the ones you don't need and don't forget to change the notification email address to something suitable to your site. Now we just need to make this run daily (please only run once per day to avoid stealing too much bandwidth from the sites that kindly give us these free goodies). # Get latest SpamAssassin rules. Runs at 2:22AM every day. 22 02 * * * /usr/sbin/rules_du_jour Change the time to something else to even-out the load on the servers that we will download from. Now the last thing we can do is try to run the script. It will output a lot of info as each rule is downloaded and installed. # rules_du_jour You should now have another, improved layer of email protection.
ClamAV AntivirusClam AntiVirus is a totally free -in all senses of the word- antivirus scanner. It is released under the GPL and has seen a lot of activity in the recent past. To install ClamAV, I recommend installing from source or getting the binary from the Crash-Hat yum repository. Download the latest source from http://www.clamav.net/stable.php then: # groupadd clamav # useradd -g clamav -s /bin/false -c "Clam AntiVirus" -M clamav # gpasswd -a clamav amavis # cd /usr/local/src/ # tar xzvf clamav-#.##.#.tar.gz # cd /usr/local/src/clamav-#.##.# # ./configure --sysconfdir=/etc # make # make install # cp /usr/local/src/clamav-#.##.#/contrib/init/RedHat/clamd /etc/init.d/ # chmod 0755 /etc/init.d/clamd # chkconfig --add clamd # chkconfig --levels 235 clamd on Note: you may need to upgrade the Edit LogFile /var/log/clamav/clamd.log LogFileMaxSize 10M LogTime LogSyslog PidFile /var/run/clamav/clamd.pid TemporaryDirectory /tmp DatabaseDirectory /var/clamav LocalSocket /var/run/clamav/clamd.sock FixStaleSocket MaxConnectionQueueLength 30 MaxThreads 20 ReadTimeout 300 User clamav AllowSupplementaryGroups DetectBrokenExecutables ScanMail ArchiveMaxCompressionRatio 300 All other parameters should be commented, in particular Now we need to tell Amavisd-New to enable virus scanning. Edit # @bypass_virus_checks_maps = (1); <- This line should be commented out Look for the following section in Automated update of Virus definitionsEdit the #Example <- This line should be commented out Now create a new 05 * * * * /usr/local/bin/freshclam --quiet Now Note: Make sure that the name of the socket file Testing the AntiVirusStart our AntiVirus service and restart our setup to check if everything works fine. # service postfix stop # service amavisd stop # service clamd stop # service clamd start # service amavisd start # service postfix start Note: Postfix should always start after amavisd! Send an email with the following in the message body (in an HTML email) or as an attachment (in a text file if you are sending the email as plain text only): This is a recognised fake virus signature that should trigger the ClamAV. That message should normally only be received by the account we set up in
SquirrelMail web interfaceSquirrelMail is the webmail interface that comes preloaded with Fedora. Make sure Apache is running By default, SquirrelMail is not accessible from https, and since our server will only be for mail, there is not need for appending the First get the original SquirrelMail Apache config file out of the way: # cd /etc/httpd/conf.d/ # mv squirrelmail.conf squirrelmail.OLD Then edit the <VirtualHost _default_:443> ... DocumentRoot "/usr/share/squirrelmail" ServerName mail.example.com <Directory /usr/share/squirrelmail> AllowOverride None Options ExecCGI Order allow,deny Allow from all </Directory> ... </Virtualhost> RewriteEngine on # Log the rewrites, just in case we need to debug (increase leve for verbosity) RewriteLog "/var/log/httpd/rewrite_log" RewriteLogLevel 0 RewriteCond %{HTTPS} off RewriteCond %{HTTP_HOST} ^(mail\..*)$ [NC] RewriteRule (^.*$) https://%1 [L,R] RewriteCond %{HTTP_HOST} ^webmail\.(.*)$ [NC] RewriteRule (^.*$) https://mail.%1 [L,R] Now make sure that Apache will start at boot and start the service for now: # chkconfig --levels 235 httpd on # service httpd start
You should be able to access your email from anywhere securely through
Note: https connections require a digital certificate registered with a known authority. The certificate is only valid for one website and one IP address and you need to pay for it. If you don;t have a certificate, your users will receive a warning when trying to access the site. You will have to tell them not to worry about that if you don't want or can't have a certificate (if you're using dynamic IP for instance). The certificate is only necessary to confirms that the site using is really who it pretends to be, it doesn't affect the fact that communications are encrypted.
Firewall considerationsEmail services by definition need to be able to connect to the outside world. Unless you are content being able o exchange emails in you own little private LAN, it's likely that -in the minimum configuration- at least your The following
Now, depending on how your users are supposed to access their email, you will need to open the necessary incoming POP, IMAP and HTTP ports and/or their secured variants on your Internet-facing connection. In a next chapter, we will see that it is fairly easy to secure your email channels using SSL and circumvent any port blocking that often ISP put in place. Firewall implementation
Having a proper firewall on your server is a must. Instead of relying on the default firewall configuration, I always opt to use the strong firewall rules scripts that allow better security and monitoring of the connections. These rules scripts are available in the IP-Masquerade-HOWTO available from The Linux Documentation Project site. Specific rulesIn my firewall script, I use the following rules in the echo -e " - Allowing access to standard Email ports" $IPTABLES -A INPUT -i $EXTIF -m state --state NEW,ESTABLISHED,RELATED \ -p tcp -s $UNIVERSE -d $EXTIP --dport 25 -j ACCEPT $IPTABLES -A INPUT -i $EXTIF -m state --state NEW,ESTABLISHED,RELATED \ -p tcp -s $UNIVERSE -d $EXTIP --dport 110 -j ACCEPT $IPTABLES -A INPUT -i $EXTIF -m state --state NEW,ESTABLISHED,RELATED \ -p tcp -s $UNIVERSE -d $EXTIP --dport 143 -j ACCEPT echo -e " - Allowing access to Secured Email ports" $IPTABLES -A INPUT -i $EXTIF -m state --state NEW,ESTABLISHED,RELATED \ -p tcp -s $UNIVERSE -d $EXTIP --dport 465 -j ACCEPT $IPTABLES -A INPUT -i $EXTIF -m state --state NEW,ESTABLISHED,RELATED \ -p tcp -s $UNIVERSE -d $EXTIP --dport 995 -j ACCEPT $IPTABLES -A INPUT -i $EXTIF -m state --state NEW,ESTABLISHED,RELATED \ -p tcp -s $UNIVERSE -d $EXTIP --dport 993 -j ACCEPT echo -e " - Allowing access to Web ports" $IPTABLES -A INPUT -i $EXTIF -m state --state NEW,ESTABLISHED,RELATED \ -p tcp -s $UNIVERSE -d $EXTIP --dport 80 -j ACCEPT $IPTABLES -A INPUT -i $EXTIF -m state --state NEW,ESTABLISHED,RELATED \ -p tcp -s $UNIVERSE -d $EXTIP --dport 443 -j ACCEPT If you are not using the same firewall script, replace the following variables:
To ensure that the script is invoked at startup and whenever my internet connection drops, I saved the script as Make sure the script is executable and modifiable only to # cd /etc/rc.d # chmod 744 rc.firewall # chown root.root rc.firewall # ./rc.firewall That's all you should need to make your email services accessible from the outside world without compromising your whole machine.
Secure, encrypted email channelsWith the proliferation of wireless hotpots, people have been able to enjoy a new freedom in accessing the web and their emails: airport lounges, coffee shops, public spaces. One of the reasons that email can be the weak link in your organisation security is that most of the time authentication connections by your email client are still sent in clear text, meaning that every time you get email, you advertise your username and password. Stunnel to the rescue!There are many ways to secure your email connections through SSL: most servers have their own configuration details allowing them to work through an encrypted channel. Here though, will will use
Installing StunnelIf To install the source code: # cd /usr/local/src # wget http://www.stunnel.org/download/stunnel/src/stunnel-4.XX.tar.gz # tar xzvf stunnel-4.XX.tar.gz # cd stunnel-4.XX # ./configure # make # make install Note that if you are installing on a RedHat machine, you will need to modify the files Note as well that the default installation directory is Creating the private key and certificate
To be able to encrypt the communication, This step is important: don't use any default key that comes with your system: the communication channels would still be encrypted, but since these keys are publicly available, your communications could be decrypted without too much hassle. To create the necessary keys just do the following: # cd /etc/stunnel # openssl req -newkey rsa:1024 -keyout privkey.pem -nodes \ -x509 -days 365 -out cert.pem You will be asked a number of questions regarding your organisation. These will be included in the certificate issued by Note that the certificate will only be available for the number of days specified when creating it. You can make your certificate valid for as little or as long as you wish. Now, # cat privkey.pem > stunnel.pem # echo "" >> stunnel.pem # cat cert.pem >> stunnel.pem # echo "" >> stunnel.pem # chmod 600 * # rm privkey.pem cert.pem That's it, Create the cert = /etc/stunnel/stunnel.pem [imaps] accept = 993 connect = 143 [pops] accept = 995 connect = 110 [smtps] accept = 465 connect = 25 What this does is simply tell Now we can try to launch # stunnel That's all that should be needed. If you are getting error messages, then try to add the path to your ... stunnel 4.08 on i386-redhat-linux-gnu PTHREAD+POLL+IPv4+LIBWRAP with OpenSSL 0.9.7f ... 500 clients allowed If you get an error saying that the binding address is already in use check that your To Allow A script is provided in the source code tree under Install the service and schedule it to run: # cp stunnel.init /etc/init.d/stunnel # chmod 755 /etc/init.d/stunnel # chown root.root /etc/init.d/stunnel # chkconfig --add stunnel That's should be all. You can check that
Alternate AccessIt is not uncommon for ISP to deal with the problem of spam and other email annoyances by forcing users to go through their own email services. Another species of more devious filtering seems to be common in places like China. The largest provider, China Telecom, seems to have strange ways of limiting (or filtering) access to IMAP and POP services when connecting to servers outside of China. To solve these issues I'm discussing here 2 solutions:
The first one may be enough to circumvent the restrictions imposed by most ISP and will work fine as long as their filter only block the usual email ports 25, 110 or 143. The second also requires that we poke holes in our firewall, but we'll just ask stunnel to listen to other ports as well as the standard SSL ones discussed in the SecureAccess article. Forwarding traffic from one port to anotherSo let's implement the first solution. As discussed in the Firewall chapter, I use the strong firewall rules scripts provided by the Linux IP Masquerade HOWTO. In the echo " - FWD: Aternate SMTP, POP3 and IMAP ports" $IPTABLES -A FORWARD -i $EXTIF -o $INTIF -p tcp --dport 725 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A PREROUTING -t nat -p tcp -d $EXTIP --dport 725 -j DNAT --to $INTIP1:25 $IPTABLES -A FORWARD -i $EXTIF -o $INTIF -p tcp --dport 710 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A PREROUTING -t nat -p tcp -d $EXTIP --dport 710 -j DNAT --to $INTIP1:110 $IPTABLES -A FORWARD -i $EXTIF -o $INTIF -p tcp --dport 743 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A PREROUTING -t nat -p tcp -d $EXTIP --dport 743 -j DNAT --to $INTIP1:143 Now restart the script (should be saved as Secure alternate accessAgain, we're going to use alternate ports 825, 810 and 843 as our arbitrary secure ports. First, we poke holes for these ports in our firewall, so just edit echo -e " - Allowing access to Alternate Secured Email ports" $IPTABLES -A INPUT -i $EXTIF -m state --state NEW,ESTABLISHED,RELATED \ -p tcp -s $UNIVERSE -d $EXTIP --dport 825 -j ACCEPT $IPTABLES -A INPUT -i $EXTIF -m state --state NEW,ESTABLISHED,RELATED \ -p tcp -s $UNIVERSE -d $EXTIP --dport 810 -j ACCEPT $IPTABLES -A INPUT -i $EXTIF -m state --state NEW,ESTABLISHED,RELATED \ -p tcp -s $UNIVERSE -d $EXTIP --dport 843 -j ACCEPT Restart the script and add the following entries in the the [altimaps] accept = 843 connect = 143 [altpops] accept = 810 connect = 110 [altsmtps] accept = 825 connect = 25 Restart
Mbox to Maildir migrationWhen upgrading a mail server, you may be faced with a rather 'interesting' problem: migrating old user account in the classic monolithic mbox format to the more tolerant and performing maildir. Mbox is a way to store emails in a single file. It's old, compatible with most mail applications, but as your mail store grows, it becomes harder to manage emails contained within. Maildir on the other hand is newer and not supported by all systems. Basically it's just a way to store emails as files within a folder hierarchy. Its advantages are mostly better performance and tolerance in case of failure since you're more likely to lose just one email instead of your entire mailbox. Postfix (MTA) and Dovecot (POP3 and IMAP server) both support the maildir format and can integrate with each other seamlessly. MigrationIt's nevertheless a great pain when you have to migrate existing mailboxes to the new format, on a new server for instance. There is apparently only one tool that allows this type of thing: it's a small Perl script maintained by Philip Mak that is available as Perfect_maildir. Just download the single file script and you are ready to convert, unless you're getting a long error message and in that case you may need to download the To install it, just enter: # perl -MCPAN -e 'install Date::Parse' If this is the first time you install a module, you will be asked a series of question. Just keep pressing Enter until you're asked about your geographic area. Make your selection of mirrors to download from and Perl will do the rest. Next time, you won't be asked anything. If you have a handful of accounts to migrate, doing it by hand may be tedious, but it can still be faster than going through setting up an automated process. I found useful to use my mail client to create IMAP accounts for every user I needed to migrate, then use their original mailbox layout to re-create the directories they had. You can get the old mailbox layout by viewing the # perfect_maildir.pl /mail/michael/email < /oldmail/var/mail/michael # perfect_maildir.pl /mail/michael/email/.Drafts < \ /oldmail/home/michael/Drafts # chown michael.michael -R /mail/michael/email Would first move the inbox and then the old Draft mboxes to the new maildirs and ensure that the files belong to the user; this is particularly important if you're doing the migration as If you need to migrate a lot of accounts, then you should use the migration tools below. They make use of Just in case it may be useful to you, here is a small script I used to move each original mbox inbox to the new maildir one: #!/usr/bin/perl my $n = $ARGV[0]; $n =~ s/^\s+//; $n =~ s/\s+$//; die "No mailbox for $n\n" \ unless (-e "/oldmail/spool/$n" && -e "/mail/$n"); `mkdir /mail/$n/email/cur` unless -e "/mail/$n/email/cur"; `mkdir /mail/$n/email/new` unless -e "/mail/$n/email/new"; `mkdir /mail/$n/email/tmp` unless -e "/mail/$n/email/tmp"; print `perfect_maildir.pl /mail/$n/email < /oldmail/spool/$n`; `chown $n.$n -R /mail/$n`; You will need to modify the hard-coded paths to suit your configuration. In mine, I used the following:
If you're setting up a new machine and your inboxes are on the old one, you can make files available to the new system through NFS and mounting the exported directories locally or simply copying using AlternativesIf your old email is sitting in a POP3 account at an ISP, you can use Fetchmail is easy to use and I won't go into the details except that you could use a poll mail.isp.com protocol pop3 user roger to roger password 123456 keep The Another way, useful if you are using IMAP on the old account and have created IMAP folders, is to have both old and new account in your client email for each user and drag-drop files from one to the other after having recreated the same directory structure manually.
Email clients configuration...ToDo...
Troubleshooting SASL authenticationTo ensure that your authentication process works fine, we'll check what the server reports when we try to feed it a correct login. Since logins are base64 encoded, copy and paste the following in a file that you call
Then use it to encode a username/password pair as it would be expected by the mail server for authentication. Here I use the existing administrator user (the account must exist on the system): # encode_sasl_plain.pl administrator 123456 Then, talk to your mail server manually:
The only lines you will need to type are 6, 15, 17. The others are the server's responses.
Maillog analysis with AWStatsMaillogs are mighty important when troubleshooting or to check if your server is properly configured for its load. AWStats is a generic log analysis package that offers a nice web interface and can be made to analyse almost any type of logs. It's easy to extend too and quite simple to install. I don;t recommend using the RPM from the AWStat website has it has been packaged differently for Fedora and if you use automatic update, your config will change. Just use # yum install awstats # echo alias awstats_updateall.pl=\ "'awstats_updateall.pl -awstatsprog=/var/www/awstats/awstats.pl'" \ >> ~/.bashrc # cd /etc/awstats/ # cp awstats.model.conf awstats.mail.conf The second line creates an alias for the Then edit the LogFile="perl /usr/bin/maillogconvert.pl standard < /var/log/maillog |" LogType=M LogFormat="%time2 %email %email_r %host %host_r %method %url %code %bytesd" SiteDomain="mail.example.com" LevelForBrowsersDetection=0 LevelForOSDetection=0 LevelForRefererAnalyze=0 LevelForRobotsDetection=0 LevelForWormsDetection=0 LevelForSearchEnginesDetection=0 LevelForFileTypesDetection=0 ShowMenu=1 ShowSummary=HB ShowMonthStats=HB ShowDaysOfMonthStats=HB ShowDaysOfWeekStats=HB ShowHoursStats=HB ShowDomainsStats=0 ShowHostsStats=HBL ShowAuthenticatedUsers=0 ShowRobotsStats=0 ShowEMailSenders=HBML ShowEMailReceivers=HBML ShowSessionsStats=0 ShowPagesStats=0 ShowFileTypesStats=0 ShowFileSizesStats=0 ShowBrowsersStats=0 ShowOSStats=0 ShowOriginStats=0 ShowKeyphrasesStats=0 ShowKeywordsStats=0 ShowMiscStats=0 ShowHTTPErrorsStats=0 ShowSMTPErrorsStats=1 Now make AWStats update its database regularly from a cron job ( 00 */2 * * * /var/www/awstats/awstats.pl -update -config=mail 00 */3 * * * /var/www/awstats/awstats.pl -update -config=localhost.localdomain Then we can construct the database right now so we can access it for the remaining of our configuration: # awstats_updateall.pl now If there are errors, double-check that you entered all the correct options in the configuration file above. If the script says it can't find AWStats Integration in ApacheSo now we have AWStats installed and updating its database regularly but what we still need is to display the stats in a convenient way. The default installation should have added the following lines to your Alias /awstats/icon/ /var/www/awstats/icon/ ScriptAlias /awstats/ /var/www/awstats/ <Directory /var/www/awstats/> DirectoryIndex awstats.pl Options ExecCGI Order deny,allow Deny from all Allow from 127.0.0.1 192.168.0.0/255.255.255.0 212.87.250.3 </Directory> Now, to access AWStats, you need to point your web browser to
Our solution, amongst many possible, was to add a subdomain NameVirtualHost *:80 <Virtualhost *:80> ServerName mailstats.faiveley-fareast.com DocumentRoot "/var/www/awstats" Alias /awstats/icon/ /var/www/awstats/icon/ ScriptAlias /awstats/ /var/www/awstats/ <Directory /var/www/awstats> DirectoryIndex awstats.pl Options ExecCGI order deny,allow deny from all Allow from 127.0.0.1 192.168.0.0/255.255.255.0 212.87.250.3 </Directory> RewriteEngine on RewriteLog "/var/log/httpd/rewrite_log" RewriteLogLevel 4 RewriteCond %{REQUEST_URI} ^/mail/?$|^/?$ [NC] RewriteCond %{HTTP_HOST} ^(mailstats\..*) [NC] RewriteRule (^.*$) http://%1/awstats/awstats.pl?config=mail RewriteCond %{REQUEST_URI} ^/web/?$ [NC] RewriteCond %{HTTP_HOST} ^(mailstats\..*) [NC] RewriteRule (^.*$) http://%1/awstats/awstats.pl?config=localhost.localdomain RewriteCond %{HTTPS} off RewriteCond %{HTTP_HOST} ^(mail\..*)$ [NC] RewriteRule (^.*$) https://%1 [L,R] RewriteCond %{HTTP_HOST} ^webmail\.(.*)$ [NC] RewriteRule (^.*$) https://mail.%1 [L,R] </Virtualhost> Requests to the web server wil be transformed as such :
Now, providing we created the mailstats sub-domain, we can access both our mail and web statistics without having to remember those long URLs. Extending AWStatsAWStats by default will provide quite a bit of useful information, but it will also ignore some that it won't understand, like how much spam or viruses were found. How to integrate this information into the stats collected by AWStats will be developped in the near future. References
Comments CongWednesday 20 December 2006, at 03:29 GMT+8 [X] This is most complete detail configuration for email that I ever seen. I use sendmail instead of posfix but I think I will switch over base on your your document. I see that you put a lot of work on here. Thank for for the document. What software do u use to write this document? I'm thinking writing HOWTO for linux like this as well please email me at congngo at yahoo.com Tilemahos ManolatosMonday 16 July 2007, at 23:00 GMT+8 [X] Congratulations -- this is the most detailed and complete tutorial regarding this topic I've ever seen Many thanks |