Mailman
Background
Mailman is a complex piece of software, I've taken notes while setting it up in a jail on a FreeBSD 8-stable machine. The jail has a global ipv4 and an ipv6 address, but no loopback address.
Installation
This section outlines the ports that needs to be installed.
Postfix
I install postfix from /usr/ports/mail/postfix and check the TLS option. I stop Sendmail before continuing:
[tykling@lists ~]$ sudo /etc/rc.d/sendmail onestop Stopping sendmail. Stopping sendmail_clientmqueue. [tykling@lists ~]$
I add the following to /etc/rc.conf:
sendmail_enable="NO" sendmail_submit_enable="NO" sendmail_outbound_enable="NO" sendmail_msp_queue_enable="NO" postfix_enable="YES"
I also add the following to /etc/periodic.conf:
daily_clean_hoststat_enable="NO" daily_status_mail_rejects_enable="NO" daily_status_include_submit_mailq="NO" daily_submit_queuerun="NO"
Finally I run postalias on /etc/aliases:
[tykling@lists ~]$ sudo postalias /etc/aliases [tykling@lists ~]$
nginx
I also install /usr/ports/www/nginx with the following options enabled:
[tykling@lists /usr/ports/www/nginx]$ sudo make showconfig | grep =on
     IPV6=on: Enable IPv6 support
     HTTP=on: Enable HTTP module
     HTTP_REWRITE=on: Enable http_rewrite module
     HTTP_SSL=on: Enable http_ssl module
[tykling@lists /usr/ports/www/nginx]$ 
I also enable it in /etc/rc.conf:
nginx_enable="YES"
thttpd
For cgi-bin processing (which nginx doesn't do) I install /usr/ports/www/thttpd.
I also enable it in /etc/rc.conf:
thttpd_enable="YES"
Mailman
Finally I install /usr/ports/mail/mailman with the Postfix option enabled:
[tykling@lists /usr/ports/mail/mailman]$ sudo make showconfig | grep =on
     POSTFIX=on: for use with postfix
[tykling@lists /usr/ports/mail/mailman]$ 
I also enable it in /etc/rc.conf:
mailman_enable="YES"
Configuration
The following section contains the configs I used for this server.
Postfix
The main config file /usr/local/etc/postfix/main.cf is very verbose by default but the defaults are fine actually, and the config below is all I need:
[tykling@lists ~]$ cat /usr/local/etc/postfix/main.cf
mynetworks_style = host
inet_protocols = ipv4 ipv6
relay_domains  = lists.thecamp.dk
mailman_destination_recipient_limit = 1
transport_maps = hash:/usr/local/etc/postfix/transport
alias_maps = hash:/usr/local/etc/postfix/aliases
# Spam restrictions
smtpd_recipient_restrictions =
        reject_invalid_helo_hostname,
        reject_non_fqdn_helo_hostname,
        reject_non_fqdn_sender,
        reject_non_fqdn_recipient,
        reject_unknown_sender_domain,
        reject_unknown_recipient_domain,
        reject_unauth_pipelining,
        reject_rbl_client zen.spamhaus.org,
        reject_rhsbl_helo dbl.spamhaus.org,
        reject_rhsbl_client dbl.spamhaus.org,
        reject_rhsbl_sender dbl.spamhaus.org,
        permit_mynetworks,
        reject_unauth_destination
# TLS settings
smtpd_tls_cert_file = /usr/local/www/certificates/lists.tyknet.dk.crt
smtpd_tls_key_file = /usr/local/www/certificates/lists.tyknet.dk.key
smtpd_tls_auth_only = yes
smtpd_tls_received_header = yes
smtpd_tls_security_level = may
smtp_tls_CAfile = /usr/local/www/certificates/lists.tyknet.dk.crt
smtp_tls_session_cache_database = btree:/var/db/postfix/smtp_tls_session_cache
smtp_tls_security_level = may
I also add the following snippet to /usr/local/etc/postfix/master.cf:
mailman unix - n n - - pipe
  flags=FR user=mailman:nobody
  argv=/usr/local/mailman/postfix-to-mailman.py ${nexthop} ${user}
Finally I fix the transport map neccesary to make Postfix deliver the mails for the domain lists.thecamp.dk to the postfix-to-mailman.py script:
[tykling@lists ~]$ cat /usr/local/etc/postfix/transport lists.thecamp.dk mailman: [tykling@lists ~]$
Postfix-to-mailman.py
I use a script to get the mail from Postfix to Mailman, the script can be downloaded and installed easily and it works very well:
[tykling@lists ~]$ fetch http://www.gurulabs.com/downloads/postfix-to-mailman-2.1.py postfix-to-mailman-2.1.py 100% of 4633 B 26 kBps [tykling@lists ~]$ sudo mv postfix-to-mailman-2.1.py /usr/local/mailman/postfix-to-mailman.py [tykling@lists ~]$
I edit the script to fix the path to Python and set two required variables:
[tykling@lists ~]$ diff -u /usr/local/mailman/postfix-to-mailman.py postfix-to-mailman.py --- /usr/local/mailman/postfix-to-mailman.py 2012-06-10 19:33:44.557197572 +0200 +++ postfix-to-mailman.py 2012-06-10 19:33:02.609292985 +0200 @@ -1,8 +1,8 @@ -#!/usr/local/bin/python +#! /usr/bin/env python # Configuration variables - Change these for your site if necessary. -MailmanHome = "/usr/local/mailman"; # Mailman home directory. -MailmanOwner = "thomas@gibfest.dk"; # Postmaster and abuse mail recipient. +MailmanHome = "/var/mailman"; # Mailman home directory. +MailmanOwner = "postmaster@example.com"; # Postmaster and abuse mail recipient. # End of configuration variables. # postfix-to-mailman-2.1.py (to be installed as postfix-to-mailman.py) [tykling@lists ~]$
Finally I need to make the script executable:
[tykling@lists ~]$ sudo chmod +x /usr/local/mailman/postfix-to-mailman.py [tykling@lists ~]$
nginx
I add the following to the nginx config file /usr/local/etc/nginx/nginx.conf:
worker_processes  1;
events {
	worker_connections  1024;
}
http {
	include       mime.types;
	default_type  application/octet-stream;
	sendfile        on;
	keepalive_timeout  65;
	server {
		listen                  80 default;
		server_name             lists.thecamp.dk;
		rewrite                 ^ https://$server_name$request_uri? permanent;
	}
	server {
		listen 443 default;
		server_name lists.tyknet.dk;
		root /usr/local/mailman;
		ssl                     on;
		ssl_certificate         /usr/local/www/certificates/lists.thecamp.dk.crt;
		ssl_certificate_key     /usr/local/www/certificates/lists.thecamp.dk.key;
		add_header              Strict-Transport-Security max-age=31536000;
		location = / {
			rewrite ^ /mailman/listinfo permanent;
		}
		location / {
			rewrite ^ /mailman$uri?$args;
		}
		location = /mailman/ {
			rewrite ^ /mailman/listinfo permanent;
		}
		location /mailman/ {
			#include proxy_params;
			proxy_pass http://lists.thecamp.dk:8080/;
			proxy_set_header Host $host;
			proxy_set_header X-Real-IP $remote_addr;
		}
		location /cgi-bin {
			rewrite ^/cgi-bin(.*)$ $1 permanent;
		}
		location /images/mailman {
			alias /usr/local/mailman/icons;
		}
		location /icons {
			alias /usr/local/mailman/icons;
		}
		location /pipermail {
			alias /usr/local/mailman/archives/public;
			autoindex on;
		}
	}
}
thttpd
I create the following config for the thttpd webserver, /usr/local/etc/thttpd.conf:
host=78.47.102.140 port=8080 dir=/usr/local/mailman/cgi-bin nochroot user=www cgipat=/** logfile=/var/log/thttpd.log
Mailman
Mailman can be configured by adding settings in /usr/local/mailman/Mailman/mm_cfg.py:
DEFAULT_URL_PATTERN = 'https://%s/mailman/' PUBLIC_ARCHIVE_URL = 'https://%(hostname)s/pipermail/%(listname)s' DEFAULT_REPLY_GOES_TO_LIST = 1 DEFAULT_ADMIN_NOTIFY_MCHANGES = Yes
Starting services
I start Postfix, nginx, thttpd and Mailman:
[tykling@lists ~]$ sudo /usr/local/etc/rc.d/postfix start postfix/postfix-script: fatal: the Postfix mail system is already running [tykling@lists ~]$ sudo /usr/local/etc/rc.d/nginx start Performing sanity check on nginx configuration: nginx: the configuration file /usr/local/etc/nginx/nginx.conf syntax is ok nginx: configuration file /usr/local/etc/nginx/nginx.conf test is successful Starting nginx. [tykling@lists ~]$ sudo /usr/local/etc/rc.d/thttpd start Starting thttpd. [tykling@lists ~]$ sudo /usr/local/etc/rc.d/mailman start Site list is missing: mailman [tykling@lists ~]$
Mailman refuses to start because there needs to be a site list called mailman. The list is created like so:
[tykling@lists ~]$ sudo /usr/local/mailman/bin/newlist Enter the name of the list: mailman Enter the email of the person running the list: thomas@gibfest.dk Initial mailman password: To finish creating your mailing list, you must edit your /etc/aliases (or equivalent) file by adding the following lines, and possibly running the `newaliases' program: ## mailman mailing list mailman: "|/usr/local/mailman/mail/mailman post mailman" mailman-admin: "|/usr/local/mailman/mail/mailman admin mailman" mailman-bounces: "|/usr/local/mailman/mail/mailman bounces mailman" mailman-confirm: "|/usr/local/mailman/mail/mailman confirm mailman" mailman-join: "|/usr/local/mailman/mail/mailman join mailman" mailman-leave: "|/usr/local/mailman/mail/mailman leave mailman" mailman-owner: "|/usr/local/mailman/mail/mailman owner mailman" mailman-request: "|/usr/local/mailman/mail/mailman request mailman" mailman-subscribe: "|/usr/local/mailman/mail/mailman subscribe mailman" mailman-unsubscribe: "|/usr/local/mailman/mail/mailman unsubscribe mailman" Hit enter to notify mailman owner... [tykling@lists ~]$
The aliases needs to be copied to the file /usr/local/etc/postfix/aliases and to make Postfix able to use it, I run:
[tykling@lists ~]$ sudo postalias /usr/local/etc/postfix/aliases [tykling@lists ~]$
After creating the mailman mailing list, Mailman starts up without complaining:
[tykling@lists ~]$ sudo /usr/local/etc/rc.d/mailman start [tykling@lists ~]$