Greg's Garage

Email was the primary reason I ended up using FreeBSD. I needed to replace a crashed Redhat 7 server with an unreadable hard drive, and decided to give FreeBSD a try. This setup was originally designed for a business I was working at, which had some specific requirements that led into the decisions I made about how it all went together.

There are many, many possibilites as to which software to use for email. I ended up choosing Sendmail for an SMTP server, and Dovecot for an IMAP server. I chose Sendmail simply because my setup is not that complicated, I am familiar with how to add and remove users from the system, and it is already installed as part of the base system. I originally chose IMAP-UW as my IMAP server, but quickly discovered that its design of storing a user's email in a single text file was too slow when users would retain large amounts of email (especially with attachements). IMAP-UW was extremely easy to set up, but Dovecot won out because of its design of storing each email as an individual file on the system. Since Sendmail stores all incoming email on the /var partition in a single text file by default, we also have to install procmail as a local delivery agent, and use that to place the inbound email into the user's home directories where Dovecot can find it.

Dovecot

Install Dovecot as follows:



FreeBSD# cd /usr/ports/mail/dovecot; make install clean
FreeBSD# cp /usr/local/etc/dovecot-example.conf /usr/local/etc/dovecot.conf



I edited the dovecot.conf file by changing the following: I need plaintext for a specific client, and SSL will be handled with stunnel. The second line specifies where to store user's mail, in this case it stores it in ~/Maildir



ssl = no
mail_location = maildir:%h/Maildir
protocols = imap pop3



Added the following to /etc/rc.conf:



dovecot_enable="YES"



And started Dovecot:



FreeBSD# /usr/local/etc/rc.d/dovecot start



You should now be able to connect ot the server using an IMAP client, such as Thunderbird. User's Inboxes can be found in the Maildir directory under their home directory. Mail is stored in the subdirectories cur, new & tmp. Each email is saved as an individual file (rather than a single text file). Each additional folder created in the IMAP client is saved with a dot prefix within /Maildir. For example, mail saved in Drafts would be found in /usr/home/username/Maildir/.Drafts/cur (or) new (or) tmp.

Sendmail / Procmail

Sendmail is already installed as part of the base system. In order to use it, all you need to do is modify the config files, and restart it. In my situation, I also wanted to enable SMTP-AUTH, a manner of authenticating remote users without opening up the system as an open relay. In order to do this, we need to install sasl2-saslauthd.



FreeBSD# cd /usr/ports/security/cyrus-sasl2-saslauthd; make install clean
FreeBSD# rehash



This will also install sasl2 as a dependency. To configure sasl2, we need to check one configuration file.



FreeBSD# ee /usr/local/lib/sasl2/Sendmail.conf



and ensure it has the following:



pwcheck_method: saslauthd



Add the following to /etc/rc.conf



saslauthd_enable="YES"



And start saslauthd



FreeBSD# /usr/local/etc/rc.d/saslauthd start



We can now test to make sure that saslauthd is operating correctly by testing it against an existing username.



FreeBSD# testsaslauthd -u username -p password



This should be the result:



0: OK "Success."



Now it's time to reconfigure Sendmail. First, add the follwing to /etc/make.conf in order to get SMTP-AUTH operating:



SENDMAIL_CFLAGS=-I/usr/local/include -DSASL=2
SENDMAIL_LDFLAGS=-L/usr/local/lib
SENDMAIL_LDADD=-lsasl2



Then recompile Sendmail:



FreeBSD# cd /usr/src/usr.sbin/sendmail
FreeBSD# make clean
FreeBSD# make obj
FreeBSD# make depend
FreeBSD# make
FreeBSD# make install



* Note, if you get an error at this point about libsmutil.a and libsm.a not existing, more than likely you did not rebuild world. You can quickly install these by entering the following:



FreeBSD# cd /usr/src/lib/libsm
FreeBSD# make clean
FreeBSD# make obj
FreeBSD# make depend
FreeBSD# make




FreeBSD# cd /usr/src/lib/libsmutil
FreeBSD# make clean
FreeBSD# make obj
FreeBSD# make depend
FreeBSD# make



But I would strongly advise you do the buildworld process, which will install these, as well as making sure any security patches have been installed.

Once Sendmail has been recompiled, it's time to configure it. One note I should have added prior to this, to avoid some issues with other mail servers, make sure that your MX record is the same as the name you gave this server when you originally set it up. I've had issues in which email was returned undeliverable because I had my MX record pointed to mail.somedomain.com, but the server was named someothername.somedomain.com. Renaming the server to mail.somedomain.com in sysinstall corrected these issues. Onto the configuration.



FreeBSD# cd /etc/mail
FreeBSD# make all



The above command will generate a hostname.somedomain.com.mc file to edit. Open it in your favorite editor, and add the following:



FEATURE(local_procmail)dnl
MAILER(procmail)dnl


define(`confAUTH_MECHANISMS',`PLAIN LOGIN')dnl
TRUST_AUTH_MECH(`PLAIN LOGIN')dnl



I add these after the "FEATURE(virtusertable)" line. The first two lines are for procmail, which is needed for Dovecot, the last two lines are for SMTP-AUTH. Now create the following configuration files:



FreeBSD# cp /etc/mail/virtusertable.sample /etc/mail/virtusertable
FreeBSD# cp /etc/mail/access.sample /etc/mail/access
FreeBSD# touch /etc/mail/local-host-names
FreeBSD# touch /usr/local/etc/procmailrc



In /etc/mail/access, enter the IP addresses of all the machines that will be allowed to relay email. I only allow my internal network as follows (this is tab delimited):



192.168.0     RELAY



In /etc/mail/local-host-names, enter in all of the names your server is recognized as on the Internet:



somedomain.com
mail.somedomain.com



In virtusertable, we enter in the email addresses of all the users on the system that will have an email address, and the username of the person we want to map it to (this is tab delimited).



john.doe@somedomain.com     johndoe
jane.doe@somedomain.com     janedoe



You can also install a catchall for anything hitting your server in virtusertable as follows:



@somedomain.com     johndoe



In this example, anything not specifically addressed to someone in virtusertable will be delivered to johndoe. Personally, I do not do this. I end up with too much spam sent to nonexistent users. To combat spam, I drop everything not explicity sent to an existing user into the bit-bucket. I know this breaks the email RFC, since it will no longer communicate back to the originating email server that the user does not exist, but it protects my server from becoming a bounce-relay from spammers. To do this I enter the following in virtusertable:



@somedomain.com     devnull



and in /etc/mail/alaises, I add the following line:



devnull     /dev/null



When in /etc/mail/alaises, I also add an alias for root to my username. This way all of the automated server emails (from the cron jobs on the previous page) end up in my InBox.



root     myusername



We now have to hash everything into db format so that Sendmail can read it. Although there are commands to do each of the following, having a small system, I just run the following:



FreeBSD# cd /etc/mail
FreeBSD# make all



Then I create & install the new cf files as follows:



FreeBSD# cd /etc/mail
FreeBSD# make install



Next thing needed is procmail. Install as follows:



FreeBSD# cd /usr/ports/mail/procmail
FreeBSD# make install clean



Add the following to the /usr/local/etc/procmailrc file you created earlier.



DROPPRIVS=yes
DEFAULT=$HOME/Maildir/
MAILDIR=$HOME/Maildir



Now add the following to /etc/rc.conf.



sendmail_enable="YES"



And restart sendmail. (make all generates the cf files, make install copies them over to the correct loaction, and make restart restarts sendmail)



FreeBSD# cd /etc/mail
FreeBSD# make all
FreeBSD# make install
FreeBSD# make restart



At this point you should be able to send email from any IP address you have listed in /etc/mail/access, or by authenticating with an existing username & passsword. If you experience problems, telnet to sendmail from the command line (commands prefixed with a #)



FreeBSD# telnet localhost 25
Trying ::1...
Connected to localhost.somedomain.com.
Escape character is '^]'.
220 mail.somedomain.com ESMTP Sendmail 8.13.8/8.13.8; Thu, 26 Oct 2006 12:10:18 -0500 (CDT)
EHLO localhost
250-mail.somedomain.com Hello localhost.somedomain.com [IPv6:::1], pleased to meet you
250-ENHANCEDSTATUSCODES
250-PIPELINING
250-8BITMIME
250-SIZE
250-DSN
250-ETRN
250-AUTH PLAIN LOGIN
250-DELIVERBY
250 HELP



If you do not see the line containing "AUTH PLAIN LOGIN", or whichever authentication method you have SASL2 configured to use, this will be the source of the problem. Only a couple of more things to check at this point. Procmail should be redirecting inbound email from /var/mail/~user to /usr/home/~user/Maildir. Sendmail should be allowing outbound mail from any IP addresses listed in /etc/access, as well as allowing outbound email from any others providing the correct username / password combo is given. Dovecot should be correctly displaying any InBoxes correctly as well.


Continued