summaryrefslogtreecommitdiffstats
path: root/doc/server/encryption.txt
blob: db5e2ae2929e69770cc5c5a6c5720e68e70c2eab (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
.. -*- mode: rst -*-
.. vim: ft=rst

.. _server-encryption:

=====================
Bcfg2 Data Encryption
=====================

.. versionadded:: 1.3.0

Bcfg2 supports encrypting some data on the disk, which can help
protect sensitive data from other people who need access to the Bcfg2
repository but are perhaps not authorized to see all data.  It
supports multiple passphrases, which can be used to enforce
separations between teams, environments, etc.  Use of the encryption
feature requires M2Crypto 0.18 or newer.

.. note::

    This feature is *not* intended to secure the files against a
    malicious attacker who has gained access to your Bcfg2 server, as
    the encryption passphrases are held in plaintext in
    ``bcfg2.conf``.  This is only intended to make it easier to use a
    single Bcfg2 repository with multiple admins who should not
    necessarily have access to each other's sensitive data.

Two basic types of data can be encrypted:

* :ref:`server-plugins-generators-cfg` files can be encrypted
  as whole files. See :ref:`server-plugins-generators-cfg-encryption`
  for more details.
* :ref:`server-plugins-connectors-properties` data can be encrypted on
  a per-element basis.  See
  :ref:`server-plugins-connectors-properties-encryption` for more
  details.

In general, Properties encryption is preferred for a few reasons:

* It plays nicely with your VCS.  If you change an encrypted Cfg file,
  then all you can see in your VCS log is that the file changed, no
  details about how it changed.  With an encrypted Properties file,
  you can see which element changed (although obviously not the
  changed content).
* It is faster when you have more than one passphrase.  When
  decrypting a Cfg file, Bcfg2 simply brute-forces it with all known
  passphrases; when decrypting a Properties element, the passphrase is
  given by name so only one passphrase must be tried.
* A Cfg file can only be encrypted with a single passphrase;
  Properties files can use different passphrases for different
  elements.  If you are using different passphrases to segregate data
  amongst different teams, this lets teams collaborate more closely on
  files and other data.

Other types of data that can be encrypted are:

* Text content of Path tags in
  :ref:`server-plugins-structures-bundler`
* Passphrases in XML description files for generated
  :ref:`server-plugins-generators-cfg-sshkeys`

.. _bcfg2-crypt:

bcfg2-crypt
===========

Encrypting and decrypting :ref:`server-plugins-generators-cfg` and
:ref:`server-plugins-connectors-properties` files can be done with the
``bcfg2-crypt`` tool, which mostly tries to do the right thing.  I.e.,
it encrypts plaintext files, decrypts encrypted files, and
automatically discovers if a file is Cfg or Properties.  Its usage is
thus generally very simple, e.g.::

    bcfg2-crypt foo.conf
    bcfg2-crypt foo.xml

Since the behavior of ``bcfg2-crypt`` varies significantly depending
on whether you are dealing with a Cfg or Properties files, these are
documented separately below.  It's also well worthwhile to familiarize
yourself with the man page for ``bcfg2-crypt``.

Encrypting Cfg Files
--------------------

To encrypt a Cfg file, you can simply run::

    bcfg2-crypt foo.conf

This will write the encrypted data to ``foo.conf.crypt``.  Once you
are satisfied that the file has been encrypted as you wish, you can
remove the plaintext version, or you can use the ``--remove`` flag of
``bcfg2-crypt``.

To decrypt a file, simply run ``bcfg2-crypt`` again::

    bcfg2-crypt foo.conf.crypt

On Cfg files, ``bcfg2-crypt`` is more-or-less equivalent to the
following commands (encryption and decryption, respectively)::

    openssl enc -aes-256-cbc -k <passphrase> -in foo.conf \
        -out foo.conf.crypt -a
    openssl enc -d -aes-256-cbc -k <passphrase> -in foo.conf.crypt \
        -out foo.conf -a

Those commands can be used in lieu of ``bcfg2-crypt`` if you hate
convenience.

Encrypting Properties Files
---------------------------

To encrypt or decrypt a properties file, simply run::

    bcfg2-crypt foo.xml

If the top-level tag of a Properties file is not ``<Properties>``,
then you need to use the ``--properties`` flag to ``bcfg2-crypt``::

    bcfg2-crypt --properties foo.xml

The first time you run ``bcfg2-crypt`` on a Properties file, it will
encrypt all character data of all elements.  Additionally, it will add
``encrypted="<key name>"`` to each element that has encrypted character
data.  It also adds ``encryption="true"`` to the top-level
``<Properties>`` tag as a flag to the server that it should try to
decrypt the data in that file.  (If you are using Properties schemas,
you will need to make sure to add support for these attributes.)  On
subsequent runs, only those elements flagged with ``encrypted="*"``
are encrypted or decrypted.

To decrypt a Properties file, simply re-run ``bcfg2-crypt``::

    bcfg2-crypt foo.xml

This decrypts the encrypted elements, but it does *not* remove the
``encrypted`` attribute; this way, you can decrypt a Properties
file, modify the contents, and then simply re-run ``bcfg2-crypt`` to
encrypt it again.  If you added elements that you also want to be
encrypted, you can either add the ``encrypted`` attribute to
them manually, or run::

    bcfg2-crypt --xpath '*' foo.xml

You can also use the ``--xpath`` option to specify more restrictive
XPath expressions to only encrypt a subset of elements, or to encrypt
different elements with different passphrases.  Alternatively, you can
manally set the ``encrypted`` attribute on various elements and
``bcfg2-crypt`` will automatically do the right thing.  You can also
run bcfg2-crypt in interactive mode to interactively select which
attributes should be encrypted::

    bcfg2-crypt -I foo.xml

If you want to use different passphrases within a single Properties
file, you must manually set the ``encrypted`` attribute.

.. _server-encryption-configuration:

Configuring Encryption
======================

Passphrases
-----------

To configure encryption, add a ``[encryption]`` section to
``bcfg2.conf`` with any number of name-passphrase pairs.

For instance::

    [encryption]
    foo_team=P4ssphr4se
    bar_team=Pa55phra5e

.. note::

    The name of a passphrase **cannot** be ``algorithm`` or
    ``decrypt``, which are reserved for other configuration options.

This would define two separate encryption passphrases, presumably for
use by two separate teams.  The passphrase names are completely
arbitrary.

Note that this does entail a chicken-and-egg problem.  In order for
the Bcfg2 server to be able to decrypt encrypted files, the
passphrases must exist in ``bcfg2.conf`` in plaintext; but, if you're
encrypting data, presumably you don't want to include those plaintext
passphrases in your Bcfg2 repository, so you'll want to encrypt
``bcfg2.conf``.  The best way to solve this is:

#. On your Bcfg2 server, manually add the ``[encryption]`` section to
   ``bcfg2.conf`` and restart the Bcfg2 server.
#. Update ``bcfg2.conf`` in your Bcfg2 repository with the
   passphrases, and encrypt it.

The first (manual) step breaks the mutual dependency.

Algorithm
---------

By default, Bcfg2 uses the AES-256-CBC cipher algorithm.  If you wish
to change this, you can set the ``algorithm`` option in the
``[encryption]`` section of ``bcfg2.conf``::

    [encryption]
    algorithm = bf_cbc

The value of ``algorithm`` must be a valid OpenSSL cipher algorithm
according the naming model of the Python :mod:`M2Crypto` module.  To
get a list of valid algorithms, you can run::

    openssl list-cipher-algorithms | grep -v ' => ' | \
        tr 'A-Z-' 'a-z_' | sort -u

.. _server-encryption-lax-strict:

Lax vs. Strict decryption
-------------------------

By default, Bcfg2 expects to be able to decrypt every encrypted
datum.  Depending on how encryption is implemented at your site,
though, that may not be possible.  (For instance, if you use
encryption to protect data for your production environment from your
staging Bcfg2 server, then you would not expect the staging server to
be able to decrypt everything.)  In this case, you want to enable lax
decryption in the ``[encryption]`` section of ``bcfg2.conf``::

    [encryption]
    decrypt = lax

This causes a failed decrypt to produce a warning only, not an error.

This can be overridden by individual XML files by setting
``decrypt="strict"`` on the top-level tag (or, vice-versa; if strict
is the default an XML file can specify ``decrypt="lax"``.

Note that you could, for instance, set lax decryption by default, and
then set strict decryption on individual files.

Encryption API
==============

.. automodule:: Bcfg2.Server.Encryption