<?xml version="1.0" encoding="ISO-8859-1"?>

<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN" "http://docbook.org/xml/4.1.2/docbookx.dtd">

<article lang="en">
  <articleinfo>
    <title>dns -- Balancing mail connections using the DNS</title>
    <author>
      <firstname>Carlo</firstname>
      <surname>Contavalli</surname>
      <affiliation>
        <address><email>ccontavalli at masobit.net</email></address>
      </affiliation>
    </author>
    <revhistory>
      <revision>
        <revnumber>1.0.0</revnumber>
        <date>2004/08/28</date>
        <revremark>First Document Release</revremark>
      </revision>
      <!--
      <revision>
        <revnumber>v2.2.7</revnumber>
        <date>2003-07-09</date>
        <authorinitials>es</authorinitials>
        <revremark> Fixed broken links to LDP XSL and other LDP XSL specific filenames. </revremark>
      </revision>
      -->
    </revhistory>

    <abstract>
      <para>
        This document describes how to use your
	own DNS as a load balancer for the whole
	<ulink url="http://www.pigeonair.net/">PigeonAir</ulink>
	project.
      </para>
      <para>
        The proposed setup works well using 
	Bind 8.0.0 and above, but is believed
	to work with most Bind versions.
      </para>
    </abstract>
  </articleinfo>

  <sect1 id="bef">
    <title>Before starting</title>

    <para>
      This document was written as part of the documentation
      of the PigeonAir Project to provide help and support to 
      users, system administrators or developers.
    </para>

    <para>
      While every effort has been made to ensure that the 
      information is accurate at the time of publication,
      this document may contain errors, omissions, incongruences 
      or wrong technical details. No liability for damages
      is accepted by the Author/Authors, the publishers or
      any other organization or person providing the information,
      arising from any errors or omissions that may appear,
      however caused.
    </para>

    <para>
      In case you find an error, you would like to propose better
      solutions than those discussed in this document or you
      would like to discuss an idea regarding this document
      or its content, we would be glad to hear from you and
      please feel free to contact us by writing to the &lt;pigeon-dev 
      at ml.pigeonair.net&gt; mailing list or by directly 
      contacting one of the authors.
    </para>


    <sect2>
      <title>Intended Audience</title>

      <para>
        This document is meant to explain DNS Administrators how
	to setup their own Bind DNS to balance connections in a 
	PigeonAir Cluster. You should be worried about using
	the DNS as balancer if your PigeonAir cluster is made
	of more than one node and if your installation does
	not use any other kind of balancer.
      </para>
      <para>
        It is strongly discouraged to use DNS balancing in
	any cluster with more than 3/4 nodes, since it is  
	<emphasis>always</emphasis> better to use a dedicated
	appliance or system to balance connections. 
      </para>
    </sect2>

    <sect2>
      <title>Copyright Notice</title>

      <para>
        This document was written by Carlo Contavalli &lt;ccontavalli at masobit.net&gt; 
        and is thus Copyright (C) Carlo Contavalli 2003, 2004 and the PigeonAir Project.
      </para>
      <para>
        Permission is granted to copy, distribute and/or modify this document
        under the terms of the GNU Free Documentation License, Version 1.1 or
        any later version published by the Free Software Foundation; with no
        Invariant Sections, no Front-Cover Texts and no Back-Cover Texts.
      </para>

      <para>
        Any example of program code available in this document should be
        considered protected by the terms of the GNU General Public License.
      </para>

      <para>
        You should have received a copy of the GNU General Public License
        along with this document; if not, write to the Free Software
        Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
      </para>

      <para>
        Trademarks are owned by their respective owners. 
      </para>
    </sect2>
  </sect1>


  <!-- nota: l'id deve essere diverso per ogni sezione,
   	e serv per generare automaticamente delle referenze
	incrociate (esempio: guardate la sezione X per
	maggiori informazioni. X puo` cambiare, se vengono
	spostati dei dati su e giu` per il documento. L'id
	no -->
  <sect1 id="intro">
    <title>DNS Records for standard mail services</title>
    <para>
    This section will discuss DNS configuration
    needed to balance services like IMAP, POP3 and 
    SMTP.</para>

    <sect2>
      <title>POP3/IMAP Protocol</title>

      <para>
        Main purpose of the DNS records regarding the
	POP3/IMAP services is to allow users to use
	a symbolic name to connect to one of the 
	POP3/IMAP servers.
      </para>

      <para>
        Which POP3/IMAP node of the cluster the user 
	will actually end up to connect to is not really 
	important: using a shared storage cluster, each 
	node of the cluster is able to access user data,
	while using a distributed storage the server
	receiving the connection will take care
	to forward it to correct node. If you don't
	know what I mean, please make sure to read
	%TODO%.
      </para>

      <para>
        To load balance connections, it is thus sufficient
	to add multiple <emphasis>A</emphasis> records,
	pointing to all the POP3/IMAP Proxies/Servers,
	depending on the setup being used.
      </para>
      <para>
        This needs to be done for all the domain handled
	by the cluster, either adding all A records
	for each domain or by adding a CNAME which points
	to the list of A records.
      </para>
      <para>
        As an example, if we need to provide an IMAP/POP3
	server with address ``imap.mydomain.org'' and we
	have a PigeonAir cluster made of 3 nodes having with
	ip address 1.2.3.4, 1.2.3.5 and 1.2.3.6, we need
	to add the following records in the ``mydomain.org''
	zone:
	<programlisting>
imap.mydomain.org.	A 	1.2.3.4
			A	1.2.3.5
			A	1.2.3.6</programlisting>
	As said in the previous section, those records
	should be added to all the zones of every virtual
	domain handled by the cluster. If you don't like
	this, either use another balancer, use <emphasis>CNAMEs</emphasis>,
	or try to find a better solution.
      </para>
    </sect2>

    <sect2>
      <title>SMTP Protocol</title>
      <para>
        The SMTP protocol handles both the reception of new emails
	from remote servers and the sending of emails for dialup
	customers (relaying).
      </para>
      <para>
        The two setups require two different sets of DNS records
	to be added, that will be discussed in the specific sections.
      </para>
      <para>
        Note that there are many possible solutions, here we will
	discuss just one of them, probably not even the best one.
      </para>

      <sect3>
        <title>SMTP emails reception</title>

	<para>
	  As in the IMAP/POP3 case, for the PigeonAir cluster
	  to work correctly it is enough for connections
	  to get to anyone of the cluster nodes handling SMTP.
	  The servers will take care internally either to deliver
	  the mail to the disks, or to forward them to the correct
	  node of the cluster.
	</para>

	<para>
	  One of the easiest solution to use is just to provide
	  multiple equal-priority MX records in each zone being
	  handled by the mail cluster.
	</para>

	<para>
	  As an example, in the case we have 3 cluster nodes named
	  node00.mail.org, node01.mail.org and node02.mail.org that
	  need to handle the emails directed to mydomain.org,
	  we would could add the following records to the mydomain.org
	  DNS zone:
	  <programlisting>
	MX	10 	node00.mail.org.
	MX 	10 	node01.mail.org.
	MX	10	node02.mail.org.</programlisting>
	  In case your customers do not want your servers to appear
	  in their zones, you can always insert the necessary A
	  records in the mydomain.org zone, as shown below:
	  <programlisting>
	MX      10      node00.mydomain.org.
        MX      10      node01.mydomain.org.
        MX      10      node02.mydomain.org.

	node00.mydomain.org. A    1.2.3.4
	node01.mydomain.org. A    1.2.3.5
	node02.mydomain.org. A    1.2.3.6</programlisting>
	</para>
	<para>
	  This setup is a bit more inconvenient in the case 
	  we will ever need to change the IP address of the 
	  SMTP servers.
	</para>
      </sect3>

      <sect3>
        <title>SMTP emails sending (relay)</title>

	<para>
	  As in all the above cases, it is enough for a given
	  client to connect to any one of the PigeonAir cluster
	  nodes to send a mail, provided it is authorized to do
	  so.
	</para>

	<para>
	  Providers are usually required to provide the name of
	  the SMTP server for the customers to use, for example
	  smtp.mydomain.org.
	</para>

	<para>
	  In this case, you can simply add as many A records
	  for smtp.mydomain.org as many nodes of the cluster
	  you want your customers to use.
	</para>

	<para>
	  As an example, if you have 3 cluster nodes behaving
	  as relay hosts for you dialup customers, with
	  the ip addresses used in the previous examples,
	  and you want your customers to use ``smtp.mydomain.org''
	  to send emails, you can add the following records in
	  the ``mydomain.org'' DNS zone:
	  <programlisting>
smtp.mydomain.org.	A	1.2.3.4
			A	1.2.3.5
			A	1.2.3.6</programlisting>
	</para>

	<para>
	  You can either setup a single SMTP server record for
	  outgoing emails, or you can add one for every one
	  of your virtual domains.
	</para>
      </sect3>

      <sect3>
        <title>Notes</title>
	
	<para>
	  In all the previous examples, all the nodes of
	  the cluster where used for every virtual domain.
	  By configuring properly the DNS, you can also
	  choose to use certain cluster nodes for certain
	  domains and thus reserve some resources for 
	  particular services.
	</para>

      </sect3>
    </sect2>

    <sect2>
      <title>DNS Records for web interfaces</title>

      <para>
        Web interfaces are kind of trickier to setup
	correctly. The main problem here is that web
	interfaces need to track users, they need 
	to store session in order to remember what
	they were doing and their own authentication
	data.
      </para>

      <para>
        PigeonAir web interfaces all relay on PHP4,
	so you can use any PHP4 method for sharing
	sessions. In case you use one of the methods,
	you don't have to worry about DNS records
	anymore, you can simply add as many A records
	as nodes in the cluster handling web requests,
	allowing customers to connect to any of them
	on any request.
      </para>

      <para>
        Those methods either relay on a shared file
	system, like NFS, keeping all sessions shared
	among server, or on an external database
	that takes care of sharing sessions.
      </para>

      <para>
        Since we don't like NFS (introduces a SPF),
	and seems a waste to use a whole DB just
	to handle PHP sessions (depends on the environment,
	but in most cases it is), we describe here
	a simple method you can use to allow users
	to connect to any host and then bind them
	to one of the nodes until the session
	expires (or the user logs out). 
      </para>

      <para>
        As all the interfaces are very lightweight,
	the method has proved to be very reliable
	and at doing a very good average load
	balancing among servers.
      </para>

      <para>
        If you still want to share a file system
	or use a shared db, please refer to %TODO%.
      </para>

      <sect3>
        <title>How it works</title>

	<para>
	  In the described setup, sessions are not
	  shared among servers. This means that once
	  a user logs in, it must be bound to a single
	  server until it logs out.
	</para>

	<para>
	  The mechanism provided by all PigeonAir interfaces
	  relies on a ``magic name'', which is the name 
	  being used by users to access the web interface.
	</para>

	<para>
	  This name will resolve to any of the nodes involved
	  in the mail cluster. The node receiving the connection,
	  after seeing the ``magic name'' has being used, will
	  redirect the client to a mangled version of the mangled
	  name, corresponding to the name of the server itself in 
	  the DNS.
	</para>

	<para>
	  As an example, users may access the webmail using
	  ``webmail.mydomain.org'', which resolves to any of
	  the cluster nodes. Once one of the nodes receives
	  a connection for ``webmail.mydomain.org'', the magic
	  name, the connection will be redirected to (for
	  example) ``webmail00.mydomain.org'', the name of 
	  the node, thus binding the user to a given node
	  until the end of the session.
	</para>

	<para>
	  A mechanism to detect users who decide to bookmark
	  the mangled name and to redirect users anyway is 
	  being implemented right now in all the web interfaces,
	  in order to keep the load ``well balanced''.
	</para>

	<para>
	  The mangling rules allow for virtual domains to
	  make use of ``magic names'', exactly as shown above.
	</para>
      </sect3>

      <sect3>
        <title>Setting up the DNS</title>

	<para>
	  Ok, the ``magic'' name is configurable from PigeonAdmin
	  and PigeonReader configuration files. For the sake of
	  simplicity, let's say it has been chosen to be ``webmail'',
	  and let's say we have the same 3 cluster nodes as in the
	  previous examples.
	</para>

	<para>
	  In order to correctly setup the zone for ``mydomain.org'',
	  we would need to add something like:
	  <programlisting>
; To balance the connection to the webmail
webmail.mydomain.org.	A	1.2.3.4
			A	1.2.3.5
			A	1.2.3.6

; To allow the web mail to ``bind''
; the connection to a particular host
webmail00.mydomain.org.	A	1.2.3.4
webmail01.mydomain.org.	A	1.2.3.5
webmail02.mydomain.org.	A	1.2.3.6</programlisting>
	</para>
	<para>
	  If you want to, keep also in mind you are free:
	  <itemizedlist>
	    <listitem><para>
	      to force users to use just one of the cluster
	      nodes, by simply using an A record with a 
	      different name than the magic one.
	    </para></listitem>
	    <listitem><para>
	      to force the connections to follow on given
	      cluster nodes, by properly changing the A
	      records for the mangled names, or by changing
	      the configuration of the PigeonReader or
	      PigeonAdmin web interface.
	    </para></listitem>
	  </itemizedlist>
	</para>
      </sect3>
    </sect2>
  </sect1>

  
</article>
