Infohub‎ > ‎Articles‎ > ‎

A FreeBSD mail server


If you need a mail system, chances are that you’re going to need an SMTP server to receive and send emails, a POP3 or IMAP server to have them downloaded by the client, a webmail to check them while you’re out of office and, of course, an antivirus.

This guide will help you set up such a system using:

-          FreeBSD: no words to spend on it. Simply the best freely available operating system. Jump to http://www.freebsd.org and get it!
-          Postfix: fast, flexible and secure (not only) SMTP server
-          Dovecot: affordable POP3(s) and IMAP(s) server
-          Postfixadmin: a PHP tool to easily manage your postfix setup
-          Squirrelmail: easy to setup webmail system
-          ClamAV: free antivirus

To have all it up and running you need an installed FreeBSD system, I’ll assume you’re using 6.2. You must have installed the apache http server, any version over and including 1.3 will be ok as long as you have PHP installed. It is beyond the scope of this document how to install it, but in the majority of the cases you may use the standard pkg_add method. Also, installing Postifixadmin or squirrelmail via package will also install apache and php as a dependency. If you will be building your packages, then remember to update the ports collection.

Finally you need MySql (I’m using 5.x). When you install postfix and dovecot, remember to compile with MySql extensions.

Let’s start.

The difficult in setting up such a server resides in matching the parameters in the different configuration files for the different programs. Let’s start installing Dovecot and then Postfix.

cd /usr/ports/mail/dovecot
make install clean



Checking     the MySQL support. Then:

cd /usr/ports/mail/postfix
make install clean

and select



This will download and compile postfix and dovecot. Then add this to your rc.conf.

sendmail_enable="NO"
sendmail_submit_enable="NO"
sendmail_outbound_enable="NO"
sendmail_msp_queue_enable="NO"
postfix_enable="YES"

Then we need to get the uid of user postfix:

# id postfix
uid=125(postfix) gid=125(postfix) groups=125(postfix), 6(mail)

So mine is 125, your may vary. Take note of this number as we’ll need it later.

Let’s install postfixadmin:

/usr/ports/mail/postfixadmin
make install clean

And go with standard options. You’ll get some php5 dependencies.

Now let’s configure Apache. I prefer having a single virtual host for any site, so

ee /usr/local/etc/apache2/httpd.conf

Jump to the endings of the file and uncomment

NameVirtualHost *:80

Then create a virtual host for your Postfixadmin. Go to /usr/local/www/postfixadmin and edit DATABASE_MYSQL.TXT to change the password in the first lines. Then

mysql <DATABASE_MYSQL.TXT

to create the database. Then edit config.inc.php in the postfixadmin folder and set:

-          database_password to the password you changed in DATABASE_MYSQL.TXT
-          replace change-this-to-your.domain.tld with your domain name
-          'domain_path' = YES
-          'domain_in_mailbox' = 'NO';
-          'encrypt' = 'cleartext';

If you want to limit local access to postfixadmin dir do:

chown -R www:www postfixadmin/
chmod -R 700 postfixadmin/

Now try to access your site using your servername (remember we’re using name based virtual hosting). You should see all OKs. If it is as expected, delete setup.php and click to Admin section. You’ll log in using admin/admin: change this using htpasswd against the .htpasswd file in the admin directory.

Now you need to add this to your main.cf in

virtual_alias_maps = mysql:/usr/local/etc/postfix/mysql_virtual_alias_maps.cf
virtual_gid_maps = static:125
virtual_mailbox_base = /usr/local/virtual
virtual_mailbox_domains = mysql:/usr/local/etc/postfix/mysql_virtual_domains_maps.cf
virtual_mailbox_limit = 51200000
virtual_mailbox_maps = mysql:/usr/local/etc/postfix/mysql_virtual_mailbox_maps.cf
virtual_minimum_uid = 125
virtual_transport = virtual
virtual_uid_maps = static:125

Replacing:

-          /usr/local/virtual with your mailbox base path
-          125 with the userid of the postfix user

In /usr/local/etc/postfix, create a file named ‘mysql_virtual_alias_maps.cf’ containing

user = postfix
password = postfix
hosts = localhost
dbname = postfix
query = SELECT goto FROM alias WHERE address='%s' AND active = 1

Here and in the files that follow, replace the password for user postfix with the one you changed in DATABASE_MYSQL.TXT.

Create mysql_virtual_domains_maps.cf with

user = postfix
password = postfix
hosts = localhost
dbname = postfix
query = SELECT domain FROM domain WHERE domain='%s'

Create mysql_virtual_mailbox_maps.cf

user = postfix
password = postfix
hosts = localhost
dbname = postfix
query = SELECT maildir FROM mailbox WHERE username='%s' AND active = 1

Now create the directory tree:

cd /usr/local/virtual
mkdir -p /usr/local/virtual/mydomain.com
chmod -R 770 /usr/local/virtual
chown -R postfix:postfix /usr/local/virtual

Now we need to configure dovecot.

cp /usr/local/etc/dovecot-example.conf  /usr/local/etc/dovecot.conf, and edit dovecot.conf changing:

-          disable_plaintext_auth = no
-          log_path = /var/log/dovecot.log
-          ssl_disable = yes
-          mail_location = maildir:/usr/local/virtual/%d/%n
-          first_valid_uid = 125
-          last_valid_uid = 125

Uncomment and complete this:

passdb sql {
        args = /usr/local/etc/dovecot-mysql.conf
}
userdb sql {
        args = /usr/local/etc/dovecot-mysql.conf
}

Create a file named ‘/usr/local/etc/dovecot-mysql.conf’ containing

driver = mysql
connect = host=localhost dbname=postfix user=postfix password=postfix

user_query = SELECT concat('/usr/local/virtual/', maildir) as home, concat('maildir:/usr/local/virtual/', maildir) as mail, 125 AS uid, 125 AS gid, concat('maildir:storage=', quota) AS quota FROM mailbox WHERE username = '%u' AND active = '1'

password_query = SELECT username as user, password, concat('/usr/local/virtual/', maildir) as userdb_home, concat('maildir:/usr/local/virtual/', maildir) as userdb_mail, 125 as userdb_uid, 125 as userdb_gid FROM mailbox WHERE username = '%u' AND active = '1'

default_pass_scheme = PLAIN

Check for the text in red to match your setup (125 = postfix gid, /usr/local/virtual/ = mailbox root).

Let’s install SquirrelMail

cd /usr/ports/mail/squirrelmail
make install clean

As we have done for Postfixadmin, lets create a virtual host pointing to /usr/local/www/squirrelmail, then:

cd /usr/local/www/squirrelmail
./configure

And set all the parameters you need. I use to change option 2.3 from SMTP to SENDMAIL.

That’s all! Now point your browser to the home of your SquirrelMail server and you’re ready.

Now let’s install an antivirus: ClamAV

cd /usr/ports/security/clamav
make install clean

leaving the default options


Similarly, for Amavis:

cd /usr/ports/security/amavisd-new
make install clean



This is the interface between the antivirus software and the mail server. In the bitmap you can see I decided to enable some compression formats that were disabled by default. You’ll get several perl dependencies here. Also when installing spamassassin you’ll be asked if you want to update it: for now respond No.

Now we have to add user clamav to the vscan group: edit /etc/groups, find the line with vscan and modify as:

vscan:*:110:clamav

Now, entering the command

id clamav

you should get an answer similar to (note the red part):

uid=106(clamav) gid=106(clamav) groups=106(clamav), 6(mail), 110(vscan).

Write them down. I obtained clamav=106 and vscan=110. Edit the file /usr/local/etc/amavisd.conf by setting the correct values for $mydomain and $myhostname, that is something like:
$mydomain=domain.my
$myhostname=mail.domain.my

Now indicate Amavisd that we have the ClamAV scanner. Edit /usr/local/etc/amavisd.conf: find the lines below and uncomment them (not the first one, obviously).
# ### http://www.clamav.net/
 ['ClamAV-clamd',
            \&ask_daemon, ["CONTSCAN {}\n", "/var/run/clamav/clamd"],
            qr/\bOK$/, qr/\bFOUND$/,
            qr/^.*?: (?!Infected Archive)(.*) FOUND$/ ],

Add the various _enable lines to your rc.conf file so that programs can start

clamav_clamd_enable="YES"
clamav_freshclam_enable="YES"
amavisd_enable="YES"
#amavisd_ram="512m"

I commented out the last one. Decide based on your needs. And then start them

/usr/local/etc/rc.d/clamav-freshclam start
/usr/local/etc/rc.d/clamav-clamd start
/usr/local/etc/rc.d/amavisd start

You should see several messages.

Now let’s integrate postfix and Amavisd: edi t /usr/local/etc/postfix/main.cf and add:

content_filter = smtp-amavis:[127.0.0.1]:10024
max_use = 15

Postfix will send content to the filter on port 10024. Once scanned the message will be back to postfix, so edit /usr/local/etc/postfix/master.cf and tell postfix to listen also on port 10025.

# AMaVIs interface for postfix

smtp-amavis unix -      -            n                  -                        2       smtp
                -o smtp_data_done_timeout=1200
                -o disable_dns_lookups=yes

127.0.0.1:10025 inet n-       n       -                   -                                                   smtpd
                -o content_filter=
                -o local_recipient_maps=
                -o relay_recipient_maps=
                -o smtpd_restriction_classes=
                -o smtpd_client_restrictions=
                -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

Referencies

Writing this document involved lots of experimenting and readings. In particular from www.freebsddiary.org for FreeBSD specific information and from bliki.rimuhosting.com for Linux information.