Proxying
========

Dovecot supports proxying IMAP and POP3 connections to other hosts. The
proxying can be done for all users, or only for some specific users. There are
two ways to do the authentication:

 1. Forward the password to the remote server and let it perform the actual
    authentication. This requires that the client uses only plaintext
    authentication.
 2. Let Dovecot proxy perform the authentication and login to remote server
    using the proxy's<master password> [MasterPassword.txt]. This allows client
    to use also non-plaintext authentication.

The proxy is configured pretty much the same way as <login referrals>
[PasswordDatabase.ExtraFields.Host.txt], with the addition of 'proxy' field.
The common fields to use for both proxying ways are:

 * 'proxy' and 'proxy_maybe': Enables the proxying. Either one of these fields
   is required.
    * 'proxy_maybe' can be used to implement "automatic proxying". If the proxy
      destination matches the current connection, the user gets logged in
      normally instead of being proxied. If the same happens with 'proxy', the
      login fails with "Proxying loops" error. This feature exists only in
      v1.1+.
 * 'host=s': The destination server's *IP address*. This field is required.
   Note that currently it's required to use an IP address since no DNS
   resolving is done.
 * 'port=s': The destination server's port. The default is 143 with IMAP and
   110 with POP3.
 * 'destuser=s': Tell client to use a different username when logging in.

The connections created to the destination server can't be TLS/SSL encrypted.

The destination servers don't need to be running Dovecot, but you should make
sure that the Dovecot proxy doesn't advertise more capabilities than the
destination server can handle. For IMAP you can do this by changing
'imap_capability' setting. For POP3 you'll have to modify Dovecot's sources for
now ('src/pop3/capability.h').

Password forwarding
-------------------

Make sure that the authentication succeeds with any given password. You can do
this by using empty passwords. v1.1+ requires also that you return 'nopassword'
field.

Master password
---------------

This way of forwarding requires the destination server to support master user
feature. The users will be normally authenticated in the proxy and the common
proxy fields are returned, but you'll need to return two fields specially:

 * 'destuser=s': Both the logging username and the master username need to be
   included in this.
 * 'pass=s': This field contains the master user's password.

For the master user logins it'd be cleaner to use a SASL mechanism with
authorization ID, but for now this isn't supported.

If the destination server is Dovecot, you can return these fields like:

 * 'destuser=%u*proxy'
 * 'pass=secret'

Then in the destination Dovecot's config file set
'auth_master_user_separator=*' and create a master user named *proxy* with
password *secret*. See <MasterPassword.txt> for more information how to
configure this.

Example password forwarding SQL configuration
---------------------------------------------

Create the SQL table:

---%<-------------------------------------------------------------------------
CREATE TABLE proxy (
  user varchar(255) NOT NULL,
  host varchar(16) default NULL,
  destuser varchar(255) NOT NULL default '',
  PRIMARY KEY  (user)
);
---%<-------------------------------------------------------------------------

Insert data to SQL corresponding your users.

Working data could look like this: 

+------+-------------+-----------------+
| user | host        | destuser        |
+------+-------------+-----------------+
| john | 192.168.0.1 |                 |
+------+-------------+-----------------+
| joe  | 192.168.0.2 | joe@example.com |
+------+-------------+-----------------+

The important parts of 'dovecot.conf':

---%<-------------------------------------------------------------------------
# If you want to trade a bit of security for higher performance, change these
settings:
login_process_per_connection = no
login_processes_count = 20

# If you are not moving mailboxes from host to one on daily basis you can
# use authentication cache pretty safely.
auth_cache_size = 4096

auth default {
  mechanisms = plain

  # dovecot-auth only needs to be able to connect to SQL
  user = nobody

  # Userdb settings are not used with proxy but there need to be something.
  userdb static {
    args = uid=0 gid=0
  }
  passdb sql {
    args = /usr/local/etc/dovecot-sql.conf
  }
}
---%<-------------------------------------------------------------------------

The important parts of 'dovecot-sql.conf':

---%<-------------------------------------------------------------------------
# Database driver: mysql, pgsql
driver = mysql

# Database connect string.
# Only MySQL driver support multiple hosts for now.
connect = host=sqlhost1 host=sqlhost2 dbname=mail user=dovecot password=secret

# Query
password_query = SELECT NULL AS password, host, destuser, 'Y' AS proxy FROM
proxy WHERE user = '%u'
---%<-------------------------------------------------------------------------

Example proxy_maybe SQL configuration
-------------------------------------

Create the SQL table:

---%<-------------------------------------------------------------------------
CREATE TABLE users (
  user varchar(255) NOT NULL,
  domain varchar(255) NOT NULL,
  password varchar(100) NOT NULL,
  host varchar(16) NOT NULL,
  home varchar(100) NOT NULL,
  PRIMARY KEY (user)
);
---%<-------------------------------------------------------------------------

The important parts of 'dovecot.conf':

---%<-------------------------------------------------------------------------
# user/group who owns the message files:
mail_uid = vmail
mail_gid = vmail

auth default {
  mechanisms = plain

  # dovecot-auth only needs to be able to connect to SQL
  user = nobody

  passdb sql {
    args = /usr/local/etc/dovecot-sql.conf
  }
  userdb sql {
    args = /usr/local/etc/dovecot-sql.conf
  }
}
---%<-------------------------------------------------------------------------

The important parts of 'dovecot-sql.conf':

---%<-------------------------------------------------------------------------
driver = mysql

password_query = \
  SELECT concat(user, '@', domain) AS user, password, host, 'Y' AS proxy_maybe
\
  FROM users WHERE user = '%n' AND domain = '%d'

user_query = SELECT home FROM users WHERE user = '%n' AND domain = '%d'
---%<-------------------------------------------------------------------------

(This file was created from the wiki on 2009-03-02 04:42)
