You are not logged in.
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.conf
Now, 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-depends
this 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 start
You 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-configuration
Configure postfix to start on boot
# echo "postfix=YES" >> /etc/rc.conf # echo "sendmail=NO" >> /etc/rc.conf
The 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/sendmail
If 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=100
in 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 - - virtual
Now create the following files:
transport.cf
user=uname password=passwd dbname=maildb table=transport select_field=transport where_field=domain hosts=localhost
mysql_virt.cf
user=uname password=passwd dbname=maildb table=users select_field=maildir where_field=address hosts=localhost
uids.cf
user=uname password=passwd dbname=maildb table=users select_field=uid where_field=address hosts=localhost
gids.cf
user=uname password=passwd dbname=maildb table=users select_field=gid where_field=address hosts=localhost
virtual.cf
user=uname password=passwd dbname=maildb table=virtual select_field=goto where_field=address hosts=localhost
Configure 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=1
IMPORTANT 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 johndoe
Starting 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-depends
First 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. Example
Now 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/clamd
and 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_mappings
In 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 ClamSMTP
OPTIONAL 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-depends
You 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.0
Now 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 - - smtpd
to 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.com
Last edited by WIntellect (2005-07-02 00:57:13)
Offline
Does it make sense having a printable version?
Offline
just because i had so many problems with this i'll just post some helping hands .......
Linux users:
You may see a few different errors if you have this problem. Most complain about can't access transport.cf. If you read the logs carefully when you restart postfix, there's actually a problem with postfix talking to mysql.sock because postfix is chrooted, Fix for this is putting the following in /etc/init.d/postfix startup script
if [ -e /var/spool/postfix/var/run/mysqld/mysqld.sock ]; then
rm /var/spool/postfix/var/run/mysqld/mysqld.sock
fi
mkdir -p /var/spool/postfix/var/run/mysqld
chown mysql /var/spool/postfix/var/run/mysqld
Offline
umm another problem i just ran into ... ID10T but i'm sure someone else is going to do it
when adding the maildir to the database, make sure you have that last '/' ..... else you'll get errors such as
/var/spool/postfix/virtual/domain.com/user is not a directory or something like that
Offline
i added the last '/' at the maildir, but i can't login to courier, because: "sending of password did not succeed. mail server .. responded: maildir invalid (no 'cur' directory)". in mysql db maildir = southpark.szinyei.hu/kocka/ and home= /var/spool/postfix/virtual. what can be the matter?
..sorry for my n00b
Offline
this is a pretty tight guide. i couldn't find one this good when i was starting up a hosting company a few years ago.
Offline
lucas wrote:
this is a pretty tight guide. i couldn't find one this good when i was starting up a hosting company a few years ago.
Thank you kindly ![]()
Offline
would you like to write a manual pls, how can i set up an sasl authentication from the mysql server, that the users could send message via the postfix server?
Offline
kocka wrote:
would you like to write a manual pls, how can i set up an sasl authentication from the mysql server, that the users could send message via the postfix server?
I'm not quite sure I understand you : "sasl authentication from the mysql server"
Are you saying that the people who send email need sasl authentication? Is that what you mean?
Offline
WIntellect wrote:
Are you saying that the people who send email need sasl authentication? Is that what you mean?
you're right. sorry for my english. i don't want to get an openrelay server, but i would like to use my postfix for send mails from mail clients on other machine. i hope this is clear ![]()
Offline
outgoing smtp authentication, right?
Offline
kocka wrote:
WIntellect wrote:
Are you saying that the people who send email need sasl authentication? Is that what you mean?
you're right. sorry for my english. i don't want to get an openrelay server, but i would like to use my postfix for send mails from mail clients on other machine. i hope this is clear
ok, so you want other machines using Outlook/Kmail/Sylpheed/mutt/etc. to use authentication to send their mail out to the world, right?
If you clarify that for me, then I can look into it
I think I recently did this for work ![]()
Offline
yes, this is what i want to do ![]()
Offline
classy
Offline
WIntellect wrote:
The 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:
Code:
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'
This is where I’m stuck. I'm using FreeBSD 6.1 and I can't find a "/etc/rc.conf.d/postfix” umm... would it be possible for someone to let me know where this file is located... I'm new to the BSDs and have never done anything with out a GUI except for DOS so I’m a little out of my league.
I would appreciate any help I can get.
Thank you in advance.
-Cody
Offline
FreeBSD installs this into /usr/local/etc/postfix for the *.cf scripts and such. The postfix.sh script to start postfix is stored in /usr/ocal/etc/rc.d
So that start and stop commands would be:
/usr/local/etc/rc.d/postifx.sh start /usr/local/etc/rc.d/postfix.sh stop
Offline
Thank You RoddieRod. I looked at the files and they were all pointing to the correct place. I guess with FreeBSD 6.1 and ports they set it up so they all know where each other are and play together nice.
Yay!
Offline
Hello,
i've follow this doc to build on freebsd 6.1 but i've always this message in /var/log/maillog when a user try a check mail on the server.
Sep 27 17:49:02 calimero pop3d: chdir twice.com/john/: No such file or directory
i've followed this:
# 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 johndoe
but nothing .
Many thx for your help.
Offline
What wave you got in your DB for the "john" entry?
Offline
Found it !
in mysql db it was / instead of the full path.
Thx !!
Offline
![]()
Offline
Hi,
Very good Howto WInttelect! I got it setup and working in minutes! However, I came across another problem which is bugging me for 2 days now...
I tried to integrate maildrop in the process, which worked out fine partially, except for delivery to aliases. I use maildrop to move spam to a users ".Spam" folder in the Maildir, like I used to have in Qmail (which I was using before). Maildrop now delivers mail correctly for the virtual users themselves, but for the aliases of these virtual users I get the error below:
May 16 19:47:25 chernobyl postfix/pipe[3928]: 730D619EDF8: to=<alias@hostname.com>, relay=maildrop, delay=1.8, delays=1.7/0/0/0.02, dsn=5.1.1, status=bounced (user unknown. Command output: Invalid user specified. )
alias@hostname.com is an alias which should redirect to vincent@hostname.com. I have this correctly setup in the "virtual" table. I have also setup the domain transport to "maildrop:" for hostname.com in the domain table. Thats why I use "virtual_transport = $transport_maps".
I will post my configuration below.
MAIN.CF
smtpd_helo_required = yes maildrop_destination_recipient_limit=1 transport_maps=mysql:/usr/pkg/etc/postfix/transport.cf mydestination = $mydomain, $myhostname, $transport_maps virtual_transport = $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=/data/mail/virtual virtual_maps=mysql:/usr/pkg/etc/postfix/virtual.cf virtual_alias_maps = $virtual_maps alias_maps = $virtual_maps # The following two lines are optional, and hopefully self explanitory virtual_mailbox_limit=2048000000 virtual_minimum_uid=100 ### ClamAV ### content_filter = scan:localhost:10025 receive_override_options = no_address_mappings ### SASL ### smtpd_sasl_auth_enable = yes smtpd_sasl2_auth_enable = yes smtpd_sasl_security_options = noanonymous smtpd_sasl_local_domain = $myhostname # smtp_sasl_password_maps = mysql:/usr/local/etc/postfix/mysql_virtual_pass_maps.cf broken_sasl_auth_clients = yes smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_non_fqdn_hostname, reject_non_fqdn_sender, reject_non_fqdn_recipient, reject_unauth_destination, reject_unauth_pipelining, reject_invalid_hostname, reject_rbl_client opm.blitzed.org, reject_rbl_client list.dsbl.org, reject_rbl_client bl.spamcop.net, reject_rbl_client sbl-xbl.spamhaus.org # check_recipient_access mysql:/usr/pkg/etc/postfix/mysql-recipient.cf # The above line must be fitted in one line DONT FORGET
MASTER.CF
maildrop unix - n n - - pipe
flags=DRhu user=mailusr argv=/usr/pkg/bin/maildrop -d ${recipient}I am using maildrop from /usr/pkgsrc/mail/maildrop on NetBSD 3.1. If more information is needed, please let me know.
Does anyone have a clue what needs to be done here?
Thanks in advance,
CentralX
Last edited by CentralX (2007-05-17 23:15:17)
Offline
I'm afraid I don't know maildrop, sorry ![]()
Offline