Postfix w/o Maildrop

From Wiki
Jump to: navigation, search

Contents

Install packages

The setup needs a whole load of packages to work. Either install separately, or do in a single command line.

Postfix

apt-get install postfix postfix-mysql postfix-doc

Configuration options:

General type of configuration? <-- Internet site
System mail name: <-- hammond-vm.tolien.co.uk

OpenSSL

apt-get install openssl

Courier

apt-get install courier-authlib-mysql courier-pop courier-pop-ssl courier-imap courier-imap-ssl

Configuration options:

create directories for web-based admin <-- no
create SSL cert <-- OK

The script automatically runs mkimapdcert, which by defaults creates a certificate with country = US, state = NY, location = New York etc... The settings are stored in /etc/courier/imapd.cnf.

The same applies to mkpop3dcert, which uses /etc/courier/pop3d.cnf.

SASL

Original instructions used libsasl2, which is apparently deprecated and replaced by libsasl2-2.

apt-get install libsasl2-2 libsasl2-modules libsasl2-modules-sql sasl2-bin libpam-mysql

General Setup

vmail user

There's an entry for it in master.cf, but it seems the vmail user doesn't actually get created.

useradd vmail -d /var/vmail -m -s /bin/false

Which will create the root folder under which all the mail will be stored as well as setting its ownership appropriately.

MySQL tables

User to access the Postfix tables:

CREATE USER 'postfix'@'localhost' IDENTIFIED BY 'password';
CREATE DATABASE 'postfix';
GRANT SELECT , INSERT , UPDATE , DELETE ON `postfix` . * TO 'postfix'@'localhost';
FLUSH PRIVILEGES;

MySQL queries to create required tables for Postfix:

USE postfix;

 CREATE TABLE postfix_alias (
  id int(11) unsigned NOT NULL auto_increment,
  alias varchar(128) NOT NULL default '',
  destination varchar(128) NOT NULL default '',
  PRIMARY KEY (id)
  UNIQUE KEY alias (alias)
 ) TYPE=MyISAM;
 
 CREATE TABLE postfix_relocated (
  id int(11) unsigned NOT NULL auto_increment,
  email varchar(128) NOT NULL default '',
  destination varchar(128) NOT NULL default '',
  PRIMARY KEY (id)
 ) TYPE=MyISAM;
 
 CREATE TABLE postfix_transport (
  id int(11) unsigned NOT NULL auto_increment,
  domain varchar(128) NOT NULL default '',
  destination varchar(128) NOT NULL default '',
  PRIMARY KEY (id),
  UNIQUE KEY domain (domain)
 ) TYPE=MyISAM;
 
 CREATE TABLE postfix_users (
  id int(11) unsigned NOT NULL auto_increment,
  email varchar(128) NOT NULL default '',
  clear varchar(128) NOT NULL default '',
  crypt varchar(128) NOT NULL default '',
  name tinytext NOT NULL,
  uid int(11) unsigned NOT NULL default '1001',
  gid int(11) unsigned NOT NULL default '1001',
  homedir tinytext NOT NULL,
  maildir tinytext NOT NULL,
  quota tinytext NOT NULL,
  access enum('Y','N') NOT NULL default 'Y',
  postfix enum('Y','N') NOT NULL default 'Y',
  PRIMARY KEY (id),
  UNIQUE KEY email (email)
 ) TYPE=MyISAM;
 
 CREATE TABLE postfix_virtual (
  id int(11) unsigned NOT NULL auto_increment,
  email varchar(128) NOT NULL default '',
  destination varchar(128) NOT NULL default '',
  PRIMARY KEY (id)
 ) TYPE=MyISAM;
 
 CREATE TABLE postfix_access (
  id int(10) unsigned NOT NULL auto_increment,
  source varchar(128) NOT NULL default '',
  access varchar(128) NOT NULL default '',
  type enum('recipient','sender','client') NOT NULL default 'recipient',
  PRIMARY KEY (id)
 ) TYPE=MyISAM;

The purposes of the tables used here is explained in postfix SQL tables

Postfix

/etc/postfix/main.cf:

mydestination = hammond-vm.tolien.co.uk, localhost.tolien.co.uk, , localhost, $transport_maps

local_recipient_maps = $virtual_alias_maps $virtual_mailbox_maps

transport_maps = mysql:/etc/postfix/mysql-transport.cf

virtual_alias_maps = mysql:/etc/postfix/mysql-aliases.cf
virtual_mailbox_base = /var/vmail
virtual_mailbox_maps = mysql:/etc/postfix/mysql-virtual-maps.cf
virtual_transport = virtual
virtual_uid_maps = static:1001
virtual_gid_maps = static:1001
virtual_minimum_uid = 1001

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

smtpd_sasl_auth_enable = yes
smtpd_sasl_local_domain = $myhostname
smtpd_sasl_security_options = noanonymous
smtpd_use_tls = yes
smtpd_tls_cert_file = /etc/postfix/smtpd.cert
smtpd_tls_key_file = /etc/postfix/smtpd.key

virtual_maps is deprecated in favour of separate virtual_alias_domains and virtual_alias_maps controls.

Mysql files

Create the following:

mysql-aliases.cf

# mysql-aliases.cf
user = postfix
password = password
dbname = postfix
table = postfix_alias
select_field = destination
where_field = alias
hosts = 127.0.0.1

mysql-relocated.cf

# mysql-relocated.cf
user = postfix
password = password
dbname = postfix
table = postfix_relocated
select_field = destination
where_field = email
hosts = 127.0.0.1

mysql-transport.cf


# mysql-transport.cf
user = postfix
password = password
dbname = postfix
table = postfix_transport
select_field = destination
where_field = domain
hosts = 127.0.0.1

mysql-virtual.cf

# mysql-virtual.cf
user = postfix
password = password
dbname = postfix
table = postfix_virtual
select_field = destination
where_field = email
hosts = 127.0.0.1

mysql-recipient.cf

# mysql-recipient.cf
user = postfix
password = password
dbname = postfix
table = postfix_access
select_field = access
where_field = source
additional_conditions = and type = 'recipient'
hosts = 127.0.0.1

mysql-sender.cf

# mysql-sender.cf
user = postfix
password = password
dbname = postfix
table = postfix_access
select_field = access
where_field = source
additional_conditions = and type = 'sender'
hosts = 127.0.0.1

mysql-client.cf

# mysql-client.cf
user = postfix
password = password
dbname = postfix
table = postfix_access
select_field = access
where_field = source
additional_conditions = and type = 'client'
hosts = 127.0.0.1

mysql-virtual-maps.cf

# mysql-virtual-maps.cf
user = postfix
password = password
dbname = postfix
table = postfix_users
select_field = maildir
where_field = email
additional_conditions = and postfix = 'y'
hosts = 127.0.0.1

mysql-virtual-uid.cf

# mysql-virtual-uid.cf
user = postfix
password = password
dbname = postfix
table = postfix_users
select_field = uid
where_field = email
additional_conditions = and postfix = 'y'
hosts = 127.0.0.1

mysql-virtual-gid.cf

# mysql-virtual-gid.cf
user = postfix
password = password
dbname = postfix
table = postfix_users
select_field = gid
where_field = email
additional_conditions = and postfix = 'y'
hosts = 127.0.0.1

SSL Certificate

From /etc/postfix:

sudo openssl req -new -outform PEM -out smtpd.cert -newkey rsa:2048 -nodes -keyout smtpd.key -keyform PEM -days 2000 -x509
Generating a 2048 bit RSA private key
..........................+++
.............................+++
writing new private key to 'smtpd.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]: <-- GB
State or Province Name (full name) [Some-State]: <-- Timbuktu
Locality Name (eg, city) []:
Organization Name (eg, company) [Internet Widgits Pty Ltd]: <-- Tolien
Organizational Unit Name (eg, section) []:
Common Name (eg, YOUR name) []: <-- hammond-vm.tolien.co.uk
Email Address []:

Courier-IMAP

Warning: Courier is anal about spaces preceding configuration options. The option should have no spaces before it in the same line.

Edit /etc/courier/authdaemonrc, changing

authmodulelist="authpam"

to

authmodulelist="authmysql authpam"

Then edit /etc/courier/authmysqlrc:

MYSQL_SERVER            127.0.0.1
MYSQL_USERNAME          postfix
MYSQL_PASSWORD          password
MYSQL_PORT              0
MYSQL_OPT               0
MYSQL_DATABASE          postfix
MYSQL_USER_TABLE        postfix_users
MYSQL_CRYPT_PWFIELD     crypt
MYSQL_CLEAR_PWFIELD     clear
MYSQL_LOGIN_FIELD       email
MYSQL_UID_FIELD         uid
MYSQL_GID_FIELD         gid
MYSQL_HOME_FIELD        homedir
MYSQL_MAILDIR_FIELD     maildir
MYSQL_WHERE_CLAUSE      access='y'

/etc/courier/imapd should have

IMAPDSTART=YES

and /etc/courier/imapd-ssl should have

IMAPDSSLSTART=YES

SASL

The SASL auth daemon isn't needed, so /etc/default/saslauthd should contain

START=no

Create /etc/postfix/sasl/smtpd.conf:

pwcheck_method: authdaemond
authdaemond_path: /var/run/courier/authdaemon/socket
log_level: 3
mech_list: PLAIN LOGIN

To make the courier authdaemon usable from within Postfix's chroot, some symlinking is needed:

/etc/init.d/courier-authdaemon stop
rm -rf /var/run/courier/authdaemon/ /var/spool/postfix/var/run/courier/authdaemon/
mkdir -p /var/spool/postfix/var/run/courier/authdaemon/
ln -s /var/spool/postfix/var/run/courier/authdaemon/ /var/run/courier/authdaemon
/etc/init.d/courier-authdaemon start
postfix reload

Create a user

INSERT INTO postfix_transport (domain,destination) VALUES ("domain.tld", "virtual:");
INSERT INTO postfix_users (email, clear, homedir, maildir) VALUES ("user@domain.tld", "password", "/var/vmail", "domain.tld/user/Maildir/");

The maildir record in postfix_users must end with a forward slash to make Postfix work with a Maildir.

Testing

SMTP

Valid user:

telnet localhost 25
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
220 hammond-vm.tolien.co.uk ESMTP Postfix (Debian/GNU)
EHLO localhost
250-hammond-vm.tolien.co.uk
250-PIPELINING
250-SIZE 10240000
250-VRFY
250-ETRN
250-STARTTLS
250-AUTH PLAIN CRAM-MD5 LOGIN
250-ENHANCEDSTATUSCODES
250-8BITMIME
250 DSN
MAIL FROM: test@localhost
250 2.1.0 Ok
rcpt to: user@domain.tld
250 2.1.5 Ok
DATA
354 End data with <CR><LF>.<CR><LF>
This is a test
.
250 2.0.0 Ok: queued as 720554B082
quit
221 2.0.0 Bye


Invalid user:

telnet localhost 25
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
220 hammond-vm.tolien.co.uk ESMTP Postfix (Debian/GNU)
EHLO localhost
250-hammond-vm.tolien.co.uk
250-PIPELINING
250-SIZE 10240000
250-VRFY
250-ETRN
250-STARTTLS
250-AUTH PLAIN CRAM-MD5 LOGIN
250-ENHANCEDSTATUSCODES
250-8BITMIME
250 DSN
MAIL FROM: root@localhost
250 2.1.0 Ok
RCPT TO: nonexistanttestuser@tolien.co.uk
550 5.1.1 <nonexistanttestuser@tolien.co.uk>: Recipient address rejected: User unknown in local recipient table
quit
221 2.0.0 Bye

IMAP

telnet localhost 143
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
* OK [CAPABILITY IMAP4rev1 UIDPLUS CHILDREN NAMESPACE THREAD=ORDEREDSUBJECT THREAD=REFERENCES SORT QUOTA IDLE ACL ACL2=UNION STARTTLS] Courier-IMAP ready. Copyright 1998-2005 Double Precision, Inc.  See COPYING for distribution information.
a login user@domain.tld password
a OK LOGIN Ok.
a examine inbox
* FLAGS (\Draft \Answered \Flagged \Deleted \Seen \Recent)
* OK [PERMANENTFLAGS ()] No permanent flags permitted
* 1 EXISTS
* 1 RECENT
* OK [UIDVALIDITY 1200873832] Ok
* OK [MYRIGHTS "acdilrsw"] ACL
a OK [READ-ONLY] Ok
a logout
* BYE Courier-IMAP server shutting down
a OK LOGOUT completed

Troubleshooting

http://www.courier-mta.org/authlib/README.authdebug.html has commands required to manually perform a login with IMAP/POP3, with and without SSL.

Personal tools