Bcfg2 Data Encryption¶
New in version 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:
- Cfg files can be encrypted as whole files. See Encrypted Files for more details.
- Properties data can be encrypted on a per-element basis. See Encrypted Properties data 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:
bcfg2-crypt¶
Encrypting and decrypting Cfg and
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.
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 tobcfg2.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 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
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]
lax_decryption = true
This causes a failed decrypt to produce a warning only, not an error.
This can be overridden by individual XML files by setting
lax_decryption="false"
on the top-level tag (or, vice-versa; if
strict is the default an XML file can specify
lax_decryption="true"
.
Note that you could, for instance, set lax decryption by default, and then disable it on individual files.