Mail workshop handout

Getting Sendmail running

go to:



make cf

Given the way that the Makefile is constructed, if there are no preexisting cf files a new mc file will be created with your hostname pre-pended then compiled into a cf file also with your hostname pre-pended .


make install

will install the as the

On FreeBSD systems the instructions start a service at boot time go in the file /etc/rc.conf. The examples for entries to the /etc/rc.conf are to be found in /etc/defaults/rc.conf. See if you can find the line required to enable sendmail in /etc/defaults/rc.conf, and put it in /etc/rc.conf. Then you should be able to type:

/etc/init.d/sendmail start

and sendmail should start up.

how can you tell? try:

telnet localhost 25

Are there any other ports that sendmail might be listening on? how about 587?

If sendmail is running, the first question I always ask myself when firing up a mailserver for the first time is, am I an open relay?

Try the following to test it out.

from another machine:

telnet the_ip_of_your_mailserver 25


mail from:

rcpt to:

Was it willing to relay for you?

if not then we aren't.

Relaying for our users

At this point the system is capable of accepting mail for local delivery and you can send mail from the local system to the outside world, but customers on our network won't be able to relay mail through the machine.

Take a look at /etc/mail/access.sample

It's a good idea to copy /etc/mail/access.sample to /etc/mail/access rather than just starting from scratch so that you have the examples in the file you'll be editing.

Comment out all of the existing lines, and lets add one relay line for the subnet that we are using during the workshop.

Once you've saved the file, type:


in the the /etc/mail directory. You'll note that it has now created an accessdb which is the file that sendmail will actually check when attempting to determine if a host is authorized to relay.

Did it work? restart sendmail and find out.

Local delivery with procmail

It is possible to use procmail as end user by having a .forward file invoke procmail, but it's vastly more elegant to have procmail serve as the local delivery agent for sendmail.

Why do we need this? Because procmail allows us greater flexibility in delivery and enables user specific customization, for things like filtering messages into folders, forwarding mail, blacklisting addresses etc...

Before we configure sendmail to use procmail for mail-delivery we need to install it from the ports first. type:

cd /usr/ports/procmail


Note that procmail is heavily dependant on filesystem locking working so it does some tests before building.

note also the warning which is highly useful information for us.

then type:

make install

Now we need to integrate it into our host specific .mc file.

cd /etc/mail


Scroll down until you find the section of features.

Add a comment so that you'll know what it was that you were doing when you have to look at the file in the future. note that in sendmail mc files (which are written in m4) the string dnl will keep it from interpreting the line.

dnl enabling local-delivery via procmail

Then enable the feature.


save the file. then do:

make cf

to build the cf file from the mc file. Then:

make install

to install the as the

Then restart sendmail.

Delivery into user home directories

In a traditional unix mail environment mail is delivered in /var/mail, user created folders on the other-hand will be in ~username or ~username/mail.

We want to deliver mail into user home directories for a couple reasons:

If we are enforcing quotas /var/mail causes us to have two that have to get manged separately.

if we have problems with i/o scalability separating users off into seperate home filesystems is easy, they can live on different disks or even different nfs servers splitting apart /var is a bit harder.

Since we're using procmail for mail delivery now, where mail is delivered is controlled by the environment variable MAIL=. If we set that value in the system-wide procmailrc which lives in /usr/local/etc/procmailrc, it will be honored for all users unless overridden.

There isn't one now, so create it with the following information:




Note that while procmail will create the inbox folder if it does not exist. it will not create the maildir folder.

The solution to the maildir creation is to create the dirctory Maildir in the directory /usr/share/skel so that when user accounts are created, the directory is installed in in their account as well. You will have to create it for any preexisting accounts that you want to deliver mail to.

Installing clamav

The best way to plug clamav into mail delivery is as a sendmail milter. Doing so allows it to parse data delivered to sendmail while the connection is still open so that mail can be accepted or rejected while the connection to the remote mail sender is still up.

Go to:




will prompt you to select options you may need to enable:


Options for clamav 0.88.2_4 │

│ ┌────────────────────────────────────────────────────────────────┐ │

│ │ [ ] MILTER Compile the milter interface │ │

│ │ [ ] CURL Support URL downloading │ │

│ │ [ ] LIBUNRAR Support for external Unrar library │ │

│ │ [ ] STDERR Print logs to stderr instead of stdout │ │

│ │ │ │

│ │ │ │

│ │ │ │

│ │ │ │

│ │ │ │

│ │ │ │

│ │ │ │

│ │ │ │

│ │ │ │

│ │ │ │

│ │ │ │


[ OK ] Cancel │


We do need the milter interface, so you'll have to select that.

Note that when you type:

make install

it will pull in some additional depandancies that we're required to build but are required to actually run it.

Once it's installed we have two additional steps left before it's usable:

Get clamd and freshclam running.

Get clamav milter installed in sendmail and running.

third party packages install their rc files in:


in that directory look at the files clamav-clamd clamav-freshclam and clamav-milter

so we need to add the following lines to /etc/rc.conf:

#starting clamd freshclam and milter




Then we can start clamd and freshclam.

to enable the milter in sendmail, we need to add the line:

INPUT_MAIL_FILTER(`clamav', `S=local:/var/run/clamav/clmilter.sock, F=T, T=S:4m;R:4m')

to our /etc/mail/

then make the cf and install it as the

note two key things:


points to the location of the socket where sendmail will contact the clamav milter


Indicates the the behavior of sendmail if it can't contact clamav-milter. In this case it indicates that sendmail should defer messages with a transient failure. If you want to to continue to deliver mail in the event of a failure you want to remove that.

After that we should be able to stop sendmail start the clamav-milter and then start sendmail.


The spamassassin port is slightl unituitively called p5-Mail-Spamassassin

cd /usr/ports/mail/p5-Mail-SpamAssassin



Options for p5-Mail-SpamAssassin 3.1.1_4 │

│ ┌────────────────────────────────────────────────────────────────┐ │

│ │ [X] AS_ROOT Run spamd as root (recommended) │ │

│ │ [ ] DOMAINKEYS DomainKeys support │ │

│ │ [X] SSL Build with SSL support for spamd/spamc │ │

│ │ [ ] MYSQL Add MySQL support │ │

│ │ [ ] PGSQL Add PostreSQL support │ │

│ │ [X] RAZOR Add Vipul's Razor support │ │

│ │ [ ] SPF_QUERY Add SPF query support │ │

│ │ [ ] RELAY_COUNTRY Relay country support │ │

│ │ [ ] TOOLS Install SpamAssassin tools │ │

│ │ │ │

│ │ │ │

│ │ │ │

│ │ │ │

│ │ │ │

│ │ │ │


[ OK ] Cancel │


make install

You'll note that while it pulls in a few dependancies in order to build it pulls in a whole lot when you go to install it.

Look at /usr/local/etc/rc.d/sa-spamd

Edit /etc/rc.conf accordingly.

Look at /usr/local/etc/mail/spamassassin/init.pre and

copy to and salt to taste (adjust according to your preferences)

some changes we make for our users at the UO are:

use_bayes 0

report_safe 0

one of my personal favorites is:

rewrite_header Subject *SPAM* _HITS_

Now we have to get spam-assassin in the delivery path of mail. we're going to do this procmail because that will allow later user customization.

place the following in the system-wide procmailrc


* < 5000000

| /usr/local/bin/spamc

This filters all messages smaller than a certain size (5MB) through spamassassin... You could filter all messsages through it ,but in general very large messages aren't spam (greater than 300KB or so currently) and they are expensive to process.

Note that we're not doing any post processing so spam is simply delivered along with regular mail albeit with the header rewritten. we could add a rule:


* ^X-Spam-Status: Yes


that would deliver all mail into a users spam folder... (got to manage that resource)



* ^X-Spam-Status: Yes


better be sure that the false postive rate is pretty low.


cd /usr/ports/mail/dovecot/


don't need any of the options

make install

do need a group and user for dovecot

copy /usr/local/etc/dovecot-example.conf to /usr/local/etc/dovecot.conf

the first critical thing we need to change is the default mail-environment

note it's currently set to:

default_mail_env = mbox:/var/mail/%u

we're going to set it to:

default_mail_env = maildir:%h/Maildir:INBOX=%h/Maildir/Inbox:INDEX=%h/Maildir/.imapidx

we also need to tell dovecot where it's ssl private key and cert are (we'll generate them in a moment.

find the line:

#ssl_cert_file = /etc/ssl/certs/dovecot.pem

uncommnet it and cahnge it to:

ssl_cert_file = /etc/ssl/certs/dovecot.crt

and the following line change to:

ssl_key_file = /etc/ssl/certs/dovecot.pem

make sure that the protocols we're supporting are:

protocols = imap pop3 imaps pop3s

I bet you can guess that we need to add:


to the /etc/rc.conf

Note also that dovecot as currently configured is dependant on an ssl certificate being present (you want it to be secure right).

cd /etc/ssl/

mkdir certs

cd certs

openssl genrsa -des3 -out dovecot.key 1024

Lets remove the password from that key so that we have one that apache can use to start up without prompting us with the password.

openssl rsa -in dovecot.key -out dovecot.pem

In order generate a certificate we first need to generate a certificate signing request.

openssl req -new -key dovecot.key -out dovecot.csr

Follow the prompts, note that common name is the name of the server. If you were going to get a certificate signed by a certificate authority, you would take the csr an send it to them. We are going to sign our own cert with our private key.

openssl x509 -req -days 60 -in dovecot.csr -signkey dovecot.key -out dovecot.crt

Now we should have all all the pieces in place to start dovecot.