GNU mailman mit nginx auf Debian/wheezy

Wenn man GNU mailman auf Debian/wheezy einsetzen will, dann installiert das Debian-Paket netterweise unter /etc/mailman/apache.conf ein Konfigurationsfile für den Apache, das einem die Aliasse so hinbiegt, dass sie auf Anhieb funktionieren. Gleichzeitig tut man sich mit dem Indianer recht leicht, cgi-bin’s auszuführen - das kann er nämlich von Haus aus. Mit nginx hat man hier leider etwas verloren, kann der doch weder cgi-bin von sich aus noch gibt es eine vorbereitet Konfiguration. Also schauen wir uns mal an, wie man das relevante Subset an Funktionalität mit nginx & Co. nachbauen kann.

Relativ einfach ist der cgi-bin-Teil. Debian stellt hier das Paket fcgiwrap bereit, welches man einfach installiert und startet. Das Ding ist bereits so vorkonfiguriert, dass es uns alle CGIs aus /usr/lib/cgi-bin ausführt und von nginx normal via FastCGI angesprochen werden kann. Das war der einfach Teil.

Die nginx-Konfiguration ist etwas komplizierter, man muss sich da nämlich mit der Variable fastcgi_split_path_info auseinandersetzen. Dabei handelt es sich um eine RegExp, in der wir zwei Teile gruppieren müssen. Der erste Teil soll dabei der Pfad zu dem eigentlichen CGI-Skript sein, der zweite Teil der zum Pfad. Oder anders gesagt, wenn wir die den Request /mailman/admin/listname/nondigest haben, dann muss die RegExp daraus den Skriptnamen mailman/admin machen und die Pfadinfo sollte /listname/nondigest sein - man beachte hier die Slashes, der Skriptname darf am Ende keinen, die Pfadinfo muss am Ende einen haben. Das ganze sieht dann ungeführ so aus:

# lists.example.net definition
server {
  server_name lists.example.net;
  listen 80;
  listen [::]:80;

  root /var/www/lists;
  index index.html;
  access_log /var/log/nginx/access-lists.example.net.log;


  location / {
    try_files $uri $uri/ =404;
  }

  location /mailman/ {
    gzip off;
    root  /usr/lib/cgi-bin;
    fastcgi_split_path_info (^/mailman/[^/]+)(/.*)$;
    fastcgi_pass  unix:/var/run/fcgiwrap.socket;
    # I commented out SCRIPT_FILENAME in /etc/nginx/fastcgi_params
    include /etc/nginx/fastcgi_params;
    fastcgi_param SCRIPT_FILENAME /usr/lib/cgi-bin$fastcgi_script_name;
    fastcgi_param PATH_INFO       $fastcgi_path_info;
  }

  location /pipermail/ {
    alias /var/lib/mailman/archives/public/;
    autoindex on;
  }

  location /images/mailman/ {
    alias /usr/share/images/mailman/;
  }

  location ~ /\.ht {
    deny all;
  }
}

Ein paar Anmerkungen dazu:

  • Zeilen vier und fünf sehen so aus, wenn es sich nicht um den Default-vHost auf dem Server handelt, deswegen kein default_server und kein ipv6only dahinter.
  • Zeile 19 macht genau den Split, den ich oben erwähnt habe.
  • Zeilen 21-24 sind ein bisserl speziell: Die mitgelieferte Datei /etc/nginx/fastcgi_params definiert den Parameter SCRIPT_FILENAME in für uns unbrauchbarer Form, deswegen habe ich da den “dreckigen” Weg gewählt und das einfach auskommentiert, weswegen ich es in Zeile 23 so setzen kann, wie ich will. Das bedeutet natürlich auch, dass man auf anderen vHosts auf dem selben Server immer eine Zeile extra braucht - wägt selber ab, was für Euch am wenigsten Aufwand ist.
  • Zeile 23 sorgt dann dafür, dass ein Request wie /mailman/listinfo/listname an das Skript /usr/lib/cgi-bin/mailman/listinfo weitergeleitet wird - via fcgiwrap natürlich.
  • Zeile 24 gibt bei einem Request wie /mailman/listinfo/listname den
  • Parameter /listname mit an das CGI-Skript weiter.

Insgesamt ist fcgiwrap wirklich sehr praktisch, das hat mir den Umstieg auf nginx bei einigen Dingen, z.B. auch awstats, deutlich erleichtert.

Zuletzt muss man sagen, dass die obige Konfiguration nicht perfekt ist: So habe ich zum einen auf die Rewrites verzichtet, die z.B. /admin nach /mailman/admin überführen, und zum anderen habe ich nie getestet, ob öffentliche Archive funktionieren. Wäre toll, wenn das mal jemand testen könnte und mir dann Bescheid sagt.