Вы находитесь на странице: 1из 39

OpenBSD Mailserver

Written by Bart Dorlandt


Friday, 18 April 2008 22:08 - Last Updated Friday, 13 February 2009 15:30
I followed this guide at kernel-panic.it . Below you'll find a small steps-to-follow guide with some
additions.

What to build

I've set-up a mailserver that supports multiple domains. It uses:

- Postfix as MTA (with greylisting)
- Postgrey
- MySQL as backend
- Dovecot as IMAP/POP3 server and Local Delivery Agent (LDA)
- with quota

- Control plane by amavisd for:

- Anti-spam with Spam Assassin

- Anti-virus with clamav

- Fetchmail to fetch remote email and inject it in your mailserver
- Squirrelmail for webmail.

What to install

At the time of writing I use OpenBSD 4.2. I make use of packages and ports to make this all
work.

1 / 39
OpenBSD Mailserver
Written by Bart Dorlandt
Friday, 18 April 2008 22:08 - Last Updated Friday, 13 February 2009 15:30

Postfix

First we'll install postfix with mysql support. If you also want to use sasl support you'll need to
use ports, because there is no package which support them both.
pkg_add -ai postfix-2.5.20070531-mysql

After this step we'll enable and configure postfix.

/usr/local/sbin/postfix-enable
echo'sendmail_flags="-bd"' >> /etc/rc.conf.local
echo 'syslogd_flags="-a /var/spool/postfix/dev/log"' >> /etc/rc.conf.local

Next, remove the "sendmail clientmqueue runner" from root's crontab.

Below you'll see my configuration of the file: /etc/postfix/main.cf. Use it or tune it as you
please.

#soft_bounce = no
queue_directory = /var/spool/postfix
command_directory = /usr/local/sbin
daemon_directory = /usr/local/libexec/postfix
mail_owner = _postfix
#default_privs = nobody
myhostname = smtp.bamweb.nl
mydomain = bamweb.nl
myorigin = bamweb.nl
inet_interfaces = all
inet_protocols = all
#proxy_interfaces =
#proxy_interfaces = 1.2.3.4
2 / 39
OpenBSD Mailserver
Written by Bart Dorlandt
Friday, 18 April 2008 22:08 - Last Updated Friday, 13 February 2009 15:30
mydestination = localhost.$mydomain, localhost
smtpd_helo_required = yes
disable_vrfy_command = yes
strict_rfc821_envelopes = yes
### Dovecot LDA ###
# To use it for everything
#mailbox_command = /usr/local/libexec/dovecot/deliver
# To use it virtually, which is needed to use plugins like quota, or to enable logging.
virtual_transport = dovecot
dovecot_destination_recipient_limit = 1
invalid_hostname_reject_code = 554
multi_recipient_bounce_reject_code = 554
non_fqdn_reject_code = 554
relay_domains_reject_code = 554
unknown_address_reject_code = 554
unknown_client_reject_code = 554
unknown_hostname_reject_code = 554
unknown_local_recipient_reject_code = 554
unknown_relay_recipient_reject_code = 554
unknown_sender_reject_code = 554
unknown_virtual_alias_reject_code = 554
unknown_virtual_mailbox_reject_code = 554
unverified_recipient_reject_code = 554
unverified_sender_reject_code = 554
# I have my server in a datacenter, so I don't need to have my clients
# use this as an smtp server. Else put your trusted networks behind this range
# seperated by a comma.
mynetworks = 127.0.0.0/8
relay_domains = $mydestination, hash:/etc/postfix/relay_domains
#relayhost = $mydomain
#relayhost = [gateway.my.domain]
#relayhost = uucphost
#relayhost = [an.ip.add.ress]
#relay_recipient_maps = hash:/etc/postfix/relay_recipients
relay_recipient_maps =
#in_flow_delay = 1s
recipient_delimiter = +
smtpd_banner = $myhostname ESMTP $mail_name
3 / 39
OpenBSD Mailserver
Written by Bart Dorlandt
Friday, 18 April 2008 22:08 - Last Updated Friday, 13 February 2009 15:30
sendmail_path = /usr/local/sbin/sendmail
newaliases_path = /usr/local/sbin/newaliases
mailq_path = /usr/local/sbin/mailq
setgid_group = _postdrop
html_directory = /usr/local/share/doc/postfix/html
manpage_directory = /usr/local/man
sample_directory = /etc/postfix
readme_directory = /usr/local/share/doc/postfix/readme
# List of alias databases used by the local delivery agent
alias_maps = hash:/etc/postfix/aliases
alias_database = hash:/etc/postfix/aliases
virtual_mailbox_domains = mysql:/etc/postfix/mysql_virtual_domains.cf
virtual_mailbox_base = /var/mail/vhosts
virtual_mailbox_maps = mysql:/etc/postfix/mysql_virtual_mailboxes.cf
virtual_minimum_uid = 2000
virtual_uid_maps = static:2000
virtual_gid_maps = static:2000
virtual_alias_maps = mysql:/etc/postfix/mysql_virtual_alias_maps.cf
mysql:/etc/postfix/mysql_virtual_email2email.cf
# You may change your size limit, if you experience errors
message_size_limit = 20480000
#queue_minfree = 120000000
#-------------Greylisting + Postgrey ----------------#
smtpd_recipient_restrictions = permit_mynetworks,
permit_mx_backup,
reject_invalid_hostname,
check_relay_domains,
reject_non_fqdn_hostname,
reject_non_fqdn_sender,
reject_non_fqdn_recipient,
reject_unknown_sender_domain,
reject_unknown_recipient_domain,
reject_unauth_destination,
reject_rbl_client relays.ordb.org,
reject_rbl_client opm.blitzed.org,
reject_rbl_client list.dsbl.org,
reject_rbl_client sbl.spamhaus.org,
reject_rbl_client cbl.abuseat.org,
reject_rbl_client dul.dnsbl.sorbs.net,
reject_rbl_client dev.null.dk,
reject_rbl_client virbl.dnsbl.bit.nl,
reject_rbl_client smtp.dnsbl.sorbs.net,
4 / 39
OpenBSD Mailserver
Written by Bart Dorlandt
Friday, 18 April 2008 22:08 - Last Updated Friday, 13 February 2009 15:30
reject_rbl_client socks.dnsbl.sorbs.net,
reject_rbl_client http.dnsbl.sorbs.net,
reject_rbl_client web.dnsbl.sorbs.net,
# leave the next line out if you don't want to use postgrey
check_policy_service inet:127.0.0.1:60000
permit
# This command is use to forward the emails to the amavis daemon
content_filter = smtp-amavis:[127.0.0.1]:10024
# in case you want different bounce messages
bounce_template_file = /etc/postfix/bounce.cf

Here we prepare the postfix /etc/postfix/master.cf configuration for amavisd. The number 4 is
related to the $max_server you will define in
amavisd.conf

smtp-amavis unix - - y - 4 smtp
-o smtp_data_done_timeout=1200
-o smtp_send_xforward_command=yes
-o disable_dns_lookups=yes
-o max_use=20
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_delay_reject=no
-o smtpd_client_restrictions=permit_mynetworks,reject
-o smtpd_helo_restrictions=
-o smtpd_sender_restrictions=
-o smtpd_recipient_restrictions=permit_mynetworks,reject
-o mynetworks_style=host
-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 smtpd_client_connection_count_limit=0
-o smtpd_client_connection_rate_limit=0
-o receive_override_options=no_header_body_checks,no_unknown_recipient_checks
5 / 39
OpenBSD Mailserver
Written by Bart Dorlandt
Friday, 18 April 2008 22:08 - Last Updated Friday, 13 February 2009 15:30
dovecot unix - n n - - pipe flags=DRhu user=vmail:vmail argv=/usr/local/libexec/dovecot/deliver
-d $(recipient)

file: /etc/postfix/bounce.cf

#
# The failure template is used when mail is returned to the sender;
# either the destination rejected the message, or the destination
# could not be reached before the message expired in the queue.
#
failure_template = <<EOF
Charset: us-ascii
From: MAILER-DAEMON (Mail Delivery System)
Subject: Undelivered Mail Returned to Sender
Postmaster-Subject: Postmaster Copy: Undelivered Mail
This is the mail system at host $myhostname.
I'm sorry to have to inform you that your message could not
be delivered to one or more recipients. It's attached below.
For further assistance, please send mail to <postmaster>
If you do so, please include this problem report. You can
delete your own text from the attached returned message.
The mail system
EOF
#
# The delay template is used when mail is delayed. Note a neat trick:
# the default template displays the delay_warning_time value as hours
# by appending the _hours suffix to the parameter name; it displays
# the maximal_queue_lifetime value as days by appending the _days
# suffix.
#
# Other suffixes are: _seconds, _minutes, _weeks. There are no other
# main.cf parameters that have this special behavior.
#
# You need to adjust these suffixes (and the surrounding text) if
6 / 39
OpenBSD Mailserver
Written by Bart Dorlandt
Friday, 18 April 2008 22:08 - Last Updated Friday, 13 February 2009 15:30
# you have very different settings for these time parameters.
#
delay_template = <<EOF
Charset: us-ascii
From: MAILER-DAEMON (Mail Delivery System)
Subject: Delayed Mail (still being retried)
Postmaster-Subject: Postmaster Warning: Delayed Mail
This is the mail system at host $myhostname.
####################################################################
# THIS IS A WARNING ONLY. YOU DO NOT NEED TO RESEND YOUR MESSAGE. #
####################################################################
Your message could not be delivered for more than $delay_warning_time_hours hour(s).
It will be retried until it is $maximal_queue_lifetime_days day(s) old.
For further assistance, please send mail to <postmaster>
If you do so, please include this problem report. You can
delete your own text from the attached returned message.
The mail system
EOF
#
# The success template is used when mail is delivered to mailbox,
# when an alias or list is expanded, or when mail is delivered to a
# system that does not announce DSN support. It is an error to specify
# a Postmaster-Subject: here.
#
success_template = <<EOF
Charset: us-ascii
From: MAILER-DAEMON (Mail Delivery System)
Subject: Successful Mail Delivery Report
This is the mail system at host $myhostname.
Your message was successfully delivered to the destination(s)
listed below. If the message was delivered to mailbox you will
receive no further notifications. Otherwise you may still receive
notifications of mail delivery errors from other systems.
7 / 39
OpenBSD Mailserver
Written by Bart Dorlandt
Friday, 18 April 2008 22:08 - Last Updated Friday, 13 February 2009 15:30
The mail system
EOF
#
# The verify template is used for address verification (sendmail -bv
# address...). or for verbose mail delivery (sendmail -v address...).
# It is an error to specify a Postmaster-Subject: here.
#
verify_template = <<EOF
Charset: us-ascii
From: MAILER-DAEMON (Mail Delivery System)
Subject: Mail Delivery Status Report
This is the mail system at host $myhostname.
Enclosed is the mail delivery report that you requested.
The mail system
EOF

Postfix & MySQL files

create each of these files in /etc/postfix/ and add the information to it. I use the socket of mysql.
How this is done in chrooted apache will be described later at bootscripts.

In these examples I have use the user and password vmail. You may change this to whatever
you like. Also you can change the name of the database. I've used
mail
.

/etc/postfix/mysql_virtual_alias_maps.cf

user = vmail
password = vmail
hosts = unix:/var/run/mysql/mysql.sock
dbname = mail
query = SELECT alias FROM alias_maps WHERE account='%s'
8 / 39
OpenBSD Mailserver
Written by Bart Dorlandt
Friday, 18 April 2008 22:08 - Last Updated Friday, 13 February 2009 15:30

/etc/postfix/mysql_virtual_domains.cf

user = vmail
password = vmail
hosts = unix:/var/run/mysql/mysql.sock
dbname = mail
query = SELECT domain FROM domains WHERE domain='%s'

/etc/postfix/mysql_virtual_mailboxes.cf

user = vmail
password = vmail
hosts = unix:/var/run/mysql/mysql.sock unix:/var/spool/postfix/var/run/mysql/mysql.sock
dbname = mail
query = SELECT maildir FROM users WHERE login='%s'

/etc/postfix/mysql_virtual_email2email.cf

user = vmail
password = vmail
hosts = unix:/var/run/mysql/mysql.sock
dbname = mail
query = SELECT login FROM users WHERE login='%s'

We have made all the preparations. Now we are going to setup Postgrey.


Postgrey

I have installed Postgrey from "Ports". The advantage this way is you'll have the postgreyreport
9 / 39
OpenBSD Mailserver
Written by Bart Dorlandt
Friday, 18 April 2008 22:08 - Last Updated Friday, 13 February 2009 15:30
tool also installed. With this tool you can create a report out of your /var/log/maillog.

cd /usr/ports/mail/postgrey
make install
cp -p /usr/local/share/examples/postgrey/* /etc/postfix/

You may want to edit postgrey_whitelist_recipients and add the emails of users for which you
don't want greylisting.

At the end we will make the startup scripts. Up to MySQL.


MySQL

Now we will install the MySQL server. This is done by the following command.

pkg_add -ai mysql-server

Copy an example configuration that fits your needs to /etc. For example:

cp /usr/local/share/mysql/my-small.cnf /etc/my.cnf
10 / 39
OpenBSD Mailserver
Written by Bart Dorlandt
Friday, 18 April 2008 22:08 - Last Updated Friday, 13 February 2009 15:30

Now we can edit this file. I don't want to be able to connect to this database from anywhere else
than localhost. So, I use the following command and place it in the [mysqld] section. I have
placed some configuration for the logging here.

bind-address = 127.0.0.1
expire_logs_days = 10
max_binlog_size = 50M

You may use this file also in your home directory (or the one of root) so you can access your
database with more ease by filling in the password in the file. Rename the file to .my.cnf

NOTE: this isn't the safest trick...

I like to use an own class for mysql. To do this add the following to the login.conf. (copy-paste
will do the trick)

echo "" >> /etc/login.conf
echo "mysql:" >> /etc/login.conf
echo " :openfiles-cur=1024:" >> /etc/login.conf
echo " :openfiles-max=2048:" >> /etc/login.conf
echo " :tc=daemon:" >> /etc/login.conf
echo "" >> /etc/login.conf

Ok, now we are going to set the password of the database.

/usr/local/bin/mysql_install_db

11 / 39
OpenBSD Mailserver
Written by Bart Dorlandt
Friday, 18 April 2008 22:08 - Last Updated Friday, 13 February 2009 15:30
su -c mysql root -c '/usr/local/bin/mysqld_safe &'
mysqladmin -u root password <choose one>

Connect to your mysql server with the client with the root account mysql -u root -p and fill in
the requested password. Expand the mysql insertion to your need. For example insertion of
domains
,
users
or
alias_maps
. Please note we use default values for uid, gid, home and quota, so you don't need to add it,
unless it is different.

NOTE: remember! My values are in here, check them first before you paste it into your
mysql-client.

What this piece of text does is the following:

Create the database and use it:

CREATE DATABASE `mail`;
USE `mail`;

Create the user vmail and give it the rights on the database mail.

CREATE USER 'vmail'@'localhost' IDENTIFIED BY 'vmail';
GRANT SELECT , INSERT , UPDATE , DELETE ON `mail` . * TO 'vmail'@'localhost';

Create the tabel alias_maps and fill it up.
12 / 39
OpenBSD Mailserver
Written by Bart Dorlandt
Friday, 18 April 2008 22:08 - Last Updated Friday, 13 February 2009 15:30

CREATE TABLE `alias_maps` (
`account` varchar(80) NOT NULL default '',
`alias` text NOT NULL,
PRIMARY KEY (`account`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
INSERT INTO `alias_maps` (`account`, `alias`) VALUES
('bart@domain2.tld', 'bart@domain1.tld'),
('bart@localhost', 'bart@domain1.tld'),
('webmaster@domain1.tld', 'bart@domain1.tld'),
('postmaster@domain1.tld', 'bart@domain1.tld'),
('bart.dorlandt@domain1.tld', 'bart@domain1.tld'),
('@domain1.tld', 'admin@domain1.tld'),
('@domain2.tld', 'admin@domain1.tld'),
('more@domain1.tld', 'bart@domain1.tld,user1@gmail.com,user2hotmail.com');

Create the tabel domains and fill it up.

CREATE TABLE `domains` (
`domain` varchar(50) NOT NULL default '',
PRIMARY KEY (`domain`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
INSERT INTO `domains` (`domain`) VALUES
('domain1.tld'),
('domain2.tld');

Create the tabel users and fill it up

CREATE TABLE `users` (
`login` varchar(255) NOT NULL,
`uid` smallint(6) NOT NULL default '2000',
`gid` smallint(6) NOT NULL default '2000',
`home` varchar(255) NOT NULL default '/var/mail/vhosts',
`name` varchar(255) NOT NULL,
`password` varchar(13) NOT NULL,
13 / 39
OpenBSD Mailserver
Written by Bart Dorlandt
Friday, 18 April 2008 22:08 - Last Updated Friday, 13 February 2009 15:30
`maildir` varchar(255) NOT NULL,
`quota` varchar(10) NOT NULL,
PRIMARY KEY (`login`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
INSERT INTO `users` (`login`, `name`, `password`, `maildir`,) VALUES
('bart@domain1.tld', 'Bart Dorlandt', ENCRYPT('password'), 'domain1.tld/bart/');


Dovecot

Dovecot is a very small and quick IMAP/POP3 server. It is capable of doing IMAP, IMAPS,
POP, POPS. Did I mention it is easy to configure... For some extra info for configuring the SQL
part, take a look here . Recently, I also included quota support. For this to work you need to
have the LDA served by dovecot and you need to enable the plugins. If you don't want the
quota support just disable the plugin.

Now we will install the Dovecot Imapserver. This is done by the following command. (make sure
you select package with mysql support)
pkg_add -ai dovecot

Edit the following file to your needs: /etc/ssl/dovecot-openssl.cnf
Execue the following command.

/usr/local/sbin/dovecot-mkcert.sh

changes to /etc/dovecot.conf

14 / 39
OpenBSD Mailserver
Written by Bart Dorlandt
Friday, 18 April 2008 22:08 - Last Updated Friday, 13 February 2009 15:30
protocols = imap imaps pop3s
protocol imap {
listen = 127.0.0.1:143
ssl_listen = *:993
}
disable_plaintext_auth = yes
log_path = /var/log/dovecot.log
ssl_listen = *
ssl_cert_file = /etc/ssl/dovecotcert.pem
ssl_key_file = /etc/ssl/private/dovecot.pem
mail_location = maildir:/var/mail/vhosts/%d/%n
first_valid_uid = 2000
last_valid_uid = 2000
first_valid_gid = 2000
last_valid_gid = 2000
maildir_copy_with_hardlinks = yes
protocol imap {
mail_plugins = quota imap_quota
}
protocol pop3 {
mail_plugins = quota
pop3_client_workarounds = outlook-no-nuls oe-ns-eoh
}
protocol lda {
mail_plugins = quota
sendmail_path = /usr/local/sbin/sendmail
auth_socket_path = /var/run/dovecot/auth-master
log_path = /var/log/dovecot-deliver.log
info_log_path = /var/log/dovecot-deliver.log
}
auth default {
mechanisms = plain login digest-md5
passdb sql {
args = /etc/dovecot-sql.conf
}
userdb prefetch {
}
userdb sql {
15 / 39
OpenBSD Mailserver
Written by Bart Dorlandt
Friday, 18 April 2008 22:08 - Last Updated Friday, 13 February 2009 15:30
args = /etc/dovecot-sql.conf
}
socket listen {
master {
path = /var/run/dovecot/auth-master
mode = 0660
# Default user/group is the one who started dovecot-auth (root)
user = vmail
group = vmail
}
client {
user = _postfix
group = _postfix
path = /var/spool/postfix/private/auth
mode = 0660
}
}
}
plugin {
quota = maildir
}

changes to /etc/dovecot-sql.conf

Take a look here for configuring the extra fields. This is the default file, change values if
needed.You to get the quota and other information during the prefetch to work with quotas.

driver = mysql
connect = host=/var/run/mysql/mysql.sock dbname=mail user=vmail password=mailv
default_pass_scheme = CRYPT
### with prefetch and quota ###
user_query = SELECT uid, gid, home, maildir as mail, concat('maildir:storage=',quota) AS
quota FROM users WHERE login = '%u'
password_query = SELECT password, uid AS userdb_uid, gid AS userdb_gid, home AS
userdb_home, maildir as userdb_mail, concat('maildir:storage=', quota) AS userdb_quota
FROM users WHERE login = '%u'

16 / 39
OpenBSD Mailserver
Written by Bart Dorlandt
Friday, 18 April 2008 22:08 - Last Updated Friday, 13 February 2009 15:30


Fetchmail

Fetchmail is a very nice program to fetch mails from other servers. I use it to read POP
addresses and put the emails in my IMAP mailbox.

Now we will install the Fetchmail. This is done by the following command.

pkg_add -ai fetchmail

Below you'll find my config.

set daemon 300
#set logfile /var/log/fetchmail
set no bouncemail
defaults
protocol pop3
poll pop.<domain1>.nl
user <remote_user> pass <password> is <localuser1> here nokeep
poll pop.<domain2>.nl
user <remote_user> pass <password> is <localuser2> here nokeep
# keep in mind that the localuser in this
# howto is in fact "user@domain.tld"

17 / 39
OpenBSD Mailserver
Written by Bart Dorlandt
Friday, 18 April 2008 22:08 - Last Updated Friday, 13 February 2009 15:30


ClamAV

Make sure you have the newest updates of your ports of the current tree. For more info on how
to do that, you may check the info on the openBSD port page .

You can check if you have the newest files by doing:

head -n1 /usr/ports/security/clamav/Makefile

if it is at least version 1.37 you are fine.

Ok, lets continue. By executing the following commands you will install clamav with support for
unrar and unarj.

cd /usr/ports/archivers/unarj/
make
make install
cd /usr/ports/archivers/unrar/
make
make install
cd /usr/ports/security/clamav/
make
make install

18 / 39
OpenBSD Mailserver
Written by Bart Dorlandt
Friday, 18 April 2008 22:08 - Last Updated Friday, 13 February 2009 15:30
When this is finished we can edit the two files in your etc directory; freshclam.conf and clamd.co
nf . First
we will edit freshclam.conf. For the first entry of of the DatabaseMirror you might want change it
to your country code. Check the rest of the configuration and make sure these values are set.

DatabaseDirectory /var/db/clamav
DatabaseOwner _clamav
DNSDatabaseInfo current.cvd.clamav.net
DatabaseMirror db.nl.clamav.net
DatabaseMirror database.clamav.net
MaxAttempts 3
checks 24

Now you may start freshclam to download the latest patches.

freshclam

put the following line in your (roots) crontab to execute this every hour. So your virusscanner will
be kept up to date.

26 * * * * /usr/local/bin/freshclam >/dev/null 2>&1

Next, we will edit clamd.conf

DatabaseDirectory /var/db/clamav
LocalSocket /var/clamav/clamd.sock
User _clamav
TemporaryDirectory /tmp
# if you also want logging enable these
LogFile /var/log/clamd.log
LogFileMaxSize 2M
19 / 39
OpenBSD Mailserver
Written by Bart Dorlandt
Friday, 18 April 2008 22:08 - Last Updated Friday, 13 February 2009 15:30
LogTime yes
LogClean yes
LogFacility LOG_MAIL
LogVerbose yes

you may start it by entering clamd

clamd


Spam Assassin

SpamAssassin is a mature, widely-deployed open source project that serves as a mail filter to
identify Spam. SpamAssassin uses a variety of mechanisms including header and text analysis,
Bayesian filtering, DNS blocklists, and collaborative filtering databases.

Now we will install the SpamAssassin. This is done by the following command.

mkdir -p /var/db/spamassassin
pkg_add -ai p5-Mail-SpamAssassin

SpamAssassin has a lot of configuration option. Only a few are needed to get it working. If you
want to see how to tune the rest you make take a look at the man page ( Mail::SpamAssassin::
Conf ).
20 / 39
OpenBSD Mailserver
Written by Bart Dorlandt
Friday, 18 April 2008 22:08 - Last Updated Friday, 13 February 2009 15:30

You may edit and change the following in this file: /etc/mail/spamassassin/local.cf

rewrite_header Subject ***** SPAM *****
report_safe 1
lock_method flock
required_score 5.0
trusted_networks <your SMTP server IP address>
use_bayes 1
bayes_auto_learn 1
# these aren't needed to get it going, but I use them anyway
ok_languages nl en
ok_locales en


Amavisd

To install Amavisd-new it is required to install freeze. Unfortunately freeze isn't available as a
package. So you need ports to install it. This what we will do first and after it we will install
amavisd-new from package.

cd /usr/ports/archivers/freeze
make
make install
pkg_add -ai amavisd-new

21 / 39
OpenBSD Mailserver
Written by Bart Dorlandt
Friday, 18 April 2008 22:08 - Last Updated Friday, 13 February 2009 15:30
Below you'll find a list of my changed settings. Feel free to change anything.

$max_servers = 4;
$daemon_user = '_clamav';
$daemon_group = '_clamav';
$mydomain = 'bamweb.nl';
$MYHOME = '/var/amavisd';
$TEMPBASE = "$MYHOME/tmp";
$ENV{TMPDIR} = $TEMPBASE;
$QUARANTINEDIR = '/var/clamav/quarantine';
$pid_file = "$MYHOME/var/amavisd.pid";
$lock_file = "$MYHOME/var/amavisd.lock";
@local_domains_maps = ( [".$mydomain","domain1.tld","domain2.tld"] );
$log_level = 5;
$DO_SYSLOG = 1;
$enable_db = 0;
$sa_tag_level_deflt = 2.0; # add spam info headers if at, or above that level
$sa_tag2_level_deflt = 6.31; # add 'spam detected' headers at that level
#$sa_kill_level_deflt = 6.31; # If this is the same as $sa_tag2_level_deflt it will block it
$sa_kill_level_deflt = 25; # if this value is higher then $sa_tag2_level_deflt
# it will forward the email to the client with a change in the header
# spam with a higher mark will be blocked
$sa_dsn_cutoff_level = 9; # spam level beyond which a DSN is not sent
$sa_quarantine_cutoff_level = 20; # spam level beyond which quarantine is off
$recipient_delimiter = '+';
$myhostname = 'hostname.domain.tld';
$final_virus_destiny = D_DISCARD;
$final_banned_destiny = D_BOUNCE;
$final_spam_destiny = D_BOUNCE;
$final_bad_header_destiny = D_PASS;
$virus_quarantine_to = "virus@$mydomain";
$banned_quarantine_to = "banned@$mydomain";
22 / 39
OpenBSD Mailserver
Written by Bart Dorlandt
Friday, 18 April 2008 22:08 - Last Updated Friday, 13 February 2009 15:30
$bad_header_quarantine_to = "bad_header@$mydomain";
# Uncomment the next line to send all spam to this account, else it will just go the user
#$spam_quarantine_to = "spam@$mydomain";
# Don't forget to create these files. In these files you can list an emailaddress per line.
# in Whitelist it will always go through
# in Blacklist it will never go through
@whitelist_sender_maps = read_hash("$MYHOME/whitelist");
@blacklist_sender_maps = read_hash("$MYHOME/blacklist");
@av_scanners = (
# Only uncomment the ClamAV lines which are specified here
# ### http://www.clamav.net/
['ClamAV-clamd',
&ask_daemon, ["CONTSCAN {}n", "/var/clamav/clamd.sock"],
qr/bOK$/, qr/bFOUND$/,
qr/^.*?: (?!Infected Archive)(.*) FOUND$/ ],
# NOTE: the easiest is to run clamd under the same user as amavisd; match the
# socket name (LocalSocket) in clamav.conf to the socket name in this entry
# When running chrooted one may prefer: ["CONTSCAN {}n","$MYHOME/clamd"],
# ### http://www.clamav.net/ and CPAN (memory-hungry! clamd is preferred)
# ['Mail::ClamAV', &ask_clamav, "*", [0], [1], qr/^INFECTED: (.+)/],
);
@av_scanners_backup = (
# ### http://www.clamav.net/ - backs up clamd or Mail::ClamAV
['ClamAV-clamscan', 'clamscan',
"--stdout --disable-summary -r --tempdir=$TEMPBASE {}", [0], [1],
qr/^.*?: (?!Infected Archive)(.*) FOUND$/ ],
);

Create the tmp directory you specified above and test your config:

mkdir -p /var/amavisd/tmp
chown -R _clamav:_clamav /var/amavisd/
/usr/local/sbin/amavisd debug

23 / 39
OpenBSD Mailserver
Written by Bart Dorlandt
Friday, 18 April 2008 22:08 - Last Updated Friday, 13 February 2009 15:30


Squirrelmail

I run everything on the same machine so everything is localhost. Below you'll find the settings
I've changed in $squirrelmail/config/config.php

$domain = 'mail.domain.tld';
$imapServerAddress = '127.0.0.1';
$imapPort = 143;
$useSendmail = false;
$smtpServerAddress = '127.0.0.1';
$imap_server_type = 'courier';
$optional_delimiter = '.';
$default_folder_prefix = '';
$trash_folder = 'INBOX.Trash';
$sent_folder = 'INBOX.Sent';
$draft_folder = 'INBOX.Drafts';
$default_move_to_trash = true;
$default_move_to_sent = true;
$default_save_as_draft = true;
$default_unseen_notify = 3;
$default_unseen_type = 1;
$auto_create_special = true;
$data_dir = '/htdocs/squirrel-attachment/';
$attachment_dir = $data_dir;
$default_left_size = '180';
$plugins[0] = 'abook_take';
$plugins[1] = 'calendar';
$plugins[2] = 'delete_move_next';
$plugins[3] = 'message_details';
$plugins[4] = 'filters';
24 / 39
OpenBSD Mailserver
Written by Bart Dorlandt
Friday, 18 April 2008 22:08 - Last Updated Friday, 13 February 2009 15:30
$theme_default = 17;
$addrbook_dsn = 'mysql://vmail:vmail@127.0.0.1/mail';
$prefs_dsn = 'mysql://vmail:vmail@127.0.0.1/mail';
$addrbook_global_dsn = 'mysql://vmail:vmail@127.0.0.1/mail';
$addrbook_global_writeable = true;
$addrbook_global_listing = true;

Please use the program configure to set-up the configuration to use the template courier for
IMAP settings.

As you can see I use the global addressbook. You'll have to create it along with user
preferences table ande the address table to save a users addressbook.

CREATE TABLE `address` (
`owner` varchar(128) NOT NULL default '',
`nickname` varchar(16) NOT NULL default '',
`firstname` varchar(128) NOT NULL default '',
`lastname` varchar(128) NOT NULL default '',
`email` varchar(128) NOT NULL default '',
`label` varchar(255) default NULL,
PRIMARY KEY (`owner`,`nickname`),
KEY `firstname` (`firstname`,`lastname`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE `global_abook` (
`owner` varchar(128) NOT NULL default '',
`nickname` varchar(16) NOT NULL default '',
`firstname` varchar(128) NOT NULL default '',
`lastname` varchar(128) NOT NULL default '',
`email` varchar(128) NOT NULL default '',
`label` varchar(255) default NULL,
PRIMARY KEY (`owner`,`nickname`),
KEY `firstname` (`firstname`,`lastname`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE `userprefs` (
`user` varchar(128) NOT NULL default '',
`prefkey` varchar(64) NOT NULL default '',
`prefval` blob NOT NULL,
25 / 39
OpenBSD Mailserver
Written by Bart Dorlandt
Friday, 18 April 2008 22:08 - Last Updated Friday, 13 February 2009 15:30
PRIMARY KEY (`user`,`prefkey`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

PHP changes /var/www/conf/php.ini

I have made these changes to the php.ini to be able to upload larger files. These may seem
huge, but in fact I use this value also for another website to upload movies. So feel free to
shrink them a bit.

post_max_size = 50M
upload_tmp_dir = /tmp
upload_max_filesize = 50M

Open webmail

Open webmail can be installed by using the pkg_add function of OpenBSD. If you have
configured your PKG_PATH , you are
able to install openwebmail by using
pkg_add -iv openwebmail
as root. This will also install the following packages.

p5-Compress-Zlib-1.41
p5-Text-Iconv-1.4
tnef-1.4.1
p5-Digest-SHA1-2.11
p5-Digest-HMAC-1.01
p5-GSSAPI-0.22
p5-Authen-SASL-2.10
p5-Net-SSLeay-1.30p0
p5-IO-Socket-SSL-0.996
p5-Quota-1.5.1
ispell-3.2.06p1
p5-CGI-SpeedyCGI-2.22
openwebmail-2.51

If you want to have the dutch language (like me). You'll also have to install the ispell-dutch-3.2.0
6p0 package.
26 / 39
OpenBSD Mailserver
Written by Bart Dorlandt
Friday, 18 April 2008 22:08 - Last Updated Friday, 13 February 2009 15:30
You can change the default setting by executing this command
/usr/local/bin/ispell-config
.

Unfortunatly I haven't figured this one out for OpenBSD. The information on the installation is
scarce. The init script you had to execute did little for me. I hope someone could add some
usefull info here.

NOTE: If you are able to make this work, you also have bring perl into the chroot /var/www.
Probably it also needs to be set to
suid
.


Startup files

Here you'll find the configs to let programs start at boot time.

We have 2 config files to edit. /etc/rc.conf.local and /etc/rc.local. In the first we will define some
parameters for default programs and in
rc.local
we can put our own startup scripts.

Lets start with /etc/rc.conf.local

/etc/rc.conf.local

27 / 39
OpenBSD Mailserver
Written by Bart Dorlandt
Friday, 18 April 2008 22:08 - Last Updated Friday, 13 February 2009 15:30
shlib_dirs="$shlib_dirs /usr/local/lib/mysql" # extra directories for ldconfig
mysql=YES
syslogd_flags="-a /var/spool/postfix/dev/log"
sendmail_flags="-bd"

In the next configuration we also create the socket for mysql so we can connect from the
chrooted environment.

/etc/rc.local

### MySQL
### MySQL
if [ X"${mysql}" == X"YES" -a -x /usr/local/bin/mysqld_safe ]; then
# MYSQLd met logging
# echo -n " mysqld"; /usr/local/bin/mysqld_safe --user=_mysql --log=/var/mysql/mysql.log
--bind-address=127.0.0.1 --open-files-limit=900 &
# echo -n " mysqld"; /usr/local/bin/mysqld_safe --user=_mysql &
su -c mysql root -c '/usr/local/bin/mysqld_safe >/dev/null 2>&1 &'
echo -n ' mysql'
for i in 1 2 3 4 5 6; do
if [ -S /var/run/mysql/mysql.sock ]; then
break
else
sleep 1
echo -n "."
fi
done
#
# Apache chroot Settings
mkdir -p /var/www/var/run/mysql
sleep 1
ln -f /var/run/mysql/mysql.sock /var/www/var/run/mysql/mysql.sock
#
# Postfix chroot Settings
if [ X"${postfix_flags}" != X"NO" ]; then
mkdir -p /var/spool/postfix/var/run/mysql
mkdir -p /var/spool/postfix/var/run/saslauthd
sleep 2
ln -f /var/run/mysql/mysql.sock /var/spool/postfix/var/run/mysql/mysql.sock
28 / 39
OpenBSD Mailserver
Written by Bart Dorlandt
Friday, 18 April 2008 22:08 - Last Updated Friday, 13 February 2009 15:30
fi
fi
### Mail ###
# Dovecot Imap
if [ -x /usr/local/sbin/dovecot ]; then
echo -n ' dovecot'; /usr/local/sbin/dovecot
fi
# Fetchmail
if [ -x /usr/local/bin/fetchmail ]; then
echo -n ' fetchmail'; /usr/local/bin/fetchmail -f /etc/.fetchmailrc
fi
# this will show a warning that to start as root isn't the right way, but I want to control it
# instead of my users. Plus not all my users have a shell account.
# ClamAV VirusScanner
if [ -x /usr/local/sbin/clamd ]; then
echo -n ' clamd' ; [ -S /var/clamav/clamd.sock ] && rm -f /var/clamav/clamd.sock
/usr/local/sbin/clamd >/dev/null 2>&1
fi
# Amavisd-new
if [ -x /usr/local/sbin/amavisd ]; then
echo -n ' amavisd'; /usr/local/sbin/amavisd >/dev/null 2>&1
fi


Scripts

Postfix

# cat postfix-restart.sh
#!/bin/sh
postmap /etc/postfix/relay_domains
postfix stop
sleep 2
mkdir -p /var/spool/postfix/var/run/mysql
sleep 2
ln -f /var/run/mysql/mysql.sock /var/spool/postfix/var/run/mysql/mysql.sock
postfix start

Apache

29 / 39
OpenBSD Mailserver
Written by Bart Dorlandt
Friday, 18 April 2008 22:08 - Last Updated Friday, 13 February 2009 15:30
# cat apache-restart.sh
#!/bin/sh
apachectl stop
sleep 5
apachectl startssl

MySQL

# cat sql-stop.sh
#!/bin/sh
mysqladmin -u root shutdown
# my password is configured in /root/.my.cnf

# cat sql-start.sh
#!/bin/sh
echo -n " mysqld with logging"
su -c mysql root -c '/usr/local/bin/mysqld_safe >/dev/null 2>&1 &'
for i in 1 2 3 4 5 6; do
if [ -S /var/run/mysql/mysql.sock ]; then
break
else
sleep 1
echo -n "."
fi
done
mkdir -p /var/www/var/run/mysql
sleep 1
ln -f /var/run/mysql/mysql.sock /var/www/var/run/mysql/mysql.sock
# Postfix chroot Settings
if [ "X${postfix_flags}" != X"NO" ]; then
mkdir -p /var/spool/postfix/var/run/mysql
sleep 2
ln -f /var/run/mysql/mysql.sock /var/spool/postfix/var/run/mysql/mysql.sock
fi

# cat sql-start-log.sh
#!/bin/sh
echo -n " mysqld with logging"
su -c mysql root -c '/usr/local/bin/mysqld_safe --log=/var/mysql/mysql.log >/dev/null 2>&1 &'
30 / 39
OpenBSD Mailserver
Written by Bart Dorlandt
Friday, 18 April 2008 22:08 - Last Updated Friday, 13 February 2009 15:30
for i in 1 2 3 4 5 6; do
if [ -S /var/run/mysql/mysql.sock ]; then
break
else
sleep 1
echo -n "."
fi
done
mkdir -p /var/www/var/run/mysql
sleep 1
ln -f /var/run/mysql/mysql.sock /var/www/var/run/mysql/mysql.sock
# Postfix chroot Settings
if [ "X${postfix_flags}" != X"NO" ]; then
mkdir -p /var/spool/postfix/var/run/mysql
sleep 2
ln -f /var/run/mysql/mysql.sock /var/spool/postfix/var/run/mysql/mysql.sock
fi

Clamd

# cat clamd-stop.sh
#!/bin/sh
PID=`ps ax | grep clamd | grep sbin | awk '{print $1}'`
kill $PID

# cat clamd-restart.sh
#!/bin/sh
PROGRAM=`ps -ax | grep clamd | head -n1 | awk '{print $5}'`
PID=`ps ax | grep clamd | grep sbin | awk '{print $1}'`
TEMP=`mktemp choose.XXXXXXX`
echo $PROGRAM > $TEMP
kill $PID
sh $TEMP
rm $TEMP

Amavisd

# cat amavisd-stop.sh
31 / 39
OpenBSD Mailserver
Written by Bart Dorlandt
Friday, 18 April 2008 22:08 - Last Updated Friday, 13 February 2009 15:30
#!/bin/sh
PID=`ps ax | grep amavisd | grep perl | awk '{print $1}'`
kill $PID


Mailq

If mail is stuck in your mailq because of your mailserver being down or your DNS was wrong
implemented or you had a misconfiguration. You have a couple of options. One of them is wait
for it to empty itself. I don't like that option so here are a few commands you can use:

Postfix

You can also use the -v option if you want to see what is happening.

/usr/local/sbin/postqueue -f
/usr/local/sbin/postqueue -f -v

If you want the queue only to be emptied for a certain domain, you can use the following. (also
with the -v to see what is happening)

/usr/local/sbin/postqueue -fs bamweb.nl -v

If you want to requeue the whole bunch this is what you have to do. Remember your mail won't
be gone in a second. It still has to pass the WHOLE queue.
32 / 39
OpenBSD Mailserver
Written by Bart Dorlandt
Friday, 18 April 2008 22:08 - Last Updated Friday, 13 February 2009 15:30

postsuper -r ALL

Sendmail

While I'm at it, these are for sendmail. You can also use the -v option if you want to see what is
happening.

/usr/sbin/sendmail -q
/usr/sbin/sendmail -q -v

If you want the queue only to be emptied for a certain domain, you can use the following. (also
with the -v to see what is happening)

/usr/sbin/sendmail -qR bamweb.nl -v


Backup MX

To have a backup MX you have to do a few things on the backup MX side. You don't have to do
anything on the primary MX side. Add the domain to the relay configuration, add the IP of the
primary MX to the config ( safety ), and that to the smtpd_recipient_restrictions. To make the
configuration a bit more modulair I also use the mysql backend for the backupMXs. To do this
create a file: /etc/
postfix/mysql_virtual_backupmx.cf
.
33 / 39
OpenBSD Mailserver
Written by Bart Dorlandt
Friday, 18 April 2008 22:08 - Last Updated Friday, 13 February 2009 15:30

user = vmail
password = vmail
hosts = unix:/var/run/mysql/mysql.sock
dbname = mail
query = SELECT domain FROM backupmx WHERE domain='%s'

Create thetabel in the database

CREATE TABLE `backupmx` (
`domain` varchar(50) NOT NULL default '',
PRIMARY KEY (`domain`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
INSERT INTO `backupmx` (`domain`) VALUES
('domain1.tld');

If you want to have your mail stored longer or shorter then the default of 5 days, you need to
change the maximal_queue_lifetime (thanks Samat Jain ).

Make the following changes to the postfix configuration file. /etc/postfix/main.cf

relay_domains = $mydestination, mysql:/etc/postfix/mysql_virtual_backupmx.cf
# I don't want to specify all of the users, so I leave it open
relay_recipient_maps =
#It is also possible to specify a name instead of an IP address. This is not nessecarily!
permit_mx_backup_networks = <primary MX IP domain1.tld>/32, <primary MX IP
domain2.tld>/32
# default queue time = 5 days
maximal_queue_lifetime = 40d
smtpd_recipient_restrictions = permit_mynetworks,
# put this in between
permit_mx_backup,
34 / 39
OpenBSD Mailserver
Written by Bart Dorlandt
Friday, 18 April 2008 22:08 - Last Updated Friday, 13 February 2009 15:30
check_relay_domains,
# go along with the rest.

Restart the postfix server again.


cmuSieve

because were using the Local Delivery Agent (LDA) of Dovecot, we are able to use the Sieve
plugin. This plugin makes it possible to create filters on your server. This is pretty need,
because this way you don't have to create or export/import your filters everywhere you use your
mail also in your webclient (like squirrelmail)

To get this working you'll have to install the sieve plugin . This is also in the openbsd repository,
so it ain't a sweat to install it. I installed the mysql version. This version could read the
information from the sql database, but I'm not using that option right now. So, next the
configuration. Remember, you will see some other configurations, like quota. These were
mentioned earlier. only mind the cmusieve stuf.

protocol lda {
mail_plugins = quota cmusieve
}

plugin {
sieve = /var/mail/vhosts/%d/%n/.dovecot.sieve
global_script_path = /var/mail/vhosts/dovecot.sieve.global
}
35 / 39
OpenBSD Mailserver
Written by Bart Dorlandt
Friday, 18 April 2008 22:08 - Last Updated Friday, 13 February 2009 15:30

Now we have enabled the sieve plugin and have pointed to two locations to read the sieve files.
We have a global sieve script, which is only read if no user script is found!!! And we have a
per-user-script in the directory of the virtual user. Right now only someone with access to box
may change these files.

Next we have to fill up the files. Let's start with the global script.

require "fileinto";
require "imapflags";
if header :contains "Subject" "***SPAM***" {
setflag " \\Seen ";
fileinto "Junk";
}

This script will move the email with the subject containing ***SPAM*** to the folder Junk (this is
called ".Junk" in the directory structure on the server). It will also set the flag seen (or read) on
the mail.

Next we take a look on a part of my own script. Remember, if this file exists the global script
isn't read. So you'll have to created the SPAM part yourself or not if you just want to see your
SPAM.

require ["envelope", "fileinto", "reject", "imapflags", "notify", "vacation"];
###################### SPAM #################################
if header :contains "Subject" "***SPAM***" {
setflag "\Seen";
fileinto "Junk";}
if anyof (
address :domain :is "From" "domain1.tld",
header :contains ["To", "Cc", "Bcc"] "me@domain1.tld",
address :domain :is "From" "domain2.tld")
36 / 39
OpenBSD Mailserver
Written by Bart Dorlandt
Friday, 18 April 2008 22:08 - Last Updated Friday, 13 February 2009 15:30
{ fileinto "Folder1"; }
###################### Bart #################################
if header :is "X-Original-To" "me@domain2.tld" {
fileinto "Folder2.subfolder2.subfolder1";}

This should give you an idea. You might want to check the following links to see more
configuration examples. Sieve.info & sieve@sourceforge .
Troubleshooting

Lets take a look at the troubleshooting part. Make sure you have your logging enabled in your
dovecot configuration.

protocol lda {
log_path = /var/log/dovecot-deliver.log
info_log_path = /var/log/dovecot-deliver.log
}

The first check to see if the sieve filter is being used is to see if the file .dovecot.sievec has been
created. If you have used another filename than .dovecot.sieve, your filename is being used
with the extra "c" at the end. If the script contains errors a file .dovecot.sieve.err is being
created. You can also test your sieve script online. Just google for someting like "sieve test
script".

Let's takea look in the logfile. If something is wrong in your script, you could get some of the
following errors:

deliver(me@domain1.tld): Nov 04 18:03:12 Info: sieve runtime error: Fileinto: Generic Error

deliver(me@domain1.tld): Nov 04 19:29:42 Info: sieve parse error: line 4: syntax error,
unexpected IF, expecting ';'
37 / 39
OpenBSD Mailserver
Written by Bart Dorlandt
Friday, 18 April 2008 22:08 - Last Updated Friday, 13 February 2009 15:30

In any of these cases you should test your script online or figure it out yourself.

If you see the following it succeeded.

deliver(me@domain1.tld): Nov 05 08:15:53 Info:
msgid=<5100277056DA4B4DB696F0E71C09559101CE22BE@ms-ams-e3mb02.emea.dsmain
.com>: saved mail to Folder1.subfolder2
ManageSieve server

With this tool you are able to let your virtual users upload their sieve scripts. I haven't used it
yet, but you can find information over here.

ManageSieve Server solutions


Specials (providers)
Planet

If you want to set up a backup MX behind a planet internet provider you need to set up a few
things. First you need to configure the following in the DNS. The first one is the primary MX. The
second one is the system by name or IP address with the planet account. The third is the
mailrelay of planet. Only this machine is allowed to send emails into the planet domain. After
delivery to this machine it will go through the list of the DNS again to really deliver it to
system_at.planet.nl.
38 / 39
OpenBSD Mailserver
Written by Bart Dorlandt
Friday, 18 April 2008 22:08 - Last Updated Friday, 13 February 2009 15:30

@ MX 10 mx1.bamweb.nl.
@ MX 20 system_at.planet.nl.
@ MX 21 mailrelay.planet.nl.

It doesn't matter what the priority numbers are as long the mailrelay.planet.nl is higher than the
system at planet.
39 / 39