FreeBSD Virtual Mail How-To

Ed's FreeBSD postfix+cyrus+sasl2+mysql Virtual Mail How-To

This how-to will describe the steps required to create a virtual mail email server using FreeBSD, postfix (SMTP server), cyrus (POP3 and IMAP server), sasl2 (auth server), and MySQL (holds all addresses, passwords, aliases, and domains). Additionally it will use MD5 hashed/crypted passwords for security, and provide access to administer the users, domains, aliases, passwords via a web front-end as well as provide web access to email.

While I have a fully working virtual mail setup that this document describes, and others have successfully followed it as well, this is still a work in progress as I fill in any blanks left over and fix other minor errors. As it stands, it'll get you something like ~99% there if not completely. Everything seems to be here and accurate, but don't be surprised if something is missing or somewhat different when you attempt it. -

Why would you want to read/follow this how-to?
This is for anyone who wants to, or plans to, host one or more domains on a single machine and have bob@domain1.tld and bob@domain2.tld be completely different accounts. Most people will only host one domain, perhaps a couple, just for themselves and have no need for seperate bob@ users. But if you do need a seperate bob@ user for each domain, or want a "sealed system" w/o real user logins on the system, then this is for you. To do all of this we'll be using postfix, cyrus, sasl2, mysql, apache (+ php4), squirrelmail (+ vlogin, quota, and avelsieve plugins), and postfixadmin.

So will I have to have a bunch of CNAMEs and virtual hosts and stuff?
No, aside from the web interface portion if desired. Your users login names will be stuff like fu@domain1.tld and bar@domain2.tld. This isn't a wholly uncommon practice at any other ISP your users may have used before.
One of the other how-tos on this I read they stored the passwords as plaintext. What about this one?
Nope. There is a patch for sasl2 which allows the use of DES, MD5, and Blowfish crypted/hashed passwords. The MD5 hashed passwords you'll end up using from this are compatible with the FreeBSD passwords in the system passwd file.
I want to use Courier IMAP instead of Cyrus. Is that covered? Can you help me with that?
No, I can't help you with that and it isn't covered. If you want to use Courier IMAP with Postfix for a virtual mail system there are dozens of how-tos on that already. In fact, going that route is quite a bit easier.
I'd like to use PostgreSQL instead of MySQL. Can I and how?

Yes and No. Postfix can be made to use pgsql easily. Cyrus itself doesn't use either, but cyrus-sasl2 does. A friend tried to use pgsql and had errors compiling cyrus-sasl2 with the "frost" patches applied. Postfixadmin, as of 2.1.0, supports both MySQL and PgSQL. The big stumbling block to using PgSQL instead of MySQL is support in cyrus-sasl2. If anyone goes the PgSQL route mostly following this and gets it all to work feel free to email me the changes you needed to do so I can add them as a footnote or something.
Wow, this takes a lot of work!
Sure does, but following this how-to reduces the amount of work due to research and troubleshooting by more than 50%. No wonder it is so much easier to, you know, pay someone else to host your email and deal with all of the upgrade hassles.
I have users in my default domain ( and they can login using just their name (bob) in addition to their full email address ( Is there a way to force them to use their full email address?
None that I am aware of short of using a different default domain. You might be able to use some sort of proxy for your remote pop3/imap connections, but that would very likely break SSL/TLS which would be even worse.
I want to use one installation of SquirrelMail and just point a bunch of different Apache virtual hosts at it (webmail.domain1.tld, www.domain2.tld/mail/, etc.). Can I do that, and how?
In this how-to we use Apache, SquirrelMail, and the SquirrelMail plugin vlogin to enable just that. I don't cover the addition of several Apache virtual hosts, but that's really all that needs to be done.
Some things to keep in mind
You got this off the internet - don't trust everything you find on the internet. Buyer beware. You might get what you paid for. You might get a whole lot more than what you paid for.
Your mileage will vary.
If you lose data, your job, or whatever, don't blame me - this is all at your own risk.
I use FreeBSD whenever possible and wrote this document for FreeBSD. If you use Linux this will still help you, but things will be Different and I won't help you - It can be done on Linux with minor changes, but you're on your own.
A lot of this document glosses over tons of stuff hardly ever mentioning the actualy install and/or readme documents that come with each piece of software mentioned here. We're basicly just blowing through things assuming that the defaults will be the same for you as they are for me right now. When in doubt, read the install, readme, and upgrading docs. In fact, you should read those anyway even if you follow this and it works right the first time.
Security is a problem in some cases here. Like I said, we're going to blow through some things just to get your virtual mail setup up and running. As an admin it is your job to understand your system and to take the needed steps to make it as secure as possible. This document isn't going to tell you all of those steps and it isn't meant for n00bs.
If you find a typo, or that something has changed since some piece of software has been upgraded, feel free to send me you're notes on that and I'll try and get this updated ASAP.
If you've used this before, or are just curious, you might find the Change Log to be of value.
What you'll need
A working FreeBSD 6.0 (or newer) system. FreeBSD 6.1 is highly recommended.
An up-to-date perl (5.8.6+) just because upgrading perl later will be a pain in the ass. If using FreeBSD 5.3.x you'll very likely have to install a full perl from ports anyway.
sudo - If you don't know what this is you need to stop right here and not even consider this undertaking. At all. Period.
joe - Because I like it, vi bothers me, and emacs is the wrong answer.
MySQL 4.1.x
Cyrus 2.3.x
postfix 2.3.x
phpMyAdmin - Optional though generally handy in case you need a quick peek at the tables and don't have shell access.
Happy fun compile/install/configure time
You should be installing FreeBSD 6 these days. This how-to was originally written using 4.11-Rel and updated for 5.4-Rel, but everything applies to 6-Rel (and newer) with almost no exceptions. You're pretty much on your own with this step, but a base no-frills install with ports is all you need. You won't be needing X11 for any of this so don't install that unless you have some other need.

Be sure to CVSup your system to get the latest fixes and a current ports collection. Rebuild at least your kernel if there were any source changes (and trust me, there will have been some). For maximum security you should buildworld as well to make sure you get all updates to the system installed at once. Documenting how to cvsup the system and build the kernel and world are way beyond the scope of this document.

You're also going to probably want to setup a basic firewall on the system. I recommend using pf but ipfw and ipf both will do all of the basics. Again, this step is totally beyond the scope of this document.

Get perl updated/installed if needed.

sudo allows you to run things as the super user (hence the name) or even as another user. It's very handy. Compile and install:

cd /usr/ports/security/sudo
make install %26amp;%26amp; make clean

You'll need to configure sudo so your non-root user login can use it. Most of everything written here will assume you're either doing everything as root or will have spawned a shell with sudo to get root privs. I realize there is a line in the sample config which allows you to use sudo w/o entering your password, but try to resist doing that as really bad things can happen easier than otherwise.

The sudo file is /usr/local/etc/sudoers and by default is not writable by anyone (and for good reason). To edit it use the visudo command which will securely modify it. If for some reason you don't have visudo, you can do this to edit it instead:

chmod u+w /usr/local/etc/sudoers ; joe /usr/local/etc/sudoers ; chmod a-w,o-rwx /usr/local/etc/sudoers ; rm /usr/local/etc/*~

If you do all of that on one line, everything should be ok, otherwise you have to do a bunch of lines and I did say this was going to be somewhat cut%26amp;waste friendly. To use visudo or the above method you'll either have to be logged in as root or su'ed.

At this point you should log out, login as your non-root user, and then either sudo /bin/csh (effecively root all the time) or just use sudo for each command as needed (what you are supposed to do). This is really a preference thing, but regardless, you will need sudo later on for part of the cyrus install.

joe is a wordstar-style text editor. I like it but you may or may not like it as well. This is an optional step but it's the editor I'll be referencing in this document.

cd /usr/ports/editors/joe
make install %26amp;%26amp; make clean

Compile and install the MySQL server, client, and client libraries which we'll be using later:

cd /usr/ports/databases/mysql41-server
make %26amp;%26amp; make install %26amp;%26amp; make clean

Add the following to your /etc/rc.conf to enable MySQL to be started:


Go ahead and kick mysql off:

/usr/local/etc/rc.d/ start

Get the cyrus-sasl2 crypt patches from You might want to add this link to your list of reference material. Follow the directions there to apply them to your cyrus-sasl2 source. Basicly you're going to take all of the FreeBSD patch files and dump them into the /usr/ports/security/cyrus-sasl2/files/ dir.

Now compile with MySQL support:


If the compile succeeds, do the following to finish up:

make install %26amp;%26amp; make clean

Don't bother to follow the config options on the frost page, just patch the source - we'll be covering the config later on.

You'll be using Cyrus 2.3.x for this
Get the Autocreate INBOX patch for Cyrus files from for your version of Cyrus and save them in your homedir. You should bookmark this link for future reference as well. Obviously if the version of Cyrus 2.3.x is not 2.3.3 then you should fetch the appropriate versions of the patches you need.
Compile and install cyrus:
Now extract, patch, and compile cyrus (in this case, 2.3.3):
cd /usr/ports/mail/cyrus-imapd23/
make patch
cd work/cyrus-imapd-2.3.3/
patch -p1 < ~/cyrus-imapd-2.3.3-autocreate-0.10-0.diff
patch -p1 < ~/cyrus-imapd-2.3.3-autosieve-0.6.0.diff
cd ../..

Depending on your version more or less patch files may be required. Just apply all of them.

Assuming everything goes well,
make install %26amp;%26amp; make clean
Note that later when a new version is released you'll have to do all of this over again - portupgrade will not apply these patches for you w/o additional configuration to /usr/local/etc/pkgtools.conf
Create the dir where all of our sealed cyrus files will reside:
mkdir /usr/local/imap

Note that this differs from the default install paths but will bring things together nicely. Do not use /usr/local/cyrus/ which is where the cyrus programs are installed!

Create an ssl certificate named cyrus.pem for cyrus:
openssl req -new -x509 -nodes -out /usr/local/imap/cyrus.pem -keyout /usr/local/imap/cyrus.pem -days 365

Find and set the following in /usr/local/etc/imapd.conf:
configdirectory: /usr/local/imap
partition-default: /usr/local/imap/spool
unixhierarchysep: yes
servername: domain1.tld
admins: cyrus
autocreatequota: 102400
sieveusehomedir: false
sievedir: /usr/local/imap/sieve
sasl_pwcheck_method: auxprop
tls_cert_file: /usr/local/imap/cyrus.pem
tls_key_file: /usr/local/imap/cyrus.pem
lmtpsocket: /usr/local/imap/socket/lmtp
idlesocket: /usr/local/imap/socket/idle
notifysocket: /usr/local/imap/socket/notify

I realize it says servername which should be the FQDN and I'm telling you to use domain1.tld instead. Thing is, something is weird about the handling of domains and this seems to get around it. This could be a bug in cyrus22 or a bug because of the way I'm doing things, but using domain1.tld seems to do the trick for me. Your mileage might vary. The autocreatequota option is set to 100MB in this example and you might want to bump that up.
If you have a CA file for your SSL/TLS cert, then be sure to set tls_ca_file to point at it as well in the part above.

Add the following to the end of imapd.conf:
virtdomains: yes
defaultdomain: domain1.tld
allowusermoves: yes
sasl_auxprop_plugin: sql
sasl_sql_user: postfix
sasl_sql_passwd: password
sasl_sql_database: postfix
sasl_sql_hostnames: localhost
sasl_sql_select: SELECT password FROM mailbox WHERE username='%u@%r' AND active='1'
sasl_sql_verbose: yes
sasl_sql_engine: mysql
sasl_mech_list: plain login
sasl_password_format: crypt
createonpost: yes
autocreateinboxfolders: spam
autosubscribeinboxfolders: spam
autocreate_sieve_script: /usr/local/imap/phpscript
autocreate_sieve_compiledscript: /usr/local/imap/phpscript.bc
generate_compiled_sieve_script: yes

Create /usr/local/imap/phpscript and populate it with the following:
# This script has been automatically generated by avelsieve
# (Sieve Mail Filters Plugin for Squirrelmail)
require ["fileinto","reject","vacation","imapflags","relational","comparator-i;ascii-numeric","regex","notify"];
header :is "X-Spam-Flag" "YES"
fileinto "INBOX/spam";

This sieve script will be copied to newly created users, compiled into bytecode, and run against every message that is delivered to the user. All this one does is check to see if the X-Spam-Flag header is present and set to YES. If it is, then the message is deposited to the spam folder which was also auto-created (if for some reason it doesn't exist it will go to the INBOX instead). When a message is found to be spam by SpamAssassin it gets this header. Obviously that's something extra you'll have to add yourself as I'm not covering it in this document.

If using this sieve script doesn't work later on you'll just have to create one with your test user and copy the phpscript.script to phpscript, blow away your user and their sieve dir ("How do I delete a user from my system entirely?"), then try again.

Note: If you'll have any users using POP3 instead of IMAP then you'll probably want to not do any of the automatic sieve scripting settings. The reason being that, unless I'm mistaken, POP3 will only get mail from the Inbox and not other folders (such as the spam folder).

Set permissions on the cyrus imap dir:
chown -R cyrus:cyrus /usr/local/imap
chmod o-rwx /usr/local/imap

Find and fix the socket paths in cyrus.conf:
lmtpunix cmd="lmtpd" listen="/usr/local/imap/socket/lmtp" prefork=0
notify cmd="notifyd" listen="/usr/local/imap/socket/notify" proto="udp" prefork=1

You'll also need to change the sieve listen line to make it use port 2000 instead of sieve which does not exist in /etc/services (there is "callbook" which you could use instead of 2000, but why?). Editing this line is better than editing a standard system file which you'll end up updating someday anyway.
sieve cmd="timsieved" listen="2000" prefork=0

Create the fancy cyrus paths and files:
sudo -u cyrus /usr/local/cyrus/bin/mkimap

This will spew a few lines saying that it created some files/dirs. If there are any errors, take care of them and try again. mkimap can only be run as the cyrus user, thus using sudo to run it as the cyrus user is required.

Make it so that cyrus will be started with the system by adding the following to the end of /etc/rc.conf:
Start cyrus-imapd22:
/usr/local/etc/rc.d/ start

If you go back and look in /usr/local/imap/ you'll notice some more files have been created there just now.

Compile and install postfix 2.3.x
Compile postfix:
cd /usr/ports/mail/postfix

A menu will appear asking you to select various options. This is mostly up to your own needs, but you'll want to make sure you select the TLS, SASL2, DB3 (provided SASL2 was built with it, which it is by default), and MySQL options at the very least. Make sure the "disable PCRE" option is not checked. I also use SPF but that patch has sometimes needed a little reworking in the past to make it work with other options and I won't cover that or how to configure for SPF in this document.

Install postfix:
make install

At this point you'll be asked if you want to replace sendmail to which you need to answer Yes. Once done it will then mention two different sets of lines to add to your /etc/rc.conf. One set would be good if your postfix didn't depend on anything else, and another more suited to our needs. Make sure


is set in in your /etc/rc.conf file. The reason for this line is because our postfix will depend on a MySQL server having been started at (or about) the same time.

Make it so postfix will start with the system:
ln -s /usr/local/sbin/postfix /usr/local/etc/rc.d/
You will also be asked to add the following to your /etc/periodic.conf :

Clean up after the mess we've made:
make clean
Create an SSL key and certificate (self-signed is fine) and place them both in the /usr/local/etc/postfix/postfix.pem file. I can't find the link I last used to generate a self-signed cert and key, but a quick search on Yahoo or Google will turn up a ton of them for you.
Once your postfix.pem file has been created, set permissions on it:
chown root:wheel postfix.pem
chmod o-rwx postfix.pem

Find and set the following in
mydestination = $myhostname, localhost.$mydomain
local_recipient_maps = $alias_maps
relay_domains = $mydestination $transport_maps
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
recipient_delimiter = +
mailbox_transport = cyrus
smtpd_banner = $myhostname ESMTP $mail_name

Tell postfix to only deliver one message at a time via cyrus. This line is added to

Configure postfix to offer smtp auth only when TLS is active and enable TLS by adding the following to your
virtual_alias_maps = mysql:/usr/local/etc/postfix/
virtual_mailbox_domains = mysql:/usr/local/etc/postfix/
virtual_mailbox_maps = mysql:/usr/local/etc/postfix/
virtual_mailbox_limit = 10240000
virtual_transport = cyrus

broken_sasl_auth_clients = yes
smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination
smtpd_sasl_auth_enable = yes
smtpd_sasl_local_domain = $mydomain
smtpd_sasl_security_options = noanonymous

smtp_use_tls = yes
smtpd_use_tls = yes
smtp_tls_note_starttls_offer = no
smtpd_tls_key_file = /usr/local/etc/postfix/postfix.pem
smtpd_tls_cert_file = /usr/local/etc/postfix/postfix.pem
smtpd_tls_CAfile =
smtpd_tls_loglevel = 1
smtpd_tls_received_header = yes
smtpd_tls_session_cache_timeout = 3600s
smtpd_tls_session_cache_database = btree:/usr/local/etc/postfix/smtpd_scache
tls_random_source = dev:/dev/urandom
smtpd_tls_auth_only = yes

If you have a CA file for your SSL/TLS cert, then be sure to set smtpd_tls_CAfile to point at it as well in the part above.

Create the smtpd_scache files:
touch /usr/local/etc/postfix/smtpd_scache
postmap btree:/usr/local/etc/postfix/smtpd_scache

I've been told that some books and how-tos say to use sdbm instead of btree. Apparently the TLS support in Postfix 2.2.x only supports btree, and in fact if you look at the current manual it only mentions btree in its example.

Create and add the following to /usr/local/etc/postfix/ :
user = postfix
password = password
hosts = localhost
dbname = postfix
table = alias
select_field = goto
where_field = address

Create and add the following to /usr/local/etc/postfix/ :
user = postfix
password = password
hosts = localhost
dbname = postfix
table = domain
select_field = description
where_field = domain

Create and add the following to /usr/local/etc/postfix/ :
user = postfix
password = password
hosts = localhost
dbname = postfix
table = mailbox
select_field = username
where_field = username

Create and add the following to /usr/local/lib/sasl2/smtpd.conf :
pwcheck_method: auxprop
auxprop_plugin: sql
sql_user: postfix
sql_passwd: password
sql_hostnames: localhost
sql_database: postfix
sql_select: SELECT password FROM mailbox WHERE username='%u@%r' AND active='1'
sql_verbose: yes
sql_engine: mysql
mech_list: plain
minimum_layer: 0
auto_transition: no
password_format: crypt

Make sure the path to the cyrus deliver program is correct and set the user delivery name properly in
cyrus unix - n n - - pipe
user=cyrus argv=/usr/local/cyrus/bin/deliver -e -r ${sender} -m ${extension} ${user}@${nexthop}

Now edit /etc/aliases and set root to alias to youradminuser@domain1.tld. Add another alias for cyrus to point to postmaster and make sure postmaster is aliased to root (it should be). These lines (not placed together in the file) will look like this:
root: youradminuser@domain1.tld
postmaster: root
cyrus: postmaster

If you don't use a fully qualified email address for the root alias then the system will assume user@host.domain1.tld which will not have a valid user for postfix or cyrus to deliver to. Once done, run newaliases. Later on once creating users/aliases with postfixadmin, make sure you create this user or an alias from that alias to your virtual user.

But Ed, we haven't created the database or tables in MySQL yet! Nope, we haven't. We're going to do that in a bit when we get to postfixadmin as that port includes the MySQL scheme files.
We'll be using a default Apache 2.2.x installation for this:

cd /usr/ports/www/apache22
make %26amp;%26amp; make install %26amp;%26amp; make clean %26amp;%26amp; rehash

Add the following to /etc/rc.conf:


Install the PHP4 base:
cd /usr/ports/lang/php4
make %26amp;%26amp; make install %26amp;%26amp; make clean

The default options here should be fine. Make sure the Apache2 checkbox is checked, though.

Now to compile and install the PHP4 extentions:
cd /usr/ports/lang/php4-extensions/
make %26amp;%26amp; make install %26amp;%26amp; make clean

This is where the major fun for PHP4 is. In the selection menu that comes up, you'll need the following at a minimum for all of this: imap, mcrypt, mhash, MySQL, OpenSSL, and PCRE. There'll be some other stuff selected and that's fine. Once this is done your options will be saved to the file /var/db/ports/php4-extensions/options. If you need/want to change the options later you can edit that file, or (better yet) run make config instead.

By default no php.ini file is installed, but we'll need one.
cp /usr/local/etc/php.ini-recommended /usr/local/etc/php.ini
chmod u+w /usr/local/etc/php.ini

In a bit we'll need to make a couple changes to it which is why we're making it writable by root (the owner).

Open /usr/local/etc/apache2/httpd.conf and find the DirectoryIndex directive and add index.php to it so that it looks like:
DirectoryIndex index.html index.html.var index.php

Now add the following to /usr/local/etc/apache2/Includes/mine.conf :
AddType application/x-httpd-php .php
AddType application/x-httpd-php-source .phps

SquirrelMail will need the pear-DB port installed, but the SM port doesn't install it for some reason so we'll take care of that now:
cd /usr/ports/databases/pear-DB
make install %26amp;%26amp; make clean

Edit /usr/local/etc/php.ini and find the include_path setting (it will be commented out with a ";") and set it to be like the following:
include_path = ".:/usr/local/share/pear/"

Installing phpMyAdmin is optional but might be handy. Feel free to skip it.

cd /usr/ports/databases/phpmyadmin/
make %26amp;%26amp; make install %26amp;%26amp; make clean

Now add the following to /usr/local/etc/apache2/Includes/mine.conf :

Alias /phpmyadmin/ "/usr/local/www/phpMyAdmin/"

Options Indexes MultiViews
AllowOverride None
Order deny,allow
allow from
deny from all

You'll want to add your IP address in there, and any others on seperate allow lines, for each host you want to grant access to phpMyAdmin. You don't want the world to have access to this, do you?

Go edit the phpMyAdmin config file appropriately so it'll actually work and be a little more secure (requiring a password, etc).

cd /usr/ports/mail/postfixadmin
make install

Copy the MySQL scheme file for use in a bit:
cp work/postfixadmin-2.1.0/DATABASE_MYSQL.TXT ~/

Clean up and rehash (for fun!):
make clean ; rehash

Now let's install the DB scheme that we'll be using for pretty much everything. These instructions are mostly from the DATABASE_MYSQL.TXT file:
mysql -u root -p < ~/DATABASE_MYSQL.TXT

Note that this file inserts two users into the MySQL user table, one for postfix itself and another for postfixadmin. The actual passwords are the same as the username by default. You should edit the file to change the passwords to something better than the defaults and then go back and set that changed password for the files used by postfix and cyrus if you didn't set those already.

Now add the following to /usr/local/etc/apache2/Includes/mine.conf :
Alias /postfixadmin/ "/usr/local/www/postfixadmin/"

Options Indexes
AllowOverride AuthConfig
Order allow,deny
Allow from all

postfixadmin has three modes: admin, user, and domain admin. admin mode will be used by you to do everything. user mode will be used by your users to change their passwords and set their forwarding address when/if needed. domain admin will be used by the users whom you're hosting a mail domain for - they can login and admin their own domains to add/remove/ users and aliases.

Fix the postfixadmin dir permissions:
cd /usr/local/www/
chown -R root:www postfixadmin
cd postfixadmin

Edit and make things nice. Things of primary note will be the username and password (if changed from the above DB scheme install) for the postfix database and the virtual mail tables, and the password format to generate which needs to be set to md5crypt.
Fix annoying create-mailbox checkbox which we'll never use:
joe templates/create-mailbox.tpl

Remove the checked option from the HTML tag named fMail which is near the bottom of the page. You will not be using this option at all. No point in always having to uncheck it, right? And really, you can just comment out that whole part so it doesn't blemish the world.

Fix a bug in their code which breaks this app. with MySQL:
Somewhere in the 4.4.x line of PHP they added support for using various charactor sets properly when escaping strings with mysql_real_escape_string(). Unfortunatly this requires that you have an active connection to the database server. At several points in the postfixadmin code they escape the user inputted strings (which is very good) before they have established a connection to any database server (in this case that's bad). To fix this, open the file and find the escape_string function. You need to add a call to the function db_connect() inside the block that has the three IF statements. So it'll have the db_connect() call, then the three IF statements. Don't forget to add the semi-colon to the end of the line and then save it.
Fire up a browser and go to http://somehost/postfixadmin/ and it'll say some poop about needing to run setup. The setup isn't really a setup so much as a checkup. Once you click on the setup link, you should see a list of stuff all saying OK. It'll probably complain about PHPs magic quotes being off, but ignore that as postfixadmin has its own internal work-around. Click on the link to continue into the admin section.
Disable setup.php:
mv setup.php setup.hph

If the file remains, even if unreadable by apache, postfixadmin will always want to run its little "setup" poop which is pointless since we've already done it. You could probably just rm this file, but you might need it again for some reason.

Change the admin password:
htpasswd -mb admin/.htpasswd admin NewPassword

Feel free to substitute the username admin for another, but make sure you also either remove the admin user or change its password. The -m option says to generate an MD5 hashed password, and the -b says that the password will be supplied on the commandline. Feel free to omit the -b option and password on the commandline so that it prompts you for it instead. I only use that option for this document to make it easier to cut%26amp;waste.

Note: If after installation when you go to list aliases/mailboxes for a domain, but cannot select other domains and get an SQL error and your Apache error logs shows that access is denied for a user other than the postfixadmin (in my case it was saying root@localhost even though the MySQL root user is never used), you'll probably also see an error about the file on line 131. Change the mysql_real_escape_string to mysql_escape_string and try again. After a while I upgraded some software and then had to make this change in order to keep postfixadmin working properly. The problem is that mysql_real_escape_string requires that the MySQL connection handle be passed to it, but in this case is not. Oh well.
Install SquirrelMail:
cd /usr/ports/mail/squirrelmail
make install

Now we need to add a database and tables to MySQL for the user preferences and address books:
First, create the database squirrelmail will use:
mysqladmin create squirrelmail

Next, open up work/squirrelmail-1.4.4/doc/db-backend.txt and copy the two MySQL table sections to another file called tables.txt. We'll also create our SM user, set their password, and give them access to the SM database. The temporary file should look like the following:
USE squirrelmail;

GRANT select,insert,update,delete ON squirrelmail.* TO squirreluser@localhost IDENTIFIED BY 'sqpassword';

CREATE TABLE address (
owner varchar(128) DEFAULT '' NOT NULL,
nickname varchar(16) DEFAULT '' NOT NULL,
firstname varchar(128) DEFAULT '' NOT NULL,
lastname varchar(128) DEFAULT '' NOT NULL,
email varchar(128) DEFAULT '' NOT NULL,
label varchar(255),
PRIMARY KEY (owner,nickname),
KEY firstname (firstname,lastname)

CREATE TABLE userprefs (
user varchar(128) DEFAULT '' NOT NULL,
prefkey varchar(64) DEFAULT '' NOT NULL,
PRIMARY KEY (user,prefkey)

Now create our user and tables:
mysql -u root -p < tables.txt

And clean up after our mess:
make clean
rm tables.txt

Now add the following to /usr/local/etc/apache2/Includes/mine.conf :
Alias /squirrelmail/ "/usr/local/www/squirrelmail/"

Options Indexes MultiViews
AllowOverride None
Order allow,deny
Allow from all

Get, install, and configure everything we need:
The following plugins are the bare minimum that we'll need for out SquirrelMail setup. It should go without saying that the versions of the following plugins were current at the time of the inital writing of this how-to but have since been upgraded. As time permits I'll update this to reflect those updates, but make sure you check for the latest versions yourself. The installation of these should change much with their updates, but that can change, so keep that in mind. When in doubt RTFM.

This provides some needed APIs used by various plugins in order to be used with multiple versions of SM. In particular we'll be needing this for the vlogin plugin. You're likely to need it for other plugins as well. We'll use the port to install this for us:

cd /usr/ports/mail/squirrelmail-compatibility-plugin/
make install %26amp;%26amp; make clean

avelsieve is brought to us by the same people that made the autocreate patches for cyrus-imapd22. Currently you can get this plugin from, but be sure to check for updates.

cd /usr/local/www/squirrelmail/plugins
tar xvfz ~/avelsieve-1.9.2.tar.gz
chown -R root:www avelsieve
cd avelsieve/config
cp config_sample.php config.php
cd ../..

Currently you can get this plugin from Extract and set permissions:

cd /usr/local/www/squirrelmail/plugins
tar xvfz ~/quota_usage-1.3-1.2.7.tar.gz
chown -R root:www quota_usage
cd quota_usage
cp config.php.sample config.php
cd ..

Install the plugin:
cd /usr/ports/mail/squirrelmail-vlogin-plugin
make install %26amp;%26amp; make clean

In the event your system does not have the vlogin port, you'll need to get it from After that the extraction is just like the other plugins:

cd /usr/local/www/squirrelmail/plugins
tar xvfz ~/vlogin-3.8.0-1.2.7.tar.gz
chown -R root:www avelsieve

Copy the sample config to our inital config:
cd /usr/local/www/squirrelmail/plugins/vlogin/data
cp config.php.sample.typical config.php

Now edit config.php and find the $virtualDomains array define near the top. It'll have a couple virtual domains defined already, but we're going to replace them:
'host.domain1.tld' => array(
'domain' => 'domain1.tld',
'org_name' => 'Domain One',
'org_title' => '(isset( FreeBSD Virtual Mail How-To - 站长学院

Copyright © 2016 phpStudy | 皖ICP备18014864号-4