|
FreeBSD - Mail server
Email was the primary reason I ended up using FreeBSD. We were running sendmail on a RedHat 7 server
that crashed with an unreadable hard drive in January of 2004, and I had become somewhat disenchanted with RedHat for purely personal reasons, at the time
and decided to give FreeBSD a try.
At the start of the switchover, I tried a couple of different configurations for email.
I started with IMAP-UW & Sendmail, migrated to Dovecot & Postfix, and I'm currently using Dovecot, Sendmail & Procmail.
IMAP-UW was extrememly easy to set up and configure, however it proved to be unsatisfactory in it's capability to handle huge amounts of stored email.
I switched to Dovecot, migrated the existing mailboxes using mbox2mdir, but ran into issues getting Sendmail to store the incoming mail in the correct place.
Postfix handled this without any issues, so I switched to Postfix for a time. I then discovered my folly, that sendmail was unable to deliver the emails directly to the Dovecot mail directories,
and that procmail needed to be used as a intermediary. Once I determined where the problem lay, I switched back to sendmail. Not that there is anything wrong with postfix,
it's just that I've been using sendmail for a long time, am somewhat familiar with it's workings, and don't have a complicated email setup.
I found postfix to be confusing after dealing with sendmail for so long, and found the commands to update sendmail's config files easier to remember.
Once either one of these MTAs is setup, I've yet to have to go in and change anything except to add aliases and such on ocassion. I'm betting that for a large organization
where changes are common, postfix would probably be easier to handle in the long run, but sendmail suits my purposes perfectly.
IMAP-UW / Dovecot
IMAP-UW is probably the easiest IMAP server to get up and going quickly & painlessly.
It stores all incoming mail in a single text file located in /var/mail. Although I don't have the specific commands, the only option I had to configure was to
pass the command line option to use plain text passwords (for IMAP-UW & cclient - a dependancy) during the compile. Once that was done, it was a matter of enabling
two lines in /etc/inetd.conf, and adding INETD_ENABLE="YES" to /etc/rc.conf, and restarting inetd. All in all, a working IMAP server in about 15 minutes.
However, as I said, it din't scale that well with the large amount of stored email some users has on the system, so we switched to Dovecot.
cd /usr/ports/mail/dovecot; make install clean
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 last 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:
/usr/local/etc/rc.d/dovecot start
You should now be able to connect ot the server using an IMAP client, such as Thunderbird.
Users Inboxes can be found in the Maildir directory in 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),
which is why Dovecot has been easier to deal with when you have a huge amount of stored email. 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
Sendmail is already installed as part of the base system. In order to use it, you need to 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.
cd /usr/ports/security/cyrus-sasl2-saslauthd; make install clean
rehash
This will also install sasl2 as a dependency. To configure sasl2, we need to check one configuration file.
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
/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.
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:
cd /usr/src/usr.sbin/sendmail
make clean
make obj
make depend
make
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:
cd /usr/src/lib/libsm
make clean
make obj
make depend
make
cd /usr/src/lib/libsmutil
make clean
make obj
make depend
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.
cd /etc/mail
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:
cp /etc/mail/virtusertable.sample /etc/mail/virtusertable
cp /etc/mail/access.sample /etc/mail/access
touch /etc/mail/local-host-names
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 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:
cd /etc/mail
make all
Then I create & install the new cf files as follows:
cd /etc/mail
make install
Last thing needed at this point is procmail. Install as follows:
cd /usr/ports/mail/procmail
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)
cd /etc/mail
make all
make install
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 #)
# 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 do 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. Next on our list is to make sure our server is secure in that we are not running an open relay. Test this by typing the following:
telnet relay-test.mail-abuse.org
This telnet session will test yor mail server in 20 different manners from mail-abuse.org for any openings in which to relay unauthorized email.
If all comes up clean, your server should be secure.
I also installed Spamassassin to identify inbound spam. In this instance, it rewrites the headers with the string "*****SPAM*****" for a subject, so that mail clients can easily filter it into a junk mail folder. To enable Spamassassin, do the following:
cd /usr/ports/mail/spamass-milter; make install clean
Add the following to /etc/rc.conf
spamd_enable="YES"
spamd_flags="-u spamd"
spamass_milter_enable="YES"
Run the following:
chmod 775 /root/.spamassassin
chown root:spamd /root/.spamassassin
And add the following two lines (in case of line-wrap) to /etc/mail/your.mail.server.mc
INPUT_MAIL_FILTER(`spamassassin', `S=local:/var/run/spamass-milter.sock, F=, T=C:15m;S:4m;R:4m;E:10m')
define(`confINPUT_MAIL_FILTERS', `spamassassin')
restart sendmail
cd /etc/mail
make all
make install
make restart
The config file, local.cf, for spamassassin is located in /usr/local/etc/mail/spamassassin. Make sure to copy local.cf.sample to local.cf if it's not there, and read through and make any needed changes. Here's mine:
rewrite_header Subject *****SPAM*****
trusted_networks 192.168.0/24 192.168.100/24 #(add any other networks determined to be safe here)
required_score 5.0
use_bayes 1
bayes_auto_learn 1
skip_rbl_checks 0
use_razor2 1
use_pyzor 1
Then start the demons.
/usr/local/etc/rc.d/sa-spamd start
/usr/local/etc/rc.d/spamass-milter start
*** Ran into an issue with spamassassin recently that caused some issues. All of a sudden, my /root partition was full, when it usually sits at around 30-35% used. It turns out that spamasssassin has a bug listed here in which the updating process times out, and hangs up.
This causes numerous "bayes_toks.expireXXXXXX" files to be generated in /root/.spamassassin, and spamassassin shuts itself off. After numerous attempts at cleaning up the mess, only to have it reoccur, I did the following:
Stop spamassassin.
/usr/local/etc/rc.d/sa-spamd stop
/usr/local/etc/rc.d/spamass-milter stop
Add the following to /usr/local/etc/mail/spamassassin/local.cf
bayes_auto_expire 0
Create a cron job by typing crontab -e, and adding the follwing line (it must be tab delimited)
50 1 * * * /usr/local/bin/sa-learn --sync --force-expire
Recreate the .spamassassin directory
mkdir /root/.spamassassin
chmod 775 /root/.spamassassin
chown root:spamd /root/.spamassassin
Restart Spamassassin
/usr/local/etc/rc.d/sa-spamd start
/usr/local/etc/rc.d/spamass-milter start
So far, so good....
In the event of false positives, mail from specific domain names can be whitelisted by adding the following to your local.cf file:
whitelist_from_rcvd *@somenetwork.com *@comcast.net *@someothernetwork.com
Horde
Next on the list is a webmail application. Up until lately, I've used Squirrelmail, but ran into issues with large inboxes taking forever to display.
I've recently switched to Horde, which can be somewhat of a pain to get set up, but is more of a suite then just a webmail application.
It has group calanders, task lists, and more that made it a perfect fit for our organization, and it handles large InBoxes without complaint (for our organization anyway).
Trying to keep everything as up to date as possible, I installed MySQL 5.1, Apache 2.2 & PHP5. First MySQL:
cd /usr/ports/databases/mysql54-client; make install clean
cd /usr/ports/databases/mysql54-server; make install clean
cd /usr/ports/databases/mysql54-scripts; make install clean
rehash
Add the following line to /etc/rc.conf.
mysql_enable="YES"
Start MySQL by entering the following:
/usr/local/etc/rc.d/mysql-server start
Last, we want to change the root password for the database, and install the system databases.
mysqladmin -u root password new_password
/usr/local/bin/mysql_install_db
MySQL is now up and running, next, apache.
cd /usr/ports/www/apache22; make install clean
rehash
Add the following to /etc/rc.conf
apache22_enable="YES"
Start apache by entering the following:
apachectl graceful
Point a browser to the server and you should see "It works!"
Next we build PHP5:
cd /usr/ports/lang/php5
make config
* check that the "Build Apache module" is selected
make install clean
Now we get php5 up and running. We need a php.ini file, and have to add a couple lines to httpd.conf:
cp /usr/local/etc/php.ini-recommended /usr/local/etc/php.ini
now we edit /usr/local/etc/apache22/httpd.conf and add "index.php" to the end of the following line:
DirectoryIndex index.html index.php
Next, add the last two lines of the following four directly after ":AddType application/x-gzip .gz .tgz":
AddType application/x-compress .Z
AddType application/x-gzip .gz .tgz
AddType application/x-httpd-php .php
AddType application/x-httpd-php-source .phps
If you want to run multiple sites on a single IP address, make sure this line is enabled:
Include etc/apache22/extra/httpd-vhosts.conf
Now we build Horde:
cd /usr/ports/www/horde
make install clean
Apache 2.2 wants all directories to be located under /usr/local/www/apache22/data, but some of the apps still install to /usr/local/www.
To correct this without messing around with file permissions, or worry about future updates scerwing up my apache configs, I just create a symlink
cd /usr/local/www/apache22/data
ln -s /usr/local/www/horde horde
Now go and edit /usr/local/etc/apache22/extra/httpd-vhosts.conf and add the following:
<VirtualHost *:80>
DocumentRoot /usr/local/www/apache22/data/horde
ServerName mail.yourdomain.com
ServerAlias mail.yourdomain.com
ErrorLog /var/log/mail.yourdomain.com-error_log
CustomLog /var/log/mail.yourdomain.com-error_log common
</VirtualHost>
Make sure you comment out any example sites that are listed in this file as well. Once this is done, save the file, and restart apache.
apachectl graceful
You should now be able to browse to the test page to see if everything is in place, http://yourmailserver.com/test/php.
If everything looks good, the next thing we need to do is create a datasbe for horde.
cd /usr/local/www/horde/scripts/sql
mysql -uroot -p < create.mysql.sql
Browsing to the domain you listed in httpd-vhosts.conf should bring up the front page for horde (http://mail.somedomain.com in this example).
Since horde has not been configured yet, there is no login needed.
I had a lot of problems trying to use MySQL as a backend for authentication. The issue it seems is that once you select MySQL as an authentication method, it kicks you out,
and wants you to log back in, but you can't because you were never allowed to add a user. Anyway, here's what I had to do to get Horde to use MySQL as a backend.
First, add a user to the horde database
mysql -u root -p
INSERT INTO horde_users (user_uid, user_pass) VALUES('user_name', 'password');
Next, go into Horde, and click "Administration", then "Setup", then "Horde".
On the "General" tab, I needed to turn off the "$conf[session][use_only_cookies]" setting, because of login issues.
On the "Database" tab, for "$conf[sql][phptype]", pick MySQL. Also enter the username and password with rights to the horde database.
On the "Authentication" tab, change "$conf[auth][driver]" to SQL Authentication and also change "$conf[auth][params][encryption]" to Plain.
(we change it to plain, so it can read the plaintext password that was entered directly into the database).
On the "DataTree System" tab change "$conf[datatree][driver]" to SQL Database.
Now save the configuration.
Now log back in with the username and password that you entered into the database.
At this point you can go back and change the encryption on the "Authentication" tab back to SHA, as long as you go into the Users section under Administration, and reenter your password. If you do so, it will then save your password in an encrypted format.
After getting Horde up and running, it was time to make it do something. If you want email access, you need to at least install Imp. I added some of the plugins that were available. The process for each was pretty much the same.
After building the port, go to /usr/local/www/plug-in/scripts/sql and run the sql command to buid the appropriate table like so:
cd /usr/local/www/horde/plugin/scripts/sql
mysql -uroot -p horde < name_of_appropriate_script.sql
Then log in to Horde, and go to Administration > SetUp > Name_Of_PlugIn, and generate the config file. I added the following plug-ins:
Name | Function | Location |
imp | Mail Client | /usr/ports/mail/horde-imp |
turba | Address Book | /usr/ports/mail/horde-turba |
ingo | Mail Filters | /usr/ports/mail/horde-ingo |
kronolith | Calendar | /usr/ports/deskutils/horde-kronolith |
gollem | FTP client | /usr/ports/ftp/horde-gollem |
nag | Task Manager | /usr/ports/deskutils/horde-nag |
mnemo | Notes Applicaiton | /usr/ports/deskutils/horde-mnemo |
The following config files will need to be edited in order to get Imp and Gollem to work correctly:
/usr/local/www/horde/imp/config/servers.php
/usr/local/www/horde/gollem/config/backends.php
Go to the first section in the config file, and make sure that they are pointed at "localhost". You might need to turn off SSL in the Imp config file as well.
The only additional setup to get any of these to work, outside of generating the config file, was for gollem. To use gollem, you need an FTP server, luckily one is installed as part of the base FreeBSD distribution.
To enable it do the following. Open /etc/inetd.conf, and enable the follwing line:
#ftp stream tcp nowait root /usr/libexec/ftpd ftpd -l
Then add the follwing to /etc/rc.conf
inetd_enable="YES"
Then start inetd as follows:
/etc/rc.d/inetd start
Change the line in /usr/local/horde/gollem/config/backends.php from "ftp.example.com" to "localhost", and after restarting apache, your users will have access to their home directories.
I did have some other minor issues with some of the other plugins, but were solved by reading the config files in /usr/local/www/horde/<plug_in_name&rt;/config.
Stunnel
Last but not least, I installed stunnel for ssl security for IMAP, POP3 & SMTP access.
Stunnel is a port that acts as an ssl wrapper, eliminating the need to compile ssl support into sendmail, apache & dovecot.
Simply compile the port - but do not "make clean" just yet. We need to install the certificate before we clean up rom the install.
cd /usr/ports/security/stunnel
make install
make cert
At this point, answer all the questions and the script will create your certificate files.
Note that when asked for the server name, enter the name you entered when configuring your network connection.
If you enter the name of a DNS alias, you will run into issues when connecting from an email client through SSL.
These are self-signed certificates, and will generate an error stating that the certificate can't be trusted since it is unsigned,
you can permanently accept the certificate on the client, and never be bothered again.
If you enter an alias name instead of the name you gave it to start with, every time someone connects, they will get an error message stating
that the name does not match the certificate regardless if you permanently accept it or not. Once you're done with creating the certificates, clean up as follows:
make clean
cp /usr/local/etc/stunnel/stunnel.conf-sample /usr/local/etc/stunnel/stunnel.conf
I had two issues getting this up and running, first the default stunnel.conf looks for mail.pem, but the "make cert" command creates stunnel.pem. Rename /usr/local/etc/stunnel/stunnel.pem to mail.pem, or edit the config file.
Second, the install does not create the directory for the PID file.
cp /usr/local/etc/stunnel/stunnel.pem /usr/local/etc/stunnel/mail.pem
mkdir /var/tmp/stunnel
chown stunnel:stunnel /var/tmp/stunnel
Add the following to /etc/rc.conf
stunnel_enable="YES"
And start stunnel
/usr/local/etc/rc.d/stunnel start
Also, once stunnel is running, chkrootkit will complain that 'bindshell' is infected on port 465. This can be safely ignored.
You should now have ssl encryption running on POP3, IMAP & SMTP.
Vacation
While hunting around for recipes to use as a basis for creating my .procmailrc files, I stumbled accross this recipe: (link).
Here's a local copy if for whatever reason the link is down (link). This script was the answer to my vacation problems.
With spamassassin enabled, this script does not reply to any inbound email marked as spam. It also ignores mailing lists and such, provided the headers have been set on the inbound email correctly, as well as keeping a cache of addresses it has replied to, replying with the auto-response only once.
After copying this script to the server into /usr/home/username as .procmailrc, don't forget to do a "chown user:group" on the file.
To enable the script, change the following lines to your preference, and save it to your user directory as .procmailrc:
VACATION_PASSWORD=yourpassword
VACATION_DOMAIN_NAME=domainname.com
The only other change I made to this script was where it stored the log files (if needed). I wanted to keep it in the /usr/local/home directories rather than in /tmp
PMDIR=$HOME/.procmail
#LOGFILE=$PMDIR/log
To turn it on, simply send an email to yourself with the following in the subject:
[password] vacation on
In the body of the email, enter the message you want sent out when you're out, and send the email. You will get a confirmation email that the script has been turned on.
To turn it off, simply send an email to yourself with the following in the subject:
[password] vacation off
Again you will receive a confirmation email that the script has been shut off, and that the cache has been deleted. If you have issues with this script, you can enable logging by creating a .procmail directory in your home directory, and enabling the logging functionlines at the start of the script.
In order to ensure that this vacation message does not respond to spam, enter the following lines at the top of your .procmailrc file:
:0
* ^Subject:.*\*\*\*\*\*SPAM\*\*\*\*\*
.Junk/
Replace ".Junk/" with whichever folder you want your spam diverted to. if you wish to simply delete your spam without it hitting your email client, replace ".Junk/" with "/dev/null".
Procmail rules work on a first match, meaning that any spam that trips spamassasin will be flagged, and the above rule will relocate it before the vacation rule is run. This ensures that your vacation autoresponder will not reply to spam.
That's it, a mail server that can handle large inboxes, SSL certificates, SMTP authentication, IMAP/POP3 (dovecot handles both) and includes a web interface. After 4 years, the only issues I've had to contend with is Outlook Mobile.
Outlook wants to use SPA for SMTP authentication, which is proprietary and does not work with non-MS products. Although you can shut this option off in Outlook, there is no manner of doing this with Outlook Mobile, at least not as of this writing.
|