summaryrefslogtreecommitdiffstats
path: root/doc/server/plugins/generators/sslca.txt
blob: 8e33148cb0fa1541741f49e2cf06776d178c9ea9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
.. -*- mode: rst -*-

.. _server-plugins-generators-sslca:

=====
SSLCA
=====

SSLCA is a generator plugin designed to handle creation of SSL private keys
and certificates on request.

Borrowing ideas from the TGenshi and SSHbase plugins, SSLCA automates the
generation of SSL certificates by allowing you to specify key and certificate
definitions.  Then, when a client requests a Path that contains such a
definition within the SSLCA repository, the matching key/cert is generated, and
stored in a hostfile in the repo so that subsequent requests do not result in
repeated key/cert recreation.  In the event that a new key or cert is needed,
the offending hostfile can simply be removed from the repository, and the next
time that host checks in, a new file will be created.  If that file happens to
be the key, any dependent certificates will also be regenerated.

Getting started
===============

In order to use SSLCA, you must first have at least one CA configured on 
your system.  For details on setting up your own OpenSSL based CA, please
see http://www.openssl.org/docs/apps/ca.html for details of the suggested
directory layout and configuration directives.

For SSLCA to work, the openssl.cnf (or other configuration file) for that CA
must contain full (not relative) paths.

#. Add SSLCA to the **plugins** line in ``/etc/bcfg2.conf`` and restart the
   server -- This enabled the SSLCA plugin on the Bcfg2 server.

#. Add a section to your ``/etc/bcfg2.conf`` called sslca_foo, replacing foo
   with the name you wish to give your CA so you can reference it in certificate
   definitions.

#. Under that section, add an entry for ``config`` that gives the location of
   the openssl configuration file for your CA.

#. If necessary, add an entry for ``passphrase`` containing the passphrase for
   the CA's private key.  We store this in ``/etc/bcfg2.conf`` as the permissions
   on that file should have it only readable by the bcfg2 user.  If no passphrase
   is entry exists, it is assumed that the private key is stored unencrypted.

#. Add an entry ``chaincert`` that points to the location of your ssl chaining
   certificate.  This is used when preexisting certifcate hostfiles are found, so
   that they can be validated and only regenerated if they no longer meet the
   specification. If you're using a self signing CA this would be the CA cert
   that you generated.

#. Once all this is done, you should have a section in your ``/etc/bcfg2.conf``
   that looks similar to the following::

       [sslca_default]
       config = /etc/pki/CA/openssl.cnf
       passphrase = youReallyThinkIdShareThis?
       chaincert = /etc/pki/CA/chaincert.crt

#. You are now ready to create key and certificate definitions.  For this
   example we'll assume you've added Path entries for the key,
   ``/etc/pki/tls/private/localhost.key``, and the certificate,
   ``/etc/pki/tls/certs/localhost.crt`` to a bundle or base.

#. Defining a key or certificate is similar to defining a TGenshi template.
   Under your Bcfg2's SSLCA directory, create the directory structure to match the
   path to your key. In this case this would be something like
   ``/var/lib/bcfg2/SSLCA/etc/pki/tls/private/localhost.key``.

#. Within that directory, create a ``key.xml`` file containing the following:

   .. code-block:: xml

       <KeyInfo>
           <Key type="rsa" bits="2048" />
       </KeyInfo>

#. This will cause the generation of an 2048 bit RSA key when a client requests
   that Path.  Alternatively you can specify ``dsa`` as the keytype, or a different
   number of bits.

#. Similarly, create the matching directory structure for the certificate path,
   and a ``cert.xml`` containinng the following:

   .. code-block:: xml

       <CertInfo>
           <Cert format="pem" key="/etc/pki/tls/private/localhost.key" ca="default" days="365" c="US" l="New York" st="New York" o="Your Company Name" />
       </CertInfo>

#. When a client requests the cert path, a certificate will be generated using
   the key hostfile at the specified key location, using the CA matching the ca
   attribute. ie. ca="default" will match [sslca_default] in your
   ``/etc/bcfg2.conf``

Automated Bcfg2 SSL Authentication
==================================

This section describes one possible scenario for automating ssl
certificate generation and distribution for bcfg2 client/server
communication using SSLCA. The process involves configuring a certificate
authority (CA), generating the CA cert and key pair, configuring the
bcfg2 SSLCA plugin and a Bundle to use the SSLCA generated certs to
authenticate the bcfg2 client and server.

OpenSSL CA
----------

If you already have a SSL CA available you can skip this section,
otherwise you can easily build one on the server using openssl. The
paths should be adjusted to suite your preferences.

#. Prepare the directories and files. ::

    mkdir -p /etc/pki/CA/newcerts
    mkdir /etc/pki/CA/crl
    echo '01' > /etc/pki/CA/serial
    touch /etc/pki/CA/index.txt
    touch /etc/pki/CA/crlnumber

#. Edit the ``openssl.cnf`` config file, and in the **[ CA_default ]**
   section adjust the following parameters. ::

    dir         = /etc/pki          # Where everything is kept
    certs       = /etc/pki/CA/certs     # Where the issued certs are kept
    database    = /etc/pki/CA/index.txt # database index file.
    new_certs_dir   = /etc/pki/CA/newcerts      # default place for new certs.
    certificate = /etc/pki/CA/certs/bcfg2ca.crt     # The CA certificate
    serial      = /etc/pki/CA/serial        # The current serial number
    crl_dir     = /etc/pki/CA/crl           # Where the issued crl are kept
    crlnumber   = /etc/pki/CA/crlnumber # the current crl number
    crl     = /etc/pki/CA/crl.pem       # The current CRL
    private_key = /etc/pki/CA/private/bcfg2ca.key # The private key

#. Create the CA root certificate and key pair. You'll be asked to
   supply a passphrase, and some organizational info. The most important
   bit is **Common Name** which you should set to be the hostname of
   your bcfg2 server that your clients will see when doing a reverse
   DNS query on it's ip address. ::

    openssl req -new -x509 -extensions v3_ca -keyout bcfg2ca.key -out bcfg2ca.crt -days 3650

#. Move the generated cert and key to the locations specified in ``openssl.cnf``. ::

    mv bcfg2ca.key /etc/pki/CA/private/
    mv bcfg2ca.crt /etc/pki/CA/certs/

Your self-signing CA is now ready to use. 

Bcfg2
-----

SSLCA
^^^^^

The SSLCA plugin was not designed specifically to manage bcfg2
client/server communication though it is certainly able to provide
certificate generation and management services for that purpose. You'll
need to configure the **SSLCA** plugin to serve the key, and certificate
paths that we will define later in our client's ``bcfg2.conf`` file.

The rest of these instructions will assume that you've
configured the **SSLCA** plugin as described above and that the
files ``SSLCA/etc/pki/tls/certs/bcfg2client.crt/cert.xml`` and
``SSLCA/etc/pki/tls/private/bcfg2client.key/key.xml`` represent the cert
and key paths you want generated for SSL auth.

Client Bundle
^^^^^^^^^^^^^

To automate the process of generating and distributing certs to the
clients we need define at least the Cert and Key paths served by the
SSLCA plugin, as well as the ca certificate path in a Bundle. For example:

    .. code-block:: xml

        <Path name='/etc/pki/tls/certs/bcfg2ca.crt'/>
        <Path name='/etc/pki/tls/bcfg2client.crt'/>
        <Path name='/etc/pki/tls/private/bcfg2client.key'/>

Here's a more complete example bcfg2-client bundle: 

    .. code-block:: xml

        <Bundle name='bcfg2-client'>
           <Path name='/etc/bcfg2.conf'/>
           <Path name='/etc/cron.d/bcfg2-client'/>
           <Package name='bcfg2'/>
           <Service name='bcfg2'/>
           <Group name='rpm'>
               <Path name='/etc/sysconfig/bcfg2'/>
               <Path name='/etc/pki/tls/certs/bcfg2ca.crt'/>
               <Path name='/etc/pki/tls/certs/bcfg2client.crt'/>
               <Path name='/etc/pki/tls/private/bcfg2client.key'/>
           </Group>
           <Group name='deb'>
               <Path name='/etc/default/bcfg2' altsrc='/etc/sysconfig/bcfg2'/>
               <Path name='/etc/ssl/certs/bcfg2ca.crt' altsrc='/etc/pki/tls/certs/bcfg2ca.crt'/>
               <Path name='/etc/ssl/certs/bcfg2client.crt' altsrc='/etc/pki/tls/certs/bcfg2client.crt'/>
               <Path name='/etc/ssl/private/bcfg2client.key' altsrc='/etc/pki/tls/private/bcfg2client.key'/>
           </Group>
        </Bundle>

In the above example we told Bcfg2 that it also needs to serve
``/etc/bcfg2.conf``. This is optional but convenient.

The ``bcfg2.conf`` client config needs at least 5 parameters set for SSL auth. 

#. ``key`` : This is the host specific key that SSLCA will generate.
#. ``certificate`` : This is the host specific cert that SSLCA will
   generate.
#. ``ca`` : This is a copy of your CA certificate. Not generated by SSLCA.
#. ``user`` : Usually set to fqdn of client. This *shouldn't* be required
   but is as of 1.2rc2. see: http://trac.mcs.anl.gov/projects/bcfg2/ticket/1019
#. ``password`` : Set to arbitrary string when using
   certificate auth. This also *shouldn't* be required. see:
   http://trac.mcs.anl.gov/projects/bcfg2/ticket/1019

Here's what a functional **[communication]** section in a ``bcfg2.conf``
genshi template for clients might look like.::

   [communication]
   protocol = xmlrpc/ssl
   {% if metadata.uuid != None %}\
   user = ${metadata.uuid}
   {% end %}\
   password = DUMMYPASSWORDFORCERTAUTH
   {% choose %}\
   {% when 'rpm' in metadata.groups %}\
   certificate = /etc/pki/tls/certs/bcfg2client.crt
   key = /etc/pki/tls/private/bcfg2client.key
   ca = /etc/pki/tls/certs/bcfg2ca.crt
   {% end %}\
   {% when 'deb' in metadata.groups %}\
   certificate = /etc/ssl/certs/bcfg2client.crt
   key = /etc/ssl/private/bcfg2client.key
   ca = /etc/ssl/certs/bcfg2ca.crt
   {% end %}\
   {% end %}\

As a client will not be able to authenticate with certificates it does
not yet posses we need to overcome the chicken and egg scenario the
first time we try to connect such a client to the server. We can do so
using password based auth to boot strap the client manually specifying
all the relevant auth parameters like so::

   bcfg2 -qv -S https://fqdn.of.bcfg2-server:6789 -u fqdn.of.client -x SUPER_SECRET_PASSWORD

If all goes well the client should recieve a freshly generated key and
cert and you should be able to run ``bcfg2`` again without specifying
the connection parameters.

If you do run into problems you may want to review
:ref:`appendix-guides-authentication`.

TODO
====

#. Add generation of pkcs12 format certs