MeTA1 Setup

Instructions to Setup MeTA1 with Cyrus IMAP

A demonstration on how to setup the MeTA1 MTA in conjunction with Cyrus IMAP

Overview

The contents of this tutorial are targeted towards someone who is already familiar with the functionality of an MTA and Cyrus IMAP. These are high level notes. Hopefully it will be complete enough information to guide someone else in the adventure of setting up a mail server environment using Cyrus IMAP and MeTA1.

This page will explain how to setup Claus Aßmann's MeTA1 MTA. The final MTA configuration will utilize STARTTLS certificates and access.db to control relaying. The local delivery agent will point to Cyrus IMAP's lmtp daemon

Getting Started

As of this writing MeTA1 was in it's second PreAlpha release. You can download a copy from www.meta1.org. As always, you should download the .sig file to verify the validity of the image.

Build and Setup MeTA1

Building MeTA1 is pretty straight forward. The package includes its own Berkeley DB so in case you don't have one installed the build process will handle it. Run configure -help to view all the configuration options. By default TLS and SASL are turned on so we don't need to explicitly include them with the "configure" arguments. You should not build MeTA1 as the root user. The following will run "check". "check" verifies the build integrity by running a suite of unit tests. The tests take approximately 80 minutes. You should read the ./doc/README.txt for more specific information.

./configure && make && make check

Before you attempt to install MeTA1 you need to add the appropriate users to your system. MeTA1 needs several users to provide separation of privileges and to enhance security. Currently there are four required accounts (the numbers for uid and gid are examples only); the last one listed below (meta1) is not really required:

meta1s:*:260:260:meta1 SMTPS:/nonexistent:/sbin/nologin
meta1q:*:261:261:meta1 QMGR:/nonexistent:/sbin/nologin
meta1c:*:262:262:meta1 SMTPC:/nonexistent:/sbin/nologin
meta1m:*:263:263:meta1 misc:/nonexistent:/sbin/nologin
meta1:*:264:264:meta1 other:/nonexistent:/sbin/nologin

with the corresponding groups:

meta1s:*:260:
meta1q:*:261:
meta1c:*:262:meta1s
meta1m:*:263:meta1s,meta1q
meta1:*:264:

While you're at it... in order to enable MeTA1's meta1c client to deliver to Cyrus IMAP's /var/imap/socket/lmtp socket you need to add meta1c to the "mail" group. There's probably a better way to do this however this was easiest at the time.

mail:*:1000:meta1c

To check whether the required users and groups exist, run:

$ ./misc/sm.check.sh -p

(in the build directory); see below how to override the default values for the user and group names.
A shell script to setup the directories, files, etc. as described below is available in misc/sm.setup.sh.in. This script is modified by configure to create misc/sm.setup.sh (in the build directory) which is invoked when

# make install

is called. Most defaults in the installation script misc/sm.setup.sh can be overridden with environment variables (default is listed in square brackets). Read the fine documentation for more information on the sm.setup.sh script

Configuration of MeTA1

The definitive documentation is supplied with the MeTA1 package. My focus is specifically directed towards configuring MeTA1 with STARTTLS and CRAM-MD5 SASL AUTH. Here is my /etc/meta1/meta1.conf.

	smtps {
		log_level = 24;
		log { facility=mail; ident="smtps"; }
		CDB_gid = 262;
		wait_for_server = 4;
		listen_socket { type=inet; port = 25; }
		start_action = pass;
  			pass_fd_socket = smtps/smtpsfd;
  			user = meta1s;
  			path = "/usr/local/libexec/smtps";
			flags = {8bitmime, access};
			arguments = "smtps -f /etc/meta1/meta1.conf";
			auth { 
				trusted_mechanisms = "CRAM-MD5";
				flags = { noplaintext }; 
  			}
			tls {
				key_file = "/etc/meta1/CA/newreq.pem";
				cert_file = "/etc/meta1/CA/newcert.pem";
				CAcert_directory = "/etc/meta1/CA";
				CAcert_file = "/etc/meta1/CA/cacert.pem";
			}
	}
		
	smtpc {
		log_level = 12;
		log { facility=mail; ident="smtpc"; }
		wait_for_server = 4;
		LMTP_socket = /var/imap/socket/lmtp;
		start_action = wait;
		user = meta1c;
		path = "/usr/local/libexec/smtpc";
		arguments = "smtpc -f /etc/meta1/meta1.conf";
		tls {
			key_file = "/etc/meta1/CA/newreq.pem";
			cert_file = "/etc/meta1/CA/newcert.pem";
			CAcert_directory = "/etc/meta1/CA";
			CAcert_file = "/etc/meta1/CA/cacert.pem";
		}
	}
	
	# must be previous to last in the list: started after smar
	qmgr {
		log_level = 12;
		log { facility=mail; ident="qmgr"; }
		wait_for_server = 4;
		wait_for_client = 3;
		start_action = wait;
		user = meta1q;
		restart_dependencies = { smtps, smtpc, smar };
		path = "/usr/local/libexec/qmgr";
		arguments = "qmgr -f /etc/meta1/meta1.conf";
	}

	# must be last in the list: started first
	smar {
		log_level = 12;
		log { facility=mail; ident="smar"; }
		nameserver = 192.168.1.1;
		start_action = wait;
		user = meta1m;
		restart_dependencies = { smtps, qmgr };
		path = "/usr/local/libexec/smar";
		arguments = "smar -f /etc/meta1/meta1.conf";
	}
		

Some things to note are:
The smtps "log_level" is set a bit high in my configuration for debugging purposes.
The smtps auth settings identify CRAM-MD5 as the trusted_mechanism
The smtpc delivery client points: LMTP_socket = /var/imap/socket/lmtp;
Both smtps (server) and smtpc (client) have "tls" settings.

Certificates for STARTTLS

The next thing we'll do is setup META1 to incorporate STARTTLS certificates for the purpose of regulating relay. By default, MeTA1 will build with SSL support. That is, of course, the configure script found the openssl libraries at a standard location. I will not go into details about how SSL works. For more information on STARTTLS check here.
The following information relates to self-signed certificates. In essence, you create your own root CA. All subsequently, created certificates under the root CA will be considered authorized to relay. I provide some high level information for creating certificates here.
When acting as a server, MeTA1 requires X.509 certificates to support STARTTLS: one as certificate for the server, at least one root CA (CAcert_file), i.e., a certificate that is used to sign other certificates, and a path to a directory which contains certs of other CAs (CAcert_directory). The file specified via CAcert_file can contain several certificates of CAs. The DNs of these certificates are sent to the client during the TLS handshake (as part of the CertificateRequest) as the list of acceptable CAs. However, do not list too many root CAs in that file, otherwise the TLS handshake may fail; e.g.,

error:14094417:SSL routines:SSL3_READ_BYTES:
sslv3 alert illegal parameter:s3_pkt.c:964:SSL alert number 47

You should probably put only the CA cert into that file that signed your own cert(s), or at least only those you trust. The directory specified via CAcert_directory must contain the hashes of each CA certificate as filenames (or as links to them). Symbolic links can be generated with the following two (Bourne) shell commands:

C=FileName_of_CA_Certificate
ln -s $C `openssl x509 -noout -hash < $C`.0

An X.509 certificate is also required for authentication in client mode, however, MeTA1 will always use STARTTLS when offered by a server. The client and server certificates can be identical. Certificates can be obtained from a certificate authority or created with the help of OpenSSL. The required format for certificates and private keys is PEM. To allow for automatic startup of MeTA1, private keys must be stored unencrypted. The keys are only protected by the permissions of the file system, hence they should not be readable by anyone but the owner. If server and client share the same key it is ok to make the key group readable however. Never make a private key available to a third party.

-r--r--r--  1 root     wheel       CAcert.pem
-r--r--r--  1 meta1s   meta1c      smcert.pem
-r--r-----  1 meta1s   meta1c      smkey.pem
drwxr-xr-x  2 root     wheel       certs/

Once you have your SSL certificates in place and meta1.conf is configured use tls you should verify everything is correct. First, verify the meta1.conf is configured correctly for both smtps and smtpc daemons. The following will check the syntax in the meta1.conf file.

/usr/local/libexec/smtps -f /etc/meta1/meta1.conf  -VVVV
/usr/local/libexec/smtpc -f /etc/meta1/meta1.conf -VVVV

Start the MeTA1 daemons using the mcp.sh shell script. Make sure all MeTA1 daemons are running and the syslog doesn't indicate errors. Connect to port 25 to verify STARTTLS is offered by the server.

$ telnet localhost 25
Trying ::1...
telnet: connect to address ::1: Connection refused
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
220 yourserver.com ESMTP MeTA1.1.0.PreAlpha12.0
ehlo yourserver.com
250-yourserver.com ESMTP Hi there
250-PIPELINING
250-STARTTLS
250-AUTH ANONYMOUS CRAM-MD5
250-SIZE 67108864
250-8BITMIME
250-ENHANCEDSTATUSCODES
250 HELP

It's also a good idea to connect to the smtp port using openssl to verify the connection is achieved successfully.

openssl s_client -connect yourserver.com:25 -debug -starttls smtp -crlf
CONNECTED(00000004)
read from 7C6F7540 [83EF6000] (8192 bytes => 1 (0x1))
0000 - 32                                                2
write to 7C6F7540 [CF7E8B50] (21 bytes => 21 (0x15))
0000 - 45 48 4c 4f 20 73 6f 6d-65 2e 68 6f 73 74 2e 6e   EHLO some.host.n
0010 - 61 6d 65 0d 0a                                    ame..
read from 7C6F7540 [83EF6000] (8192 bytes => 1 (0x1))
0000 - 32                                                2
write to 7C6F7540 [CF7E8B50] (10 bytes => 10 (0xA))
0000 - 53 54 41 52 54 54 4c 53-0d 0a                     STARTTLS..

To be continued...

updated: 06Dec06