Home mail server with Postfix + Dovecot (IMAP) + Squirrelmail/Roundcube on NetBSD 6.0.1


NetBSD 6.0.1


  • lightweight (no mysql server, no antivirus)
  • simple (no virtual domains/users)
  • secure


  • a valid internet domain name if you want to be able to send/receive email to/from the internet (buy a domain or take a free one at http://freedns.afraid.org )
  • valid DNS records for your domain
  • we assume your mail server is behind a properly configured router/gateway/firewall

Hardware/Virtual machine requirements

  • 512M RAM
  • 3G of disk space minimum, 8G recommended

Install NetBSD

Install from iso : http://www.netbsd.org/mirrors/#iso

Installation without X11

Note : if you later decide to install software such as Munin, you will need the X11 libraries so it’s better in this case to do a full installation.

Configure network

  • Your DNS domain : domain.tld (replace by your own)
  • Your host name: mx (or “mail”, or anything you want)

(so the fully qualified domain name FQDN for this system is : mx.domain.tld)

  • Enable sshd : YES
  • Enable ntpd : YES
  • Run ntpdate at boot : YES

Installation finished, reboot, login as root

 # man afterboot
 # man hier

Change root password if not done at install time

 # passwd root


Create a regular UNIX user, with a home directory created (we want to store our mails in ~/Maildir) Also add the user to the wheel group (for “su” ability)

 # useradd -m -G wheel fred
 # passwd fred


Now you can login via ssh with your regular user to start your copy/paste session ūüôā

First we switch to root

 # su -

Set mirror for downloading binary packages

 # export PKG_PATH=ftp://ftp2.fr.NetBSD.org/pub/pkgsrc/packages/NetBSD/$(uname -m)/6.0_2012Q3/All
 # echo >>~/.profile "export PKG_PATH=$PKG_PATH"

(adjust to another mirror and repository if needed)

My survival kit in BSD-land ūüôā

 # pkg_add -v bash nano pkgin
 # echo >>~/.profile 'export EDITOR=nano'

Notes : – packages are installed into /usr/pkg/ – if you need to see again the included notes for a given package : pkg_info

Change default shell for root

 # whereis bash
 # export EDITOR=nano; chsh

Shell : /usr/pkg/bin/bash

Start a new bash shell

 # bash

Postfix configuration

Good news, Postfix is part of the netbsd base install and therefore already installed and running! But we need to adjust its configuration. (docs are in /usr/share/examples/postfix/)

We want to store our mail messages in Maildir format, not in mbox format

 # postconf -e 'home_mailbox = Maildir/'

(or uncomment the line which is already present in the /etc/postfix/main.cf)

If you need to use a relayhost to send messages to the internet (in most cases, your ISP’s relay mail server)

 # postconf -e 'relayhost=[smtp.yourisp.org]'

Note : if you need to authenticate yourself on the relayhost, read instructions in /usr/share/examples/postfix/SOHO_README

We need proper internet domain and hostname

 # postconf -e 'mydomain=domain.tld'
 # postconf -e 'myhostname=mx.domain.tld'

Allow delivery to user@$mydomain

 # postconf -e 'mydestination = $mydomain, $myhostname, localhost.$mydomain, localhost'

Generate a self-signed SSL certificate and private key for our system

 # mkdir -p /etc/ssl/{certs,private}
 # cp /usr/share/examples/openssl/openssl.cnf /etc/openssl/
 # openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/ssl/private/myserver.key -out /etc/ssl/certs/myserver.crt
 # chmod 600 /etc/ssl/private/myserver.key

Enable TLS/SSL support for security (see /usr/share/examples/postfix/TLS_README for more)

 # postconf -e 'smtpd_tls_security_level=may'
 # postconf -e 'smtpd_use_tls=yes'
 # postconf -e 'smtpd_tls_auth_only=yes'
 # postconf -e 'smtpd_tls_cert_file=/etc/ssl/certs/myserver.crt'
 # postconf -e 'smtpd_tls_key_file=/etc/ssl/private/myserver.key'
 # postconf -e 'smtpd_tls_loglevel=1'

The rest of the postfix configuration is set to sane defaults.

Enable inbound smtp reception

 # nano /etc/postfix/master.cf

uncomment the first “smtp” line

Changes made, reload postfix

 # /etc/rc.d/postfix reload

Send a test mail from root to your regular user

 # echo "from my netbsd mailserver" | mail -s "test mail" fred

Look at the log to see if everything went fine

 # tail /var/log/maillog

Also it’s a good idea to forward system mails (sent to root) to our regular user

 # nano /etc/mail/aliases

add a line at the end :

root: fred

Save and don’t forget :

 # newaliases

Installing packages with pkgin

pkgin is an enhanced package manager similar to apt/yum/zypper. You must also specify the correct PKG_PATH in its configuration file.

 # echo $PKG_PATH >/usr/pkg/etc/pkgin/repositories.conf && pkgin update

For those who are on dynamic IP, you can use ddclient to update your DNS records (see your domain name registrar)

 # pkgin in ddclient
 # nano /usr/pkg/etc/ddclient.conf

(I personally use n$m$ch$$p and it works perfectly)

Test your settings

 # ddclient -verbose -daemon 0

Start daemon

 # cp -v /usr/pkg/share/examples/rc.d/ddclient /etc/rc.d/
 # echo >>/etc/rc.conf 'ddclient=YES' && /etc/rc.d/ddclient start

Check your DNS records

 # dig domain.tld -t any


 # host -a domain.tld

Antispam : greylisting with postgrey

(unlike some other greylisting software for postfix, postgrey doesn’t need a mysql server)

 # pkgin in postgrey

Start daemon

 # cp -v /usr/pkg/share/examples/rc.d/postgrey /etc/rc.d/
 # echo >>/etc/rc.conf 'postgrey=YES' && /etc/rc.d/postgrey start

See the documentation

 # perldoc postgrey

Adjust postfix for using postgrey daemon

 # postconf -e 'smtpd_recipient_restrictions = permit_mynetworks, reject_unauth_destination, check_policy_service inet:'
 # /etc/rc.d/postfix reload

Note : in NetBSD, the postgrey daemon is configured to listen on the 2525/tcp port, not 10023/tcp.

Now in order to test if postgrey actually works properly, send an email to your system from an external email address, and check the mail log

 # tail /var/log/maillog | grep postgrey

Antispam : spamassassin/spamass-milter

 # pkgin in spamass-milter

(will include spamassassin as a dependency)

Copy the rc.d files

 # cp -v /usr/pkg/share/examples/rc.d/{spamd,spamass-milter} /etc/rc.d/

The /etc/rc.d/spamass-milter must be corrected (this dirty hack is needed otherwise postfix will not be able to access the socket and the milter will fail)

# cat >>/etc/rc.d/spamass-milter <<EOF

 echo -n "Changing /var/run/spamass.sock ownership and permissions..."
 sleep 1
 chown postfix:postfix /var/run/spamass.sock
 chmod 0660 /var/run/spamass.sock
 echo " done"

Adjust Spamassassin’s settings

 # nano /usr/pkg/etc/spamassassin/local.cf

Uncomment the “rewrite_header Subject” directive.

Start daemons

 # echo >>/etc/rc.conf 'spamd=YES' && /etc/rc.d/spamd start
 # echo >>/etc/rc.conf 'spamass_milter=YES' && /etc/rc.d/spamass-milter start

Integrate spamass-milter with postfix (Note : this was taken from a working Debian/Postfix/Spamass-milter config ūüôā )

 # postconf -e 'smtpd_milters=unix:/var/run/spamass.sock'
 # postconf -e 'milter_default_action=accept'
 # postconf -e 'milter_connect_macros= j {daemon_name} v {if_name} _'
 # /etc/rc.d/postfix reload

Update spamassassin’s rules

 # sa-update -v && /etc/rc.d/spamd reload

Create a new cron job for daily update

 # crontab -e

 @daily /usr/pkg/bin/sa-update >/dev/null 2>&1 && /etc/rc.d/spamd reload >/dev/null 2>&1

Testing your antispam settings Send yourself a sample spam email (from an external email account), see /usr/pkg/share/doc/spamassassin/sample-spam.txt

TODO : train system for spam recognition

 # perldoc sa-learn

Install IMAP server : Dovecot

 # pkgin in dovecot-2

Dovecot configuration files are located in : /usr/pkg/etc/dovecot/ Log file is : /var/log/maillog

Edit default config, I disable pop3 since I don’t use it.

 # cd /usr/pkg/etc/dovecot/
 # nano dovecot.conf 
 protocols = imap lmtp

Now edit the 10-ssl.conf file and change the path for the certificate

 # nano conf.d/10-ssl.conf

ssl = yes

ssl_cert = </etc/ssl/certs/myserver.crt

ssl_key = </etc/ssl/private/myserver.key

Next, we want to use MailDir format for storing our messages, in our user’s home directory.

 # nano conf.d/10-mail.conf

mail_location = maildir:~/Maildir

All changes done, now start Dovecot daemon

 # cp -v /usr/pkg/share/examples/rc.d/dovecot /etc/rc.d/
 # echo >>/etc/rc.conf 'dovecot=YES' && /etc/rc.d/dovecot start

Postfix SASL support from Dovecot

This will allow you to authenticate yourself on your server, in order to send mails from outside of your local network (from your portable computer or smartphone, for instance)

Just follow the provided instructions

 # less /usr/pkg/share/doc/dovecot/wiki/HowTo.PostfixAndDovecotSASL.txt

Just be careful with this postfix line (order is important) :

 smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination, check_policy_service inet:

(Reload postfix and dovecot of course)

 # /etc/rc.d/postfix reload
 # /etc/rc.d/dovecot reload

Installing Apache web server with PHP5

 # pkgin se apache |less

We see there are several apache versions to choose from. Go for the latest, Apache 2.4.x

 # pkgin in apache-2.4
  • The apache user/group is : www/www
  • The apache daemon is : httpd
  • Configuration files are located in : /usr/pkg/etc/httpd/
  • Default document root is : /usr/pkg/share/httpd/htdocs/
  • Log files are located in : /var/log/httpd/

Note 1 : Apache’s logs will not be rotated by default. You must edit the /etc/newsyslog.conf file and add entries for Apache’s log files. Also see

 # man newsyslog

Note 2 : NetBSD comes with its own, small, httpd server (man httpd), which is not enabled by default. /etc/rc.d/httpd is the daemon startup file for this web server whereas Apache uses /etc/rc.d/apache

Copy rc.d init file and start apache (will be started at boot too)

 # cp -v /usr/pkg/share/examples/rc.d/apache /etc/rc.d/
 # echo >>/etc/rc.conf 'apache=YES' && /etc/rc.d/apache start

Installing PHP5.3.x for apache

 # pkgin in ap24-php53 php53-suhosin

Enable suhosin in PHP

 # echo >>/usr/pkg/etc/php.ini 'extension=suhosin.so'

Configure timezone in PHP

 # echo >>/usr/pkg/etc/php.ini 'date.timezone = Europe/Paris'

Enable PHP module in apache

 # nano /usr/pkg/etc/httpd/httpd.conf

Append the lines :

 LoadModule php5_module lib/httpd/mod_php5.so
 AddHandler application/x-httpd-php .php

And change the line :

 DirectoryIndex index.html


 DirectoryIndex index.html index.php

Save config, restart apache

 # /etc/rc.d/apache restart

Verify if PHP is ok

# cat >/usr/pkg/share/httpd/htdocs/tmpinfo.php <<EOF

<?php phpinfo(); ?>


Point your browser at : http://<server>/tmpinfo.php

Everything works? Good, now delete the file (security risk)

 # rm /usr/pkg/share/httpd/htdocs/tmpinfo.php

We could also enable the Apache documentation

 # nano /usr/pkg/etc/httpd/httpd.conf && /etc/rc.d/apache reload

Enable the “negotiation” module

 LoadModule negotiation_module lib/httpd/mod_negotiation.so

Then restrict access to the manual to our LAN

 # nano /usr/pkg/etc/httpd/httpd-manual.conf

Replace the line

 Require all granted


 Require ip 192.168.

And browse the docs at http:///manual/

Install Squirrelmail webmail

 # pkgin in squirrelmail squirrelmail-locales

Run the configuration script

 # cd /usr/pkg/share/squirrelmail/config && ./conf.pl

Important : set your domain name in “Server settings”!

Enable some plugins (useful for debugging) : info, message_details, …

Create a symlink in htdocs

 # ln -s /usr/pkg/share/squirrelmail /usr/pkg/share/httpd/htdocs/

(or any other name)

 # ln -s /usr/pkg/share/squirrelmail /usr/pkg/share/httpd/htdocs/mail

We need to enable the gettext extension in php.ini

 # echo >>/usr/pkg/etc/php.ini 'extension=gettext.so'

And restart apache

 # /etc/rc.d/apache restart

Now point your browser to : http:///squirrelmail/ and login with the username and password of your regular user. (root logins are not permitted of course)

You should find in your inbox, the test mail message from root we sent earlier.

Squirrelmail plugins :

 # pkgin in wget
 # cd /usr/pkg/share/squirrelmail/plugins/

(change download links with the latest versions available)

 # wget http://squirrelmail.org/countdl.php?fileurl=http%3A%2F%2Fwww.squirrelmail.org%2Fplugins%2Fcompatibility-2.0.16-1.0.tar.gz -O compatibility.tar.gz
 # tar xvzf compatibility.tar.gz

Lockout plugin (not required if fail2ban is used)

 # wget http://squirrelmail.org/countdl.php?fileurl=http%3A%2F%2Fwww.squirrelmail.org%2Fplugins%2Flockout-1.7-1.4.1.tar.gz -O lockout.tar.gz
 # tar xvzf lockout.tar.gz
 # cd lockout/data
 # cp config_example.php config.php
 # nano config.php

(read carefully and choose your settings!)

Logger plugin (required if you want to use fail2ban!)

 # wget http://squirrelmail.org/countdl.php?fileurl=http%3A%2F%2Fwww.squirrelmail.org%2Fplugins%2Fsquirrel_logger-2.3.1-1.2.7.tar.gz -O logger.tar.gz
 # tar xvzf logger.tar.gz
 # cd squirrel_logger/
 # cp config_example.php config.php
 # nano config.php

in the "$sl_logs = array ()", uncomment the 'LOGIN_ERROR' line. (this will cause all login errors to be logged in /var/log/maillog)

also set : $sl_use_GMT = 0 (required for the fail2ban jail to work)

Activate our new plugins

 # /usr/pkg/share/squirrelmail/config/conf.pl

Roundcube webmail (with sqlite backend)

 # pkgin in sqlite php53-sqlite roundcube

Enable php extensions as we are told by the packages’ instructions

# cat >>/usr/pkg/etc/php.ini <<EOF

  • Log files: /var/log/roundcube/
  • Document root: /usr/pkg/share/roundcube/
  • Docs are in : /usr/pkg/share/doc/roundcube/INSTALL

Build pear-MDB2Driversqlite from source (it’s missing in the binary packages)

 # cd /root
 # ftp ftp://ftp.netbsd.org/pub/pkgsrc/pkgsrc-2012Q3/pkgsrc.tar.xz
 # tar --xz -xf pkgsrc.tar.xz -C /usr
 # unset PKG_PATH
 # cd /usr/pkgsrc/databases/pear-MDB2_Driver_sqlite
 # make && make package

Finally install the generated package

 # pkg_add -v /usr/pkgsrc/packages/All/php53-pear-MDB2_Driver_sqlite-1.5.0b3.tgz

Setup sqlite database

 # cd /usr/pkg/share/roundcube
 # sqlite -init SQL/sqlite.initial.sql sqlite.db

Now for security purposes we move the database out of the web server’s documents tree

 # mkdir -p /var/db/roundcube
 # mv sqlite.db /var/db/roundcube
 # chown -R www:www /var/db/roundcube
 # chmod 660 /var/db/roundcube/sqlite.db

Edit Roundcube configuration

 # nano /usr/pkg/etc/roundcube/db.inc.php

 $rcmail_config['db_dsnw'] = 'sqlite:////var/db/roundcube/sqlite.db?mode=0646'; 
 # nano /usr/pkg/etc/roundcube/main.inc.php

 $rcmail_config['default_host'] = 'localhost';

Edit roundcube.conf for Apache

 # nano /usr/pkg/etc/roundcube/roundcube.conf

  # Order allow,deny
  # Allow from all
 require all granted
  # Order deny,allow
  # Deny from all
 require all denied

Setup Apache

 # echo >>/usr/pkg/etc/httpd/httpd.conf 'Include /usr/pkg/etc/roundcube/roundcube.conf' && /etc/rc.d/apache reload

Point your browser to : http:///roundcube/ and enjoy the nice webmail interface!

Remember to check /var/log/roundcube/errors in case of problems.

Enabling SSL in Apache (and other security bits)

First edit the http-ssl.conf file

 # nano /usr/pkg/etc/httpd/httpd-ssl.conf

Edit the following lines

 SSLCertificateFile "/etc/ssl/certs/myserver.crt"
 SSLCertificateKeyFile "/etc/ssl/private/myserver.key"

Then edit the global httpd.conf

 # nano /usr/pkg/etc/httpd/httpd.conf

Uncomment the following lines

 LoadModule socache_shmcb_module lib/httpd/mod_socache_shmcb.so
 LoadModule ssl_module lib/httpd/mod_ssl.so
 Include etc/httpd/httpd-ssl.conf
 Include etc/httpd/httpd-default.conf

Change some security defaults as well

 # nano /usr/pkg/etc/httpd/httpd-default.conf 
 ServerTokens Prod
 TraceEnable off

Also disable PHP signature

 # nano /usr/pkg/etc/php.ini 
 expose_php = Off

Enforce https redirection


You could as well add a list of IP blocks to be denied access to your web server (warning, huge lists will slow down your web server)

Generate an .htaccess deny list and include it in your Apache conf.

Or the opposite, a country whitelist. Example of corresponding Apache 2.4 conf for a whitelist :

<Location />

 require all denied
 require local
 require ip 192.168.

 require ip
 require ip
 require ip
 require ip
 require ip
 require ip ...



 # /etc/rc.d/apache reload

Ask the “kind” web crawlers not to index our site

# cat >/usr/pkg/share/httpd/htdocs/robots.txt <<EOF

 User-Agent: *
 Disallow: /


New firewall in NetBSD 6.0 : npf

 # man npfctl
 # man npf.conf

Due to my lack of experience with it, I used the pf firewall instead. Here’s a sample pf firewall configuration :

# cat >/etc/pf.conf <<EOF

# Generated by Fwbuilder 5.1 and edited
# replace wm0 with your actual network interface name!
# Rule  0 (wm0)
# anti spoofing rule
block in ¬† log ¬†quick on wm0 inet ¬†from self ¬†to any ¬†label “RULE 0 — DROP ”
# Rule  1 (lo)
pass ¬†quick on lo inet ¬†from any ¬†to any ¬†label “RULE 1 — ACCEPT ”
# enable the following two rules when using fail2ban
table < fail2ban > persist
block in quick from < fail2ban > to any label “fail2ban rule”
# Rule  2 (global)
# useful ICMP types; ping request
pass in ¬† quick inet proto icmp ¬†from any ¬†to self icmp-type { 3 , 0 code 0 , 8 code 0 , 11 code 0 , 11 code 1 ¬†} ¬†label “RULE 2 — ACCEPT ”
# allow SSH in (with connection rate limiting to prevent bruteforcing)
pass in ¬† quick inet proto tcp ¬†from any ¬†to self port 22 flags any keep state ( max-src-conn-rate 3/30 ) label “RULE 2 — ACCEPT ”
# allow SMTP in
pass in ¬† quick inet proto tcp ¬†from any ¬†to self port 25 flags any ¬†label “RULE 2 — ACCEPT ”
# allow IMAP in
pass in ¬† quick inet proto tcp ¬†from any ¬†to self port 143 flags any ¬†label “RULE 2 — ACCEPT ”
# allow HTTP and HTTPS in
pass in ¬† quick inet proto tcp ¬†from any ¬†to self port 80 flags any ¬†label “RULE 2 — ACCEPT ”
pass in ¬† quick inet proto tcp ¬†from any ¬†to self port 443 flags any ¬†label “RULE 2 — ACCEPT ”
# Rule  3 (global) :  allow all traffic out
pass out ¬†quick inet ¬†from self ¬†to any ¬†label “RULE 3 — ACCEPT ”
# Rule  4 (global) : block all the rest (with logging)
block ¬†log ¬†quick inet ¬†from any ¬†to any ¬†label “RULE 4 — DROP ”
# Rule  fallback rule
block ¬†quick inet ¬†from any ¬†to any no state ¬†label “RULE 10000 — DROP ”

Note : remove the spaces between the "<" ">" signs.

Enable the firewall (and his logging daemon)

 # /etc/rc.d/pf onestart
 # /etc/rc.d/pflogd onestart

If no error occured, enable the pf firewall (and his logging daemon) at boot

 # echo >>/etc/rc.conf 'pf=YES'
 # echo >>/etc/rc.conf 'pflogd=YES'

You can review pf’s log file (binary format) with

 # tcpdump -r /var/log/pflog |tail

Note : /var/log/pflog can grow fast!

Fail2ban on NetBSD

Thanks to : http://www.bsdguides.org/2012/fail2ban-with-pf-on-openbsd-5-2

Download and install the latest Fail2ban release

 # wget https://github.com/fail2ban/fail2ban/archive/master.zip --no-check-certificate
 # unzip master.zip
 # cd fail2ban-master
 # python2.7 setup.py install

Create a new pf.conf action file for fail2ban

# cat >/etc/fail2ban/action.d/pf.conf <<EOF

 actionstart = 
 actionstop =
 actioncheck =
 actionban = /sbin/pfctl -t fail2ban -T add < ip >/32 
 actionunban = /sbin/pfctl -t fail2ban -T del < ip >/32

Note : remove the spaces between the “<” “>” signs.

And add the following jails in a new jail.local file

# cat >/etc/fail2ban/jail.local <<EOF

 # NetBSD jails with PF firewall 
 ignoreip =
 bantime = 600
 findtime = 600
 maxretry = 5

 enabled = true
 filter = sshd
 action = pf[name="ssh-pf"]
 sendmail-whois[name="ssh-pf", dest=root]
 logpath = /var/log/authlog

 # Note for dovecot : will not block squirrelmail bruteforce attacks (localhost ip ignored), only external attacks.
 enabled = true
 filter = dovecot
 action = pf[name="dovecot-pf"]
 sendmail-whois[name="dovecot-pf", dest=root]
 logpath = /var/log/maillog

 enabled = true
 filter = postfix
 action = pf[name="postfix-pf"]
 sendmail-whois[name="postfix-pf", dest=root]
 logpath = /var/log/maillog

 enabled = true
 filter = sasl
 action = pf[name="sasl-pf"]
 sendmail-whois[name="sasl-pf", dest=root]
 logpath = /var/log/maillog

 # inspired from : http://mattrude.com/projects/roundcube-fail2ban-plugin/
 enabled = true
 filter = roundcube
 action = pf[name="roundcube-pf"]
 sendmail-whois[name="roundcube-pf", dest=root]
 logpath = /var/log/roundcube/errors

 enabled = true
 filter = squirrelmail
 action = pf[name="squirrelmail-pf"]
 sendmail-whois[name="squirrelmail-pf", dest=root]
 logpath = /var/log/maillog

 # end of jails

Create the roundcube.conf filter

# cat >/etc/fail2ban/filter.d/roundcube.conf <<EOF

 failregex = .*Login failed for .*. from < HOST >
 ignoreregex =

Note : remove the spaces between the “<” “>” signs.

And the squirrelmail.conf filter

# cat >/etc/fail2ban/filter.d/squirrelmail.conf <<EOF

 failregex = .*Failed webmail login: by .*. at < HOST > on .*.: Unknown user or password incorrect.
 ignoreregex =

Note : remove the spaces between the “<” “>” signs.

Note : comment the “::1 localhost” line in /etc/hosts. Dovecot jail may not work correctly otherwise.

Let’s install gamin (file alteration monitor) so that fail2ban will use it instead of the “polling” backend

 # pkgin in gamin

To start fail2ban at boot, we create a corresponding rc script

# cat >/etc/rc.d/fail2ban <<EOF

 # fail2ban rc script for NetBSD
 # PROVIDE: fail2ban
 # KEYWORD : shutdown

 if [ -f /etc/rc.subr ]; then
  . /etc/rc.subr


 if [ ! -d /var/run/fail2ban ]; then
  mkdir /var/run/fail2ban/

 echo -n " ${name}: "
 ${command} ${command_args} "$1"


And set in rc.conf

 # echo >>/etc/rc.conf 'fail2ban=YES'

Finally start fail2ban

 # /etc/rc.d/fail2ban start


 # fail2ban-client start

Now test your jails!

TODO : (FIX) old bans come up again after fail2ban restart! log rotation related?


Verify the banned ip’s in the “fail2ban” pf table

 # pfctl -t fail2ban -T show

Manually unban an ip

 # fail2ban-client set <jail> unbanip <ip>

Test a regex

 # fail2ban-regex /var/log/maillog /etc/fail2ban/filter.d/squirrelmail.conf


 # man security

Check daily for security updates

 # echo >>/etc/daily.conf 'fetch_pkg_vulnerabilities=YES'

For creating your next mail users (with disabled shell access)

 # useradd -m -s /sbin/nologin mynewuser && passwd mynewuser


System monitoring

Show processes

 # top -ac

Show listening network ports

 # netstat -an|less

By default, NetBSD will run a daily cron job (/etc/daily) which includes a complete system security check (/etc/security). Mail reports will be sent to root.

 # crontab -l
 # man daily

Postfix stats with pflogsumm

 # pkgin in pflogsumm

example of use

 # zcat /var/log/maillog*.gz |pflogsumm

Mailgraph for postfix

 # pkgin in mailgraph
 # cp -v /usr/pkg/share/examples/rc.d/mailgraph /etc/rc.d/

rc file needs some changes

 # nano /etc/rc.d/mailgraph

command_args=”-d -l /var/log/maillog”

 # mkdir -p /var/db/mailgraph
 # echo >>/etc/rc.conf 'mailgraph=YES' && /etc/rc.d/mailgraph start

We need to make sure Apache can run cgi’s

 # nano /usr/pkg/etc/httpd/httpd.conf && /etc/rc.d/apache reload

uncomment the lines :

 LoadModule cgid_module lib/httpd/mod_cgid.so Scriptsock cgisock

Now point your browser at : http://<server>/cgi-bin/mailgraph.cgi

TODO : FIX : no graphics displayed!

Web server stats with Webalizer (AWStats is also available)

 # pkgin in webalizer

Create output directory in our htdocs

 # mkdir /usr/pkg/share/httpd/htdocs/webalizer/

Edit webalizer conf

 # nano /usr/pkg/etc/webalizer.conf 
LogFile        /var/log/httpd/access_log
OutputDir      /usr/pkg/share/httpd/htdocs/webalizer/
PageType        htm*
PageType        cgi
PageType        php*
PageType        pl
DNSCache        dns_cache.db
DNSChildren     5
HTMLBody <BODY BGCOLOR="white" TEXT="black">
AllSites        yes
AllURLs         yes
AllReferrers    yes
AllAgents       yes
AllSearchStr    yes
AllUsers        yes
HideSite        *domain.tld
HideSite        localhost
HideReferrer    domain.tld/
HideReferrer    localhost
HideURL         *.gif
HideURL         *.GIF
HideURL         *.jpg
HideURL         *.JPG
HideURL         *.png
HideURL         *.PNG
ColorHit        B1D28F
ColorFile       E3AD00
ColorSite       FFEB55
ColorKbyte      FF80DF
ColorPage       80B3FF
ColorVisit      638000
ColorMisc       EEEEEE

The rest of the settings are defaults.

Now generate stats

 # webalizer

Restrict access to the webalizer generated files, to the LAN only

 # nano /usr/pkg/etc/httpd/httpd.conf && /etc/rc.d/apache reload

Append the following lines

<Directory "/usr/pkg/share/httpd/htdocs/webalizer">

Require ip 192.168.


You might want to add a cronjob

 # crontab -e

 0 0 * * * /usr/pkg/bin/webalizer -Q


 # pkgin in munin-server munin-node


Finally, test your mail server with some nice online tools

(hint: try these tools with both cases: fail2ban enabled or disabled)


Please report any mistakes, suggestions, ideas for improvement… Thanks!


Remove user from the wheel group : We need to first delete the user (while preserving his home directory and files!)

 # userdel -v fred

And add him again (not recreating his home directory)

 # adduser fred
 # passwd fred

If you decide your UNIX users should not be be able to log in to a shell

 # chsh -s /sbin/nologin fred

Beware : not to lock yourself out of a remote system! (Remember ssh root login is not allowed by default)

Verify with

 # user info fred

Stopping/rebooting the system cleanly

 # shutdown -p now
 # shutdown -r now

Reference links


4 thoughts on “Home mail server with Postfix + Dovecot (IMAP) + Squirrelmail/Roundcube on NetBSD 6.0.1

  1. Many thanks for this tutorial ūüôā
    I am trying to replace my Linux VPS as web+mail server with a Rapsberry-Pi running NetBSD 6.1RC4, you have saved me hours.

    • Hi, nice tutorial ūüôā

      Except that using a google smtp relay kills (IMHO) the idea of having our own mail server!
      (or we would have to encrypt emails with pgp so that google does not scan/analyse them…)

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s