Topic: PostfixCourierIMAP MySQL Virt. hosts + optionals ClamAV & SpamAssassin
Preamble
I take no credit for the immense hardwork done by several people; this howto is built extensively upon their howtos which can (at the time of this writing) be found here:
http://kirb.insanegenius.net/postfix.html
http://www.ezunix.org/modules.php?op=mo … amp;page=1
http://ntecs.de/blog/Tech/Sysadm
I thank them greatly for what they have done, and for making this possible. I am simply using their howtos to create a complete as possible NetBSD version. A *LOT* of this howto will be a direct copy of their work - I am NOT taking credit for those bits!
Although this howto is predominantly aimed at NetBSD, only the location of files and the process used to start each of the daemons should be NetBSD specific - the rest should be generic in nature.
Purpose
The purpose behind this document is to create a mail server solution that includes postfix as the MTA, Courier-IMAP as the IMAP/POP server and MySQL for all potentially dynamic configuration. The goal is to have completely virtual users and domains. jimbob@domain1.com != jimbob@domain2.com. This means creating a separate namespace for each domain.
Theory
The first thought is how to create that separate namespace. Using Postfix virtual delivery agent, the problem is relatively trivialized. You just deliver mail to the appropriate maildir for the appropriate address. Postfix really doesn't care that you have multiple people named jimbob because it looks at the entire address. Separate namespace for Courier gets a little trickier. You could ask all of your users to login as user@domain.com or user.domain.com or even user.somenumber and this is the best solution we've come up with so far. The problem with user@domain.com logins is that drain bamaged MUA's may interpret that to mean one's complete address is "user@domain.com@domain.com". Needless to say, this is bad. Of course, the same faulty MUA's might cause problems with thinking "user.domain.com@domain.com" is the address...
Installation
I'm a *HUGE* fan of pkgsrc, so recommend its use where possible. We first need to setup our needed options which is done by adding them to /etc/mk.conf:
# echo "PKG_OPTIONS.courier-authlib=mysql" >> /etc/mk.conf
# echo "PKG_OPTIONS.postfix=mysql" >> /etc/mk.confNow, to install the programs needed, simply:
# cd /usr/pkgsrc/databases/mysql4-server
# make install clean clean-depends
# cd /usr/pkgsrc/security/courier-authlib
# make install clean clean-depends
# cd /usr/pkgsrc/mail/courier-imap
# make install clean clean-depends
# cd /usr/pkgsrc/mail/postfix
# make install clean clean-dependsthis will install all that we need to complete this HowTo.
Setup and Start MySQL
You can start the MySQL server doing the following steps:
# echo "mysqld=yes" >> /etc/rc.conf
# cp /usr/pkg/share/examples/rc.d/mysqld /etc/rc.d
# /etc/rc.d/mysqld startYou now need to set the root password to secure your db, change new-password to suit your memory:
/usr/pkg/bin/mysqladmin -u root -p password 'new-password'
/usr/pkg/bin/mysqladmin -h `hostname` -u root -p password 'new-password'The Database
Here is the quick description of the database:
mysql> show tables;
+------------------+
| Tables_in_maildb |
+------------------+
| transport |
| users |
| virtual |
+------------------+
3 rows in set (0.00 sec)
mysql> describe transport;
+-----------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------+--------------+------+-----+---------+-------+
| domain | varchar(128) | | PRI | | |
| transport | varchar(128) | | MUL | | |
+-----------+--------------+------+-----+---------+-------+
2 rows in set (0.00 sec)
mysql> describe virtual;
+---------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------+--------------+------+-----+---------+-------+
| address | varchar(255) | | PRI | | |
| goto | varchar(255) | | | | |
+---------+--------------+------+-----+---------+-------+
2 rows in set (0.01 sec)
mysql> describe users;
+---------+----------------------+------+-----+----------------------------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------+----------------------+------+-----+----------------------------+-------+
| id | varchar(128) | | PRI | | |
| address | varchar(128) | | UNI | | |
| crypt | varchar(128) | | | | |
| clear | varchar(128) | | | | |
| name | varchar(128) | | | | |
| uid | smallint(5) unsigned | | | 0 | |
| gid | smallint(5) unsigned | | | 0 | |
| home | varchar(128) | | | /var/spool/postfix/virtual | |
| domain | varchar(128) | | | | |
| maildir | varchar(255) | | | | |
| imapok | tinyint(3) unsigned | | | 1 | |
| bool1 | tinyint(3) unsigned | | | 1 | |
| bool2 | tinyint(3) unsigned | | | 1 | |
+---------+----------------------+------+-----+----------------------------+-------+
13 rows in set (0.01 sec)Database Notes
Transport table:
The transport table is your transport map. It tells postfix what transport agent to use for each domain. It is not absolutely necessary if you want all of your users to be in the database. We do , however, highly recommend using a transport map. Having at least one domain handled with the local delivery agent means, among other things, simplicity if you have to deal with mailing lists later and that any users added to the system as system users will automatically receive mail properly. Even if you have domains explicitly defined in the mydestinations config option for postfix, you should make sure that every domain has a corresponding entry in the transport map. Another nice feature of the transport map is that you do not have to define mydestinations explicitly, simply add $transport_maps to mydestinations and you have all your domains added cleanly and effectively without having to reload Postfix when you add a domain.
domain = Any domain you host. Including those you want to deliver to using local: as the transport.
transport = The transport method. All transport methods are legal, but usually either "local:" for local transport or "virtual:" for the virtual transport agent.Virtual table:
The virtual table is your virtual map. It is similar to aliases, but different. An entry in virtual cannot point to an executable or a file. It is simply address to address mapping. However, this doesn't mean it has to be one to one. You can have a single virtual alias point to multiple addresses in a comma-delimited list. The important thing to remember is that you can have either sendmail-style or postfix-style virtual domains. Under sendmail-style, all local aliases and users exist in the virtual domain's namespace as well. In other words, a local user jimbob would be able to recieve jimbob@virtual1.com, jimbob@virtual2.com, and jimbob@localmachinedomain.com all at the same time. This can cause a problem when hosting many domains (or only a few if you have more than one user named JimBob.) Enter postfix-style virtuals. With a postfix-style virtual, the virtual domain doesn't share anything. You must define every alias and/or user within that domain. One caveat is that this means root and postmaster aliases must be defined for every postfix-style virtual. In order to implement a postfix-style virtual, you will need one line in your virtual map that has the domain name on the left, and some random text on the right. One handy way of doing this in a database virtual table is to have an entry where address is the domain name and goto is the name of the domain owner, or some other informative little piece of text. A nice convention is to use sendmail-style virtuals on all of your domains that are delivered with the local delivery agent and postfix-style on all of your domains delivered with the virtual agent. For a more thorough description of the virtual table and sendmail-style vs. postfix-style virtuals, please read "man 5 virtual".
address = This is the virtual address address@domain.tld which will be forwarded to the address in goto. For Postfix-style virtuals, this will also be the domain name.
goto = Where the virtual address above goes. This can be a comma-delimited list of addresses. It can include simply "user" entries for local users (root, postmaster, etc.), or, more commonly, complete user@domain.tld entries for users in virtual domains on your machine or for going out to other domains.Users table:
The users table is the heart and soul of this whole thing. Transport and Virtual can easily be done as text files, but the users table makes this all worthwhile. While the other two tables are used only by Postfix, this table is shared between Postfix and Courier. That leads to interesting decisions in design. First of all, some will note the different id and address fields. In some cases, these fields may be identical. In that case, remove the address field, and replace address in all postfix config files with id. The reason there are two different fields is so you can use user.domain.tld, or user.somenumber or something along those lines rather than user@domain.tld as a username. If you plan on using user@domain.tld for logins and never changing it, don't waste space on an address field. Another important thing to remember is that the encrypted form of the password must be encrypted using the OS crypt(), not with MySQL's default encryption algorithm. This can be done by using crypt=encrypt('password') in your insert or update statement. You can increase the security of this by giving encrypt a second argument of a two-character salt. If you write a user management program to handle your data additions and updates, then creating it randomly will be useful. You can then use encrypt('password','salt') for the improved security. You also should note that you can have as many or as few (including none) of the fields beginning with "imapok" above. Those fields are not required, but can come in handy as mentioned in the table description. Also, remember that if you would like to use the maildir quota extension in courier-imap, you will need to add a quota field to hold that. Probably an unsigned int would be more than sufficient.
Important I have recently found that spaces within the passwd (crypted / unencrypted) seem very hit and miss as to whether they work. I suggest NOT using spaces - so be warned.
id = username. Either user.domain.tld or user@domain.tld
address = email address. user@domain.com
crypt = The crypt() form of the password. The easies way to accomplish this is to use encrypt('password') in your insert query
clear = Clear text password. (for support purposes or Cram-MD5) You really only need one of the two password forms. If you choose that one to be clear, make sure ALL of your users can handle Cram-MD5 authentication
name = Users real name or whatever string you feel belongs here. (not required unless you tell Courier it's there.)
uid = virtual uid
gid = virtual gid. (hint to make your life simpler: Make each domain have one and only one gid)
home = You can set this to just about anything above your maildir directory. Easiest (but not very secure) is to set it to "/". If you are running postfix chroot, this needs to be somewhere inside of the jail. For instance, "/var/spool/postfix/". And, yes, the maildirs must all be subdirectories of this directory
domain = user's domain name. This is far from necessary but comes in handy for support/programming purposes
maildir = This is the users maildir. Use the full path. You don't have to, but use the full path. If this is a maildir, make sure that you include the trailing slash. (e.g. .../Maildir/ and NOT .../Maildir) Of course, if you want to use mbox (why, oh why?!) then you would need to exclude the slash
imapok = This field would allow one to prevent users from accessing their mail by setting it to 0 if you use the appropriate Courier setting in authmysqlrc of "MYSQL_WHERE_CLAUSE= imapok" This could be useful for torturing your users, among other things
bool1 = Same as above
bool2 = ditto. (yes, Kirby is an aspiring BOFH, how'd you guess?)Create the Database
To make your (our) life easier, a MySQL database creation script has been created. Simply copy the mysql script into a 'filename' and at the command line type:
# mysql -u root -p < filename
Enter password:
#issuing the password you created above (the new-password one). Here's the mysql script:
#First Create the Database
CREATE DATABASE maildb;
use maildb;
#
# Table structure for table 'transport'
#
CREATE TABLE transport (
domain varchar(128) NOT NULL default '',
transport varchar(128) NOT NULL default '',
UNIQUE KEY domain (domain)
) TYPE=MyISAM;
#
# Table structure for table 'users'
#
CREATE TABLE users (
id varchar(128) NOT NULL default '',
address varchar(128) NOT NULL default '',
crypt varchar(128) NOT NULL default '',
clear varchar(128) NOT NULL default '',
name varchar(128) NOT NULL default '',
uid smallint(5) unsigned NOT NULL default '1000',
gid smallint(5) unsigned NOT NULL default '1000',
home varchar(128) NOT NULL default '/var/spool/postfix/virtual',
domain varchar(128) NOT NULL default '',
maildir varchar(255) NOT NULL default '',
imapok tinyint(3) unsigned NOT NULL default '1',
bool1 tinyint(3) unsigned NOT NULL default '1',
bool2 tinyint(3) unsigned NOT NULL default '1',
PRIMARY KEY (id),
UNIQUE KEY id (id),
UNIQUE KEY address (address),
KEY id_2 (id),
KEY address_2 (address)
) TYPE=MyISAM;
#
# Table structure for table 'virtual'
#
CREATE TABLE virtual (
address varchar(255) NOT NULL default '',
goto varchar(255) NOT NULL default '',
UNIQUE KEY address (address)
) TYPE=MyISAM;Now we create our user and password to access the DB:
# mysql -u root -p maildb
Enter password:
mysql> GRANT ALL ON maildb.* TO 'uname'@'localhost' IDENTIFIED BY 'passwd';
Query OK, 0 rows affected (0.01 sec)
mysql>FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec)
mysql> \q
Bye
#Further Notes on the Database
You might, after looking at the above, be wondering why on a few data type and indexing choices. Well, according to the mysql docs, varchar is faster in lookups and takes less space than char, so that's why it is used for all strings here. As for the size of integers, it was just logical choosing based on potential size of the values. In the case of the essentially boolean values, even the tinyint given to them is too much. These could easily be defined as "int(1) unsigned" if MySQL allows. You could also go with ENUM as a data type for these. See MySQL docs for more details. As for indexing and such, it's a good idea to have both id and address unique and indexed for faster lookups since almost every select performed on the users table will include either id or address in the where clause. On transport, it's a good idea to index the domain field. On virtual, you definitely want address indexed. Your virtual table will get very large, very quickly, when you consider that every virtual domain will have three minimum entries. As you can see, the general idea is to index any field that is likely to show up in a where clause in database query. One other thing on the database: If you run Postfix in a chroot jail, and you are using localhost as your mysql server, you might want to add a hardlink to the mysql socket somewhere inside the jail/sandbox you are running in. Of course, this will likely break when you restart the MySQL server. Instead, it would be better to just use TCP. You can even use TCP with everything on the same system. Consult the MySQL documentation for details.
Configure Postfix
run the following command to update main.cf and master.cf with the latest Postfix services and configuration directives:
# /usr/pkg/sbin/postfix upgrade-configurationConfigure postfix to start on boot
# echo "postfix=YES" >> /etc/rc.conf
# echo "sendmail=NO" >> /etc/rc.confThe existing /etc/rc.d/postfix can be forced to start /usr/pkg/sbin/postfix instead of /usr/sbin/postfix, by adding the following lines to /etc/rc.conf.d/postfix:
required_files='/usr/pkg/etc/postfix/main.cf'
start_cmd='/usr/pkg/sbin/postfix start'
stop_cmd='/usr/pkg/sbin/postfix stop'
reload_cmd='/usr/pkg/sbin/postfix reload'Before we can start changing system wide files we need to stop sendmail; find the process and kill it:
# ps aux | grep sendmail
root 500 0.0 0.5 1012 1828 ?? Ss Wed08AM 0:03.61 sendmail: accepting connections
# kill 500
#/etc/mailer.conf needs to be updated with the correct information. Change it to the following:
sendmail /usr/pkg/sbin/sendmail
send-mail /usr/pkg/sbin/sendmail
mailq /usr/pkg/sbin/sendmail
newaliases /usr/pkg/sbin/sendmailIf you don't want all users, including those locally defined to be in the database, you'll want to set up a transport map. We used a database-driven transport map as described above. We will assume transport to be either "virtual:" for virtual delivery or "local:" for local delivery. Other methods are available, but are beyond the scope of this howto. The files listed here will be in your postfix config directory, which will be /usr/pkg/etc/postfix
in main.cf add the following lines
transport_maps=mysql:/usr/pkg/etc/postfix/transport.cf
mydestination = $mydomain, $myhostname, $transport_maps
virtual_mailbox_maps=mysql:/usr/pkg/etc/postfix/mysql_virt.cf
virtual_uid_maps=mysql:/usr/pkg/etc/postfix/uids.cf
virtual_gid_maps=mysql:/usr/pkg/etc/postfix/gids.cf
#You might want to change the following to something you'd prefer - BUT the 'home' field in the database MUST match
virtual_mailbox_base=/var/spool/postfix/virtual
virtual_maps=mysql:/usr/pkg/etc/postfix/virtual.cf
# The following two lines are optional, and hopefully self explanitory
virtual_mailbox_limit=102400000 # 100MB
virtual_minimum_uid=100in master.cf you need to uncomment or add these lines if they aren't already there.
smtp inet n - n - - smtpd
virtual unix - n n - - virtualNow create the following files:
transport.cf
user=uname
password=passwd
dbname=maildb
table=transport
select_field=transport
where_field=domain
hosts=localhostmysql_virt.cf
user=uname
password=passwd
dbname=maildb
table=users
select_field=maildir
where_field=address
hosts=localhostuids.cf
user=uname
password=passwd
dbname=maildb
table=users
select_field=uid
where_field=address
hosts=localhostgids.cf
user=uname
password=passwd
dbname=maildb
table=users
select_field=gid
where_field=address
hosts=localhostvirtual.cf
user=uname
password=passwd
dbname=maildb
table=virtual
select_field=goto
where_field=address
hosts=localhostConfigure Courier-IMAP
The file to edit in Courier-IMAP is "authmysqlrc". You'll want to define the following within it appropriately. I've noticed that the sample config file is well-commented on my installation. Hopefully the same is true for you. If you do not see a authmysqlrc.dist or some sample authmysqlrc, the below should give you a working configuration. There are a few other options, but we will not cover them here as they are unnecesary for our purposes. One of note is MYSQL_QUOTA_FIELD which allows you to use the courier quota extensions to maildir. The files below should be located in your courier-auth directory, /usr/pkg/etc/authlib:
Settings in authmysqlrc
MYSQL_SERVER localhost #your mysql server
MYSQL_USERNAME uname
MYSQL_PASSWORD passwd
MYSQL_SOCKET /tmp/mysql.sock #necessary if you are on localhost
MYSQL_DATABASE maildb
MYSQL_USER_TABLE users
MYSQL_CRYPT_PWFIELD crypt
MYSQL_CLEAR_PWFIELD clear
MYSQL_UID_FIELD uid
MYSQL_GID_FIELD gid
MYSQL_LOGIN_FIELD id
MYSQL_HOME_FIELD home
MYSQL_NAME_FIELD name
MYSQL_MAILDIR_FIELD maildir
MYSQL_WHERE_CLAUSE imapok=1 AND bool1=1 AND bool2=1IMPORTANT NOTE: key values should be seperated with tabs NOT spaces!!!
Settings in authdaemonrc
#replace authpam with whatever your local auth is, authpwd, authsasl, whatever.
authmodulelist="authmysql authpam"
# If you only want users who are in the database to login, then only use authmysql above
version="authdaemond.mysql"Sample Database Entries
Here is a sample of what should be in your database. It's one domain, "foo.com" with a single user "John Doe" who has the email adree "johndoe@foo.com". He also has two aliases, "root@foo.com" and anything not already assigned to a mailbox at "foo.com":
mysql> INSERT INTO transport VALUES ('foo.com', 'virtual:');
Query OK, 1 row affected (0.00 sec)
mysql> select * from transport;
+----------+-----------+
| domain | transport |
+----------+-----------+
| foo.com | virtual: |
+----------+-----------+
1 row in set (0.01 sec)
mysql> INSERT INTO virtual VALUES ('@foo.com', 'johndoe@foo.com');
Query OK, 1 row affected (0.00 sec)
mysql> select * from virtual;
+--------------+-----------------+
| address | goto |
+--------------+-----------------+
| root@foo.com | johndoe@foo.com |
| @foo.com | johndoe@foo.com |
+--------------+-----------------+
2 rows in set (0.00 sec)
mysql> INSERT INTO users VALUES ('johndoe', 'johndoe@foo.com', encrypt('abc'), 'abc', 'John Doe', '5000', '5000', '/', 'foo.com', 'foo.com/johndoe/', '1', '1', '1');
Query OK, 1 row affected (0.00 sec)
mysql> select * from users;
+---------+-----------------+---------------+-------+----------+------+------+...
| id | address | crypt | clear | name | uid | gid |
+---------+-----------------+---------------+-------+----------+------+------+...
| johndoe | johndoe@foo.com | uduM6SQn95Xjo | abc | John Doe | 5000 | 5000 |
+---------+-----------------+---------------+-------+----------+------+------+...
...+----------------------------+---------+------------------+--------+-------+-------+
| home | domain | maildir | imapok | bool1 | bool2 |
...+----------------------------+---------+------------------+--------+-------+-------+
| /var/spool/postfix/virtual | foo.com | foo.com/johndoe/ | 1 | 1 | 1 |
...+----------------------------+---------+------------------+--------+-------+-------+
1 row in set (0.00 sec)Create the directories
Based upon the user we just created, we need to create our directory structure:
# cd /var/spool/postfix
# mkdir virtual
# chown postfix:postfix virtual
# cd virtual
# mkdir foo.com
# chown postfix:postfix foo.com
# chmod 0775 foo.com
# cd foo.com
# mkdir johndoe
# chmod 0770 johndoe
# chown 5000:5000 johndoeStarting the services
Now that everything is in place, we'll setup and start the services.
Courier-Imap Auth
# cp /usr/pkg/share/examples/rc.d/authdaemond /etc/rc.d
# echo "authdaemond=YES" >> /etc/rc.conf
# /etc/rc.d/authdaemond start
Starting authdaemond.
#Courier-Imap
# cp /usr/pkg/share/examples/rc.d/courierimap /etc/rc.d
# echo "courierimap=YES" >> /etc/rc.conf
# /etc/rc.d/courierimap start
Starting courierimap.
# cp /usr/pkg/share/examples/rc.d/courierimaps /etc/rc.d
# echo "courierimaps=YES" >> /etc/rc.conf
# /etc/rc.d/courierimaps start
Starting courierimaps.
#Postfix
# /etc/rc.d/postfix start
postfix/postfix-script: starting the Postfix mail system
#What about POP3?
If you'd rather have your email users use pop3 (so the email load isn't sitting on your server) CourierIMAP includes a pop3 daemon which you simply need to "turn on":
# cp /usr/pkg/share/examples/rc.d/courierpop /etc/rc.d/
# echo "courierpop=YES" >> /etc/rc.conf
# /etc/rc.d/courierpop start
Starting courierpop.
#OPTIONAL CLAMAV VIRUS CHECKING
Facing the realities of this world, you may be hosting email that contains viri. So the following will update postfix to use ClamAV to scan for viri:
# cd /usr/pkgsrc/mail/clamav
# make install clean clean-depends
# cd /usr/pkgsrc/mail/clamsmtp
# make install clean clean-dependsFirst thing to do is update the viri database. Edit /usr/pkg/etc/clamd.conf and /usr/pkg/etc/freshclam.conf, and comment the "Example" line in both, which looks as follows:
# Comment or remove the line below.
ExampleNow update the viri database with this command (you may also want to cron this command to keep your database updated):
# /usr/pkg/bin/freshclam
ClamAV update process started at Sat Apr 2 22:08:55 2005
Downloading main.cvd [*]
main.cvd updated (version: 30, sigs: 31086, f-level: 4, builder: tkojm)
Downloading daily.cvd [*]
daily.cvd updated (version: 802, sigs: 1273, f-level: 4, builder: arnaud)
Database updated (32359 signatures) from database.clamav.net (IP: 62.26.160.3)
#Now start ClamAV:
# cp /usr/pkg/share/examples/rc.d/freshclamd /etc/rc.d/freshclamd
# echo "freshclamd=YES" >> /etc/rc.conf
# /etc/rc.d/freshclamd start
Starting freshclamd.
# cp /usr/pkg/share/examples/rc.d/clamd /etc/rc.d/clamd
# echo "clamd=YES" >> /etc/rc.conf
# /etc/rc.d/clamd start
Starting clamd.
#Now configure and start ClamSMTP:
Edit /usr/pkg/etc/clamsmtpd.conf and add the following line in the appropriate place:
ClamAddress: /tmp/clamdand start the daemon:
# cp /usr/pkg/share/examples/rc.d/clamsmtpd /etc/rc.d/clamsmtpd
# echo "clamsmtpd=YES" >> /etc/rc.conf
# /etc/rc.d/clamsmtpd start
Starting clamsmtpd.
#Configure postfix to use ClamAV
In main.cf add these lines:
content_filter = scan:localhost:10025
receive_override_options = no_address_mappingsIn master.cf add these:
# AV scan filter (used by content_filter)
scan unix - - n - 16 smtp
-o smtp_send_xforward_command=yes
# For injecting mail back into postfix from the filter
localhost:10026 inet n - n - 16 smtpd
-o content_filter=
-o receive_override_options=no_unknown_recipient_checks,no_header_body_checks
-o smtpd_helo_restrictions=
-o smtpd_client_restrictions=
-o smtpd_sender_restrictions=
-o smtpd_recipient_restrictions=permit_mynetworks,reject
-o mynetworks_style=host
-o smtpd_authorized_xforward_hosts=127.0.0.0/8Now have Postfix use the new ClamAV setup:
# /usr/pkg/sbin/postfix stop
postfix/postfix-script: stopping the Postfix mail system
# /usr/pkg/sbin/postfix start
postfix/postfix-script: starting the Postfix mail system
#Emails that are scanned will contain an extra header as follows:
X-Virus-Scanned: ClamAV using ClamSMTPOPTIONAL SPAMASSASSIN CHECKING
SpamAssassin is a well known app designed to tag email as spam based upon a score rating. The configuration specifics of SpamAssassin are beyond the scope of this HowTo, however, full details can be found at: http://spamassassin.apache.org/doc.html NetBSD's default location for the configuration files is : /usr/pkg/etc/spamassassin We first install spamassassin:
# cd /usr/pkgsrc/mail/spamassassin
# make install clean clean-dependsYou can now edit the main spamassassin config file to suit your needs /usr/pkg/etc/spamassassin/local.cf, although the default is actually quite good. Ensure you have at least the following:
rewrite_header Subject *****SPAM*****A useful online generator can be found here: http://www.yrex.com/spam/spamconfig.php
You can then easily create your own rules within the file. For example, the following searches for the word "pharmacy" in the body of emails utilising Perl's standard matching methodology; and then gives it a score of 1.0 - the default is 5.0 before the email is classed as spam:
body PHARMACY_WORD_SEARCH /pharmacy/i
score PHARMACY_WORD_SEARCH 1.0Now we can start the SpamAssassin daemon (spamd):
# cp /usr/pkg/share/examples/rc.d/spamd /etc/rc.d/spamd
# echo "spamd=YES" >> /etc/rc.conf
# /etc/rc.d/spamd start
Starting spamd.
#Finally, we simply need to tell Postfix to use SpamAssassin on all incoming emails via smtp. Edit the master.cf file and change this line:
smtp inet n - n - - smtpdto this:
smtp inet n - n - - smtpd
-o content_filter=spamassassinand then at the end of the file add this:
#SpamAssassin
spamassassin unix - n n - - pipe
user=nobody argv=/usr/pkg/bin/spamc -f -e
/usr/pkg/sbin/sendmail -oi -f ${sender} ${recipient}and restart postfix. External emails sent in to your box will now include details such as these in the header:
X-Spam-Flag: YES
X-Spam-Checker-Version: SpamAssassin 3.0.2 (2004-11-16) on www.foo.comLast edited by WIntellect (2005-07-01 23:57:13)
-- Copyright BSDnexus