E-Mail System Setup in FreeWRT

This document describes how to set up a mail system on the open source router firmware FreeWRT. If you find bugs or have additional information, do not hesitate to contact sumsum at freewrt dot org by email.

Overview

FreeWRT supports packages for handling emails. This is not only useful in conjunction with cron (sending the output of commands automatically executed), but also for mail reading.

The usual router does not support much free memory and thus mails must be stored externally (either on a remote mount or on a USB device). It also does not support much processor power. This is especially important when reading large mailboxes and filtering messages.

Yet I use my router for e-mail reading and sending because it is running 24/7 and it is always connected to the internet. The advantage is quite clear: I can always read all my mails and there is no need for an extra machine for that purpose. Because the router is an always-on device, there is no need for fast filtering.

Most of my mail accounts are accessible by pop3 and smtp, some require secure connections over ssl. This is possible with FreeWRT since fetchmail and ssmtp support ssl. Mail is fetched by fetchmail and piped through procmail, which in turn uses bogofilter to classify mails as spam or non-spam. Procmail sorts mails into correct mailboxes. Mail reading is done via mutt. Sending mails is done via ssmtp (which is a sendmail replacement).

Installation

For the mail system to work properly one should compile a new firmware image with the following components activated:

  • fetchmail, be sure to activate the SSL support in case you want to fetch mail via secure pop3.
  • procmail must be activated.
  • bogofilter must be activated in case you want to filter your mail. bogoutil and bogotune are not essential.
  • mutt is needed for mail writing.
  • vilistextum can be used for viewing html mails in plain text. This package does not need much flash.

After selecting all packages correctly, you can build your new firmware image. Flashing, and then go over to Configuration.

Configuration

fetchmail

Incoming mail is retrieved by fetchmail. For this to work, you need a special fetchmailrc file in your home directory. If you do not have a normal user account yet, see chapter Setting up the user account. The file must be named .fetchmailrc and should be only readable by the user itself:

$ cd
$ touch .fetchmailrc
$ chmod go-rwx .fetchmailrc
$ cat >> .fetchmailrc << EOF
poll pop.mailprovider.tld
        proto pop3
        ssl
        keep
        is remote_mail_account_name there
        pass "very_secret"
        mda ''/usr/bin/procmail -f \%F -d \%T''
EOF

Here the configuration is as usual with fetchmail. The only difference is, that the mail is not given to a local smtp server but to procmail instead.

procmail

Procmail is a very powerful mail filtering tool. There are many scripts that use procmail to filter out spam (e.g. NiX Spam by iX), but we will use bogofilter instead. We need it to pipe the mail through bogofilter and sort it accordingly by the users preferences. Procmail is configured by a file called .procmailrc in the home directory of the user:

$ cd
$ cat >> .procmailrc << EOF
MAILDIR=$HOME/mail
DEFAULT=$MAILDIR/INBOX

# Keep a copy of all messages in the box ccopy.
# This is useful for testing and usually not needed in production.
# :0c
# $MAILDIR/ccopy

# Put all totally unreadable mail into a seperate folder.
:0:
* 1^0 ^\/Subject:.*=\?(.*big5|iso-2022-jp|ISO-2022-KR|euc-kr|gb2312|ks_c_5601-1987|windows-1251|windows-1256)\?
* 1^0 ^\/Content-Type:.*charset="(.*big5|iso-2022-jp|ISO-2022-KR|euc-kr|gb2312|ks_c_5601-1987|windows-1251|windows-1256)
$MAILDIR/spam-unreadable


# Put all mail through bogofilter and let it mark the mail with X-Bogosity header field
# If you are not interested in the scoring details, remove the -v flag
:0fw
| bogofilter -p -u -l -e -v
# -p)assthrough -u)pdate, -l)og -e)xitcode 0 for spam and ham
# -v)erbose


# Handle SPAM
# Put email to spam-bogofilter if bogofilter things it is spam.
:0H:
* ^X-Bogosity: Spam, tests=bogofilter
$MAILDIR/spam-bogofilter

# Handle Non SPAM
# Put email that is not considered spam into the correct folder.
:0E
{
# You can define your own rules here. Only messages that are not
# considered spam, will reach this line.
:0H:
* ^Sender: freewrt-developers-bounces@freewrt.org
$MAILDIR/FreeWRT

# Put any mail, that has not been sorted yet, into INBOX
:0:
$MAILDIR/INBOX
}
EOF

If you want to define your own filter rules, you are welcome. They usually go where the FreeWRT filter rule is placed. Filter rules are described in many how-to's. Use google.

bogofilter

Bogofilter does not really need any setup. You need a directory called .bogofilter in your home directory where bogofilter will store its database. Futher on, bogofilter should be trained. For that you should take some spam mail and some non spam mail (a few hundered up to some thousands each) and pipe it through bogofilter: Assuming all spam mail is saved in spam.mbox and all non spam mail is saved in ham.mbox, the following commands will be enough.

$ bogofilter -s < spam.mbox
$ bogofilter -n < ham.mbox

It is very useful, not to use too many mails this way (say more than 2,000), because the resulting database will grow too big. Training on error later on is more efficient but it requires a few mails trained in this way.

mutt

The configuration of mutt is very difficult due to the many different possible options. I will emphasize on the configuration aspects that are related to setting it up with the other tools. The .muttrc or .mutt/muttrc should contain at least the following lines (or equivalents):

# specify the mailbox setup
set folder="$HOME/mail";
set spoolfile = "+INBOX";
set record="+sent-mail"; set mbox="+received"; set postponed="+postponed";
mailboxes `find ~/mail -type f -print | egrep -v "(saved|/[.])" | xargs`

# automatically view html mails in ascii
auto_view text/html

#### HAM handling ####
# Mail sent by me is not spam. Tell this to bogofilter
set sendmail="~/.mutt/sendmail.sh"
macro index H "<pipe-message>bogofilter -n -S\n<save-message>=INBOX\n"          "Learn as ham and save in INBOX"
macro pager H "<pipe-message>bogofilter -n -S\n<save-message>=INBOX\n"          "Learn as ham and save in INBOX"

#### SPAM handling ####
macro index S "<pipe-message>bogofilter -s -N\n<delete-message>"  "Learn as spam and delete message"
macro pager S "<pipe-message>bogofilter -s -N\n<delete-message>"  "Learn as spam and delete message"

Here, you can see, the auto\_view text/html which activates automatic display of html mails. The sendmail variable is set to execute a script in the .mutt directory called sendmail. The sendmail script must then contain a pipe which first tells bogofilter the mail and then sends it out through sendmail:

$ cd
$ cat >> .mutt/sendmail << EOF
#!/bin/sh
/usr/bin/bogofilter -n -p | /usr/sbin/sendmail -oem -oi $*
EOF

vilistextum

In order for the auto\_view setting to work, we need a .mailcap file in the home directory of the user which ensures the call of vilistextum:

$ cd
$ cat >> .mailcap << EOF
text/html; vilistextum %s -; copiousoutput
EOF

There are no other actions needed for vilistextum to work.

ssmtp

Sending mail currently stops behind the pipe through bogofilter in .mutt/sendmail. The configuration of ssmtp is very simple. The file /etc/ssmtp/ssmtp.conf must contain the following lines and must be readable by the user:

mailhub=smtp.mailserver.tld
AuthUser=remote_mail_account_name
AuthPass=very_secret
AuthMethod=cram-md5
FromLineOverride=YES

If you have multiple mail accounts and you want to be able to send mail from all those email addresses, this configuration won't be enough in all cases. My provider allows sending mail for other users and thus, i can simply change the from-header in mutt and send the mail. ssmtp does not change back to my default email address due to FromLineOverride?=YES. So if your provider also allows different from-fields, this configuration should be enough.

Usage

After configuring your mail system, you can call fetchmail as the user to get new mails and start mutt to read them and send new ones. Alternatively you can use the fetchmail daemon as follows:

$ echo su -c "fetchmail -d 900" username >> /etc/rc.local
$ chmod +x /etc/rc.local

This will start fetchmail in daemon mode for username with a polling interval of 900 seconds on startup. It does not ensure the restart in case of a program crash.

When bogofilter classifies mail as spam that is non spam, you can simply go to the folder spam-bogofilter, select the corresponding mail and press H. This will unregister the message as spam and register it as non spam. Vice versa you can select a mail in INBOX that is spam and press S. Mails from spam-bogofilter will be moved to INBOX when H is pressed, mails in INBOX will simply be deleted after pipeing through bogofilter. You should regularily check spam-bogofilter for falsely sorted mail.

Setting up the user account

Setting up a new user account is quite simple: Login as root and edit the file /etc/passwd and insert a new line containing:

username::1001:100:Your Name:/homedir:/bin/sh

Replace username, Your Name, /homedir accordingly to your setup. For homedir /mnt/disc0\_1 is a good choice if you are using a USB storage device that is already working.

In case you do not have a group 100, edit the file /etc/group and add:

user:x:100:

Now you should change the password for the new user by executing this as root:

# passwd username
passwd: no record of username in /etc/shadow, using /etc/passwd
Changing password for username
New password: [Enter your new password here and press enter]
Bad password: too weak
Retype password: [Enter the same password again and press enter again]

If your password is not a good choice, passwd will tell you but will go on normaly even though it is not a good idea to use a weak password.