Perdition

Perdition is an IMAP proxy. It can be used to create a front-end imap host that will then look up in a database and figure out which backend IMAP server to shuffle the request to.

This is the perdition configuration used with nest.

# apt-get install perdition-mysql

codetitle. /etc/default/perdition

RUN_PERDITION=yes
POP3=yes
POP3S=yes
IMAP4=yes
IMAP4S=yes

General Configuration

Advertise an imap capability to the world that is the same as courier’s (or whatever backend imap server we are using):

imap_capability "IMAP4rev1 UIDPLUS CHILDREN NAMESPACE THREAD=ORDEREDSUBJECT THREAD=REFERENCES SORT QUOTA IDLE"

We downcase all the incoming names, in the event that someone logged in as ‘Bob@riseup.net’:

lower_case all

Together, these will add riseup.net to user when doing the proxy lookup:

explicit_domain 'riseup.net'
add_domain servername_lookup

Needed for SSL:

ssl_cert_file /etc/certs/mail.riseup.net/cert.pem
ssl_key_file /etc/certs/mail.riseup.net/key.pem 
ssl_mode tls_listen

A ssl_mode of tls_listen will make it so that tls is supported on the connection to the public world, but not our proxy connection to a backend IMAP server. In our case, the backend connection is over a vpn private network, so we don’t bother with creating a tls connection there.

Database Lookups

Configuration options to do database lookups:

map_library /usr/lib/libperditiondb_mysql.so.0.0.0
map_library_opt dbhost-vpn:3306:nest:mailboxes:nest_mail:xxxxxx:storage_ip:143
no_lookup
timeout 1800

In our case, we are making a connection to dbhost-vpn on port 3306, using database net, logging in as user nest_mail with password xxxxxx, doing a search on the mailboxes table, returning the result in the storage_ip column, and then connecting to that ip on port 143.

Here is the format for map_library_opt: dbhost:dbport:dbname:dbtable:dbuser:dbpw:dbsrvcol:dbusercol:dbportcol. All options are required.

The no_lookup option tells perdition to skip resolving a hostname because the result will be an ip address. The default idle timeout is 1800, which we duplicate here for fun.

Putting it all together

imap

codetitle. /etc/perdition/perdition.imap4.conf

connection_limit 0
imap_capability "IMAP4rev1 UIDPLUS CHILDREN NAMESPACE THREAD=ORDEREDSUBJECT THREAD=REFERENCES SORT QUOTA IDLE STARTTLS"
ssl_cert_file /etc/certs/mail.riseup.net/cert.pem
ssl_key_file /etc/certs/mail.riseup.net/key.pem 
map_library /usr/lib/libperditiondb_mysql.so.0.0.0
map_library_opt dbhost-vpn:3306:nest:mailboxes:nest_mail:xxxxxxx:storage_ip:address:143
no_lookup
lower_case all
explicit_domain 'riseup.net'
add_domain servername_lookup
ssl_mode tls_listen

/etc/perdition/perdition.imaps.conf is exectly the same, except for one line:

ssl_mode ssl_listen

In the case of imaps, we want to require a secure connection, so we want ssl_listen instead of tls_listen.

pop

codetitle. /etc/perdition/perdition.pop3.conf

connection_limit 0
ssl_cert_file /etc/certs/mail.riseup.net/cert.pem
ssl_key_file /etc/certs/mail.riseup.net/key.pem 
map_library /usr/lib/libperditiondb_mysql.so.0.0.0
map_library_opt dbhost-vpn:3306:nest:mailboxes:nest_mail:xxxxxxx:storage_ip:address:110
no_lookup
lower_case all
explicit_domain 'riseup.net'
add_domain servername_lookup
ssl_mode tls_listen

The only difference between the pop3 config and the imap3 config is that we specify port 110 instead of 143, and we don’t need the imap_capability line.

Again, /etc/perdition/perdition.pops.conf is exectly the same, except for one line:

ssl_mode ssl_listen

Running perdition

To start, stop, and restart perdition:

/etc/init.d/perdition [start|stop|restart]

If something is not working, you can add one or both of these options to the config:

connection_logging
debug