.. -*- mode: rst -*-

.. _appendix-guides-authentication:

==============
Authentication
==============

Scenarios
=========

1. Cluster nodes that are frequently rebuilt

   Default settings work well; machines do not float, and a per-client
   password is not required.

2. :ref:`appendix-guides-nat_howto`

 * Build client records in advance with ``bcfg2-admin``, setting a uuid
   for each new client.

 * Set the address attribute for each to the address of the NAT.

 * Optionally, set a per-client password for each, and set into secure
   mode.

   .. note::

      This will require the use of the uuid and password from each
      client, and will require that they come through the NAT address.

Building bcfg2.conf automatically
=================================

This is a :ref:`Cheetah template
<server-plugins-generators-cfg-cheetah>` that automatically constructs
per-client bcfg2.conf from the per-client metadata::

    [communication]
    protocol = xmlrpc/ssl
    #if $self.metadata.uuid != None
    user = $self.metadata.uuid
    #end if
    #if $self.metadata.password != None
    password = $self.metadata.password
    #else
    password = my-password-foobat
    #end if

    [components]
    bcfg2 = https://localhost:6789

In this setup, this will cause any clients that have uuids established
to be set to use them in ``bcfg2.conf``. It will also cause any clients
with passwords set to use them instead of the global password.

How Authentication Works
========================

#. First, the client is associated with a client record. If the client
   specifies a uuid, it uses this instead of the results of a dns or
   address lookup.

#. Next, the ip address is verified against the client record. If the
   address doesn't match, then the client must be set to
   floating='true'

#. Finally, the password is verified. If the client is set to secure
   mode, the only its per-client password is accepted. If it is not set
   to secure mode, then either the global password or per-client password
   will be accepted

Failure during any of these stages results in authentication
failure. Note that clients set into secure mode that do not have
per-client passwords set will not be able to connect.

SSL Cert-based client authentication
====================================

SSL-based client authentication is supported. This requires several
things:

#. Certificate Authority (to sign all keys)

#. Server key and cert signed by the CA

#. Client key and cert signed by the CA

A variety of CAs can be used, but these keys can be simply generated
using the following set of steps:

#. Setup a CA

   http://www.flatmtn.com/article/setting-openssl-create-certificates

#. Create keys for each client and server, signing them with the CA
   signing cert

   http://www.flatmtn.com/article/setting-ssl-certificates-apache

   .. note::
       The client CN must be the FQDN of the client (as returned by a
       reverse DNS lookup of the ip address. Otherwise, you will end up
       with an error message on the client that looks like::

           Server failure: Protocol Error: 401 Unauthorized
	   Failed to download probes from bcfg2
	   Server Failure

       You will also see an error message on the server that looks
       something like::

           cmssrv01 bcfg2-server[9785]: Got request for cmssrv115 from incorrect address 131.225.206.122
           cmssrv01 bcfg2-server[9785]: Resolved to cmssrv115.fnal.gov

#. Distribute the keys and certs to the appropriate locations

#. Copy the ca cert to clients, so that the server can be authenticated

Clients authenticating themselves with a certificate will be
authenticated that way first; clients can be setup to either
authenticate solely with certs, use certs with a fallback to password,
or password only. Also a bootstrap mode will be added shortly; this
will allow a client to authenticate with a password its first time,
requiring a certificate all subsequent times. This behavior can be
controlled through the use of the auth attribute in
``Metadata/clients.xml``::

    <Clients>
      <Client name='testclient' auth='cert'/>
    </Clients>

Allowed values are:

+-------------------+------------------------------------------+
| Auth Type         | Meaning                                  |
+===================+==========================================+
| ``cert``          | Certificates must be used                |
+-------------------+------------------------------------------+
| ``cert+password`` | Certificate or password may be used. If  |
|                   | a certificate is used, the password must |
|                   | also be used.                            |
+-------------------+------------------------------------------+
| ``bootstrap``     | Password can be used for one client run, |
|                   | after that only certificate is allowed   |
+-------------------+------------------------------------------+

``cert+password`` is the default.  This can be changed by setting the
``authentication`` parameter in the ``[communcation]`` section of
``bcfg2.conf``.  For instance, to set ``bootstrap`` mode as the global
default, you would add the following to ``bcfg2.conf``::

    [communication]
    authentication = bootstrap

``bootstrap`` mode is currently incompatible with the
:ref:`server-plugins-grouping-metadata-clients-database`.
