Postfix Tutorial

Postfix, Courier/POP, SASL & Spamassassin - with MySQL admin on Ubuntu LTS 12.04 Precise Pangolin



1. DNS. Create an MX record in the primary zone file for the domains, with an A record pointing to the IP address of the mail server. You can proceed with the following installation and configuration, but your server will not test for your domain until your name server(s) are announcing DNS for it. Make sure you can see the A record IP address before testing the Postfix configuration:

dig mail.example-domain.com @name-server-for-example-domain.com

2. Install the following packages:

sudo apt-get install apache2 php5 mysql-server php5-mysql phpmyadmin postfix mailutils courier-pop courier-imap vim courier-authlib-mysql libsasl2-2 libsasl2-modules libsasl2-modules-sql postfix-mysql sasl2-bin libpam-mysql

Note: you may optionally wish to add screen to the above list - vim is included to update vi (need to sudo apt-get install vim-nox on Ubuntu 8.10)

3. Configure postfix - enter the following at the command line:

sudo postconf -e "home_mailbox = Maildir/"
sudo postconf -e "mailbox_command = "
sudo postconf -e "mydestination = localhost.localdomain, localhost"
sudo postconf -e "mynetworks = 127.0.0.0/8, <CIDR Address Block e.g. 209.152.115.0/24>"
sudo postconf -e "inet_interfaces = all"
sudo postconf -e "inet_protocols = all"

4. Restart Apache2

/etc/init.d/apache2 reload

5. Configure phpMyAdmin - add this line to the end of /etc/apache2/apache2.conf:

Include /etc/phpmyadmin/apache.conf

… then access phpMyAdmin at :

http://mailserver-domain-name/phpmyadmin/

6. Create the MySQL database 'mail':

mysql -u root -p
CREATE DATABASE `mail` DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;
USE `mail`;

7. Create the following tables on the MySQL database 'mail':

virtual_aliases
virtual_mailbox_domains
virtual_users

… using the following SQL (insert directly into phpMyAdmin):

-- ----------------------------------------------------------------
-- Table structure for table `virtual_aliases`
-- ----------------------------------------------------------------

CREATE TABLE IF NOT EXISTS `virtual_aliases` (
  `id` int(10) unsigned NOT NULL auto_increment,
  `alias` varchar(255) collate utf8_unicode_ci default NULL,
  `virtual_user_email` text collate utf8_unicode_ci,
  PRIMARY KEY (`id`),
  FULLTEXT KEY `aliases` (`alias`,`virtual_user_email`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci COMMENT='Postfix virtual recipient aliases' AUTO_INCREMENT=1 ;

-- ----------------------------------------------------------------
-- Table structure for table `virtual_mailbox_domains`
-- ----------------------------------------------------------------

CREATE TABLE IF NOT EXISTS `virtual_mailbox_domains` (
  `id` int(10) unsigned NOT NULL auto_increment,
  `domain` varchar(255) collate utf8_unicode_ci default NULL,
  PRIMARY KEY (`id`),
  FULLTEXT KEY `domains` (`domain`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci COMMENT='Postfix virtual domains' AUTO_INCREMENT=1 ;

-- ----------------------------------------------------------------
-- Table structure for table `virtual_users`
-- ----------------------------------------------------------------

CREATE TABLE IF NOT EXISTS `virtual_users` (
  `id` int(11) unsigned NOT NULL auto_increment,
  `username` varchar(255) collate utf8_unicode_ci NOT NULL default '0',
  `userrealm` varchar(255) collate utf8_unicode_ci NOT NULL,
  `userpassword` varchar(255) collate utf8_unicode_ci NOT NULL,
  `auth` tinyint(1) default '1',
  `active` tinyint(1) default '1',
  `email` varchar(255) collate utf8_unicode_ci NOT NULL default '',
  `virtual_uid` smallint(5) default '1007',
  `virtual_gid` smallint(5) default '1007',
  `virtual_mailbox` varchar(255) collate utf8_unicode_ci default NULL,
  PRIMARY KEY (`id`),
  FULLTEXT KEY `recipient` (`email`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci COMMENT='SMTP AUTH and virtual mailbox users' AUTO_INCREMENT=1 ;

8. Create MySQL User for Postfix. Run the SQL Query below (either from phpMyAdmin or Terminal), replacing with your own password (note there is an excellent password generator in phpMyAdmin under Privileges then "Add a new User"):

CREATE USER 'postfix'@'localhost' IDENTIFIED BY '<password>';
GRANT USAGE ON * . * TO 'postfix'@'localhost' IDENTIFIED BY '<password>'
WITH MAX_QUERIES_PER_HOUR 0 MAX_CONNECTIONS_PER_HOUR 0 MAX_UPDATES_PER_HOUR
0 MAX_USER_CONNECTIONS 0 ;
GRANT SELECT, INSERT, UPDATE ,DELETE, CREATE, DROP, RELOAD, SHUTDOWN,
PROCESS, FILE, REFERENCES, INDEX, ALTER ON * . * TO 'postfix'@'localhost'
WITH GRANT OPTION MAX_QUERIES_PER_HOUR 0 MAX_CONNECTIONS_PER_HOUR 0
MAX_UPDATES_PER_HOUR 0 MAX_USER_CONNECTIONS 0 ;
FLUSH PRIVILEGES;

9. Grant user privileges. The postfix user should not be able to alter or create tables, but should be restricted to read-only (SELECT) access. Run the SQL Query below (either from phpMyAdmin or Terminal), replacing with your own password (note there is an excellent password generator in phpMyAdmin under Privileges then "Add a new User"):

GRANT USAGE ON *.* TO 'postfix'@'localhost' IDENTIFIED BY PASSWORD '<password>';
GRANT SELECT ON mail.virtual_aliases TO 'postfix'@'localhost';
GRANT SELECT ON mail.virtual_users TO 'postfix'@'localhost';
GRANT SELECT ON mail.virtual_mailbox_domains TO 'postfix'@'localhost';
FLUSH PRIVILEGES;

10. Postfix Configuration Files. Create the /etc/postfix/sql directory, then create the following 6 files inside the sql directory, changing <password> in each file to the actual MySQL password for the user postfix. Alternatively, you can download all 6 files here. Finally, apply appropriate permissions to the directory.

a) Create the /etc/postfix/sql directory:

mkdir /etc/postfix/sql

b) Create the file sender_check.cf inside the sql directory, with the contents:

user = postfix
password = <password>
dbname = mail
table = virtual_users
hosts = 127.0.0.1
query = SELECT email FROM virtual_users WHERE email ='%s' and active=1

c) Create the file virtual_alias_maps.cf inside the sql directory, with the contents:

user = postfix
password = <password>
dbname = mail
table = virtual_aliases
select_field = virtual_user_email
where_field = alias
hosts = 127.0.0.1

d) Create the file virtual_gid_maps.cf inside the sql directory, with the contents:

user = postfix
password = <password>
dbname = mail
table = virtual_users
select_field = virtual_gid
where_field = email
hosts = 127.0.0.1

e) Create the file virtual_mailbox_domains.cf inside the sql directory, with the contents:

user = postfix
password = <password>
dbname = mail
table = virtual_mailbox_domains
select_field = domain
where_field = domain
hosts = 127.0.0.1

f) Create the file virtual_mailbox_recipients.cf inside the sql directory, with the contents:

user = postfix
password = <password>
dbname = mail
table = virtual_users
select_field = virtual_mailbox
where_field = email
additional_conditions = and active = '1'
hosts = 127.0.0.1

g) Create the file virtual_uid_maps.cf inside the sql directory, with the contents:

user = postfix
password = <password>
dbname = mail
table = virtual_users
select_field = virtual_uid
where_field = email
hosts = 127.0.0.1

h) Apply appropriate persmissions of the sql directory:

chown postfix /etc/postfix/sql
chgrp root /etc/postfix/sql
chmod 500 /etc/postfix/sql

11. SASL Configuration. Create the /etc/postfix/sasl directory, and apply appropriate permissions to it:

a) Create the /etc/postfix/sasl directory if it does not already exist (otherwise change directory to it):

mkdir /etc/postfix/sasl
( cd /etc/postfix/sasl )

b) Create the smtpd.conf file inside the sasl directory, with the following contents:

log_level: 1
pwcheck_method: saslauthd
mech_list: plain login
allow_plaintext: true

#auxilary plugin properties
#auxprop_plugin: sql
#sql_engine: mysql
#sql_hostnames: 127.0.0.1
#sql_user: postfix
#sql_passwd: <password>
#sql_database: mail
#sql_select: select userpassword as %p from virtual_users where username = '%u' AND active = 1

c) Apply appropriate permissions:

adduser postfix sasl
chmod -R g+wrx /etc/postfix/sasl/

12. Configure authdaemonrc. Edit /etc/courier/authdaemonrc - and change: authmodulelist="" to: authmodulelist="authmysql"

13. Configure authmysqlrc. Edit the /etc/courier/authmysqlrc and change to the following (Change the <password> in the file to the actual MySQL password for the user postfix):

MYSQL_SERVER 127.0.0.1
MYSQL_USERNAME postfix
MYSQL_PASSWORD <password>
MYSQL_DATABASE mail
MYSQL_USER_TABLE virtual_users
MYSQL_LOGIN_FIELD email
#MYSQL_CRYPT_PWFIELD crypt
MYSQL_CLEAR_PWFIELD userpassword
MYSQL_MAILDIR_FIELD virtual_mailbox
MYSQL_HOME_FIELD '/var/spool/virtual_mailboxes'
MYSQL_UID_FIELD '1007'
MYSQL_GID_FIELD '1007'

Comment out MYSQL_CRYPT_PWFIELD and MYSQL_NAME_FIELD options

… there must be NO SPACES / TABS / ANYTHING at beginning or end of line.
This is how courier connects to mysql - it should effectively replicate the information in the /etc/postfix/sql/virtual_mailbox_recipients.cf file - mysql username, table and field names for mysql, etc.

14. Restart the daemons for changes to take effect:

/etc/init.d/courier-authdaemon restart
/etc/init.d/courier-pop restart
/etc/init.d/postfix restart

15. Enter MySQL Data. Enter you user data through phpMyAdmin (or alternative GUI) in the following format:

INSERT INTO `virtual_aliases` (`id`, `alias`, `virtual_user_email`) VALUES
('', 'postmaster@example-domain.com', 'forward-to-this-user@example-domain.com'),
('', 'abuse@example-domain.com', 'forward-to-this-user@example-domain.com');

INSERT INTO `virtual_mailbox_domains` (`id`, `domain`) VALUES
('', 'example-domain.com'),
('', 'another-domain.com');

INSERT INTO `virtual_users` (`id`, `username`, `userrealm`, `userpassword`, `auth`, `active`, `email`, `virtual_uid`, `virtual_gid`, `virtual_mailbox`) VALUES
('', 'username-1', 'mail.example-domain.com', 'password', 1, 1, 'username-1@example-domain.com', 1007, 1007, 'example-domain.com/username-1/'),
('', 'username-2', 'mail.another-domain.com', 'password', 1, 1, 'username-2@another-domain.com', 1007, 1007, 'anotherdomain.com/username-2/');

16. Configure /etc/postfix/main.cf :

# MySQL Setup for Virtual Mailbox Domains as per postfix-book.com

virtual_mailbox_base = /var/spool/virtual_mailboxes
virtual_mailbox_domains = mysql:/etc/postfix/sql/virtual_mailbox_domains.cf
virtual_uid_maps = mysql:/etc/postfix/sql/virtual_uid_maps.cf
virtual_gid_maps = mysql:/etc/postfix/sql/virtual_gid_maps.cf
virtual_mailbox_maps = mysql:/etc/postfix/sql/virtual_mailbox_recipients.cf
virtual_alias_maps = mysql:/etc/postfix/sql/virtual_alias_maps.cf

# SASL authentication
smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination

smtpd_sasl_auth_enable = yes
broken_sasl_auth_clients = yes
smtpd_sasl_authenticated_header = yes
smtpd_sasl_security_options = noanonymous
smtpd_sasl_local_domain =

17. Create the file: /etc/pam.d/smtp … with the contents:

auth required pam_mysql.so user=postfix passwd=<PASSWORD> host=127.0.0.1 db=mail table=virtual_users usercolumn=email passwdcolumn=userpassword crypt=0 verbose=1
account sufficient pam_mysql.so user=postfix passwd=<PASSWORD> host=127.0.0.1 db=mail table=virtual_users usercolumn=email passwdcolumn=userpassword crypt=0 verbose=1

18. Create the file : /etc/default/saslauthd ... with the contents:

START=yes
MECHANISMS="pam"
MECH_OPTIONS=""
THREADS=5
OPTIONS="-c -m /var/spool/postfix/var/run/saslauthd -r"

19. Create the directories :

mkdir -p /var/spool/postfix/var/run/saslauthd/
mkdir /var/spool/virtual_mailboxes

20. Add /etc/passwd to vuser:x:1007:1008::/home/vuser:/bin/sh

groupadd vuser -g 1008
useradd -m vuser -u 1007 -g 1008
chown -R vuser: /var/spool/virtual_mailboxes/

21. DomainKeys Identified Mail (DKIM)

Install OpenDKIM (which replaced the dkim-filter package in Ubuntu as of 2011-12-13):

sudo apt-get install opendkim

Configure opendkim using instructions from http://opendkim.org/opendkim-README

22. Create restartmail

vi ~/.bashrc
alias restartmail='/etc/init.d/courier-authdaemon restart; /etc/init.d/courier-pop restart; /etc/init.d/postfix restart; /etc/init.d/saslauthd restart'

Then restart the various daemons using restartmail as a handy alias to restart courier, postfix, and saslauthd

23. Test. Insert your domains, users and aliases into the MySQL tables. You will need to send a message to each user account, before the account will work, as this is what creates the /var/spool/ directory for that user. Also, make sure on your email client that you enter 'username@example-domain.com' as the username and not just 'username'.

If you have any problems, try increasing logging to a higher, more verbose level, and then check the error logs.

Add -v to 'smtpd' in /etc/postfix/master.cf for verbose logging.

/etc/postfix/sasl/smtpd.conf log_level: 5

verbose courier debugging: /etc/courier/authdaemonrc DEBUG_LOGIN=2

Running the saslauthd as a foreground process attached to the terminal (so you get all login attempts displayed directly to terminal): saslauthd -d -a pam -c -m /var/spool/postfix/var/run/saslauthd -r
To test an account: testsaslauthd -s smtp -f /var/spool/postfix/var/run/saslauthd/mux -u <USERNAME> -p <PASSWORD>


24. Spamassassin. Once you have Postfix up and running, as an option you can filter spam using this configuration of Spamassassin.

a) Install the packages:

sudo apt-get install spamassassin spamc

b) Create a specific user and group for spamassassin:

groupadd -g 5001 spamd
useradd -u 5001 -g spamd -s /sbin/nologin -d /var/lib/spamassassin spamd
mkdir /var/lib/spamassassin
chown spamd:spamd /var/lib/spamassassin

c) Configure /etc/default/spamassassin

ENABLED=1
SAHOME="/var/lib/spamassassin/"
OPTIONS="--create-prefs --max-children 5 --username spamd --helper-home-dir ${SAHOME} -s ${SAHOME}spamd.log"
PIDFILE="${SAHOME}spamd.pid"

d) Configure /etc/spamassassin/local.cf

rewrite_header Subject [***** SPAM _SCORE_ *****]
required_score 2.0
#to be able to use _SCORE_ we need report_safe set to 0
#If this option is set to 0, incoming spam is only modified by adding some "X-Spam-" headers and no changes will be made to the body.
report_safe 0

# Enable the Bayes system
use_bayes 1
use_bayes_rules 1
# Enable Bayes auto-learning
bayes_auto_learn 1

# Enable or disable network checks
skip_rbl_checks 0
use_razor2 0
use_dcc 0
use_pyzor 0

e) Start spamassassin with /etc/init.d/spamassassin start

f) Configure Postfix /etc/postfix/master.cf

Change the line:
smtp inet n - - - - smtpd
… to …
smtp inet n - - - - smtpd
-o content_filter=spamassassin

g) Add the following at the end of /etc/init.d/spamassassin start

spamassassin unix - n n - - pipe
user=spamd argv=/usr/bin/spamc -f -e
/usr/sbin/sendmail -oi -f ${sender} ${recipient}

h) Reload Postfix with restartmail


References

https://help.ubuntu.com/community/PostfixBasicSetupHowto
http://www.postfix.org/STANDARD_CONFIGURATION_README.html#backup
http://www.debuntu.org/postfix-and-pamassassin-how-to-filter-spam



Powered by Embode

Leave a Comment