Introduction
Deploying sensitive data with Chef and storing passwords in cookbooks leavs you and your system open to attack. Best option is to remove data from the cookbooks itself as it will remove opportunity fot it to be discovered.
In this article, we will be focusing on using knife to create, read and write databags, which are typically used to store and deploy sensitive data outside of a version control system.
Create Cookbook
Before we start we have to create cookbook
Storing Data in Bags
A data bag is global variable that is stored as JSON data and it’s accesible from a Chef server. A data bag is indexed for searching.
Data bag example:
{
"id" : "unique_value"
"name": "Emin"
"surname": "Dedic"
"password": "thisismypassword"
}
Data Bag Configuration
I’m going to write how to create, edit, delete and show Data Bags and its Items.
Create Data Bag
We are going to create data bag locally named data_for_bag.json
Create data bag with create
argument to add a data bag to the Chef server.
$ knife data bag create account_bag
We will upload items to data beg from file that we made:
$ knife data bag from file account_bag ./mail_data.json
Output:
Updated data_bag_item[account_bag::mail]
Edit Data Bag
For using knife edit command we need to provide editor. If you didn’t configurate it you need to add text editor that will be used by knife. For example, to configure knife to open the nano text editor, add the following to your knife.rb file:
knife[:editor] = "/usr/bin/nano"
Edit out databag
$ EDITOR=nano knife data bag edit account_bag mail
Delete Data Bag
We have to use delete
argument to delete data bag and item from Chef server:
$ knife data bag delete account_bag
Show the Data Bag Items
To verify this worked, we can verify the databag exists:
$ knife data bag list
…and then view its contents:
$ knife data bag show account_bag
Output: mail
Chek mail secret:
$ knife data bag show account_bag mail
Output:
id: mail
account: [email protected]
password: eydujahy3u78ddj
Now, our cookbook can use this information during a chef run!
Inserting Data Bag Item Value into a Chef Recipe
We are going to use data bag data for mail notifications for monit on our server:
Loading data into Chef recepie:
# Made variable with data_bag_item method
mail_account = data_bag_item('account_bag', 'mail')
template "/etc/monit/conf.d/mail" do
source "monit/mail.erb"
owner "root"
group "root"
mode 00755
verify "monit -t -c %{path}"
notifies :reload, 'service[monit]', :immediately
# Put to variables
variables(
username: mail_account['account'],
password: mail_account['password']
)
end
And then loading it into mail template:
set mailserver webmail.mailserver.org port 587
# Adding variables from mail.rb recepie
username "<%= @username %>" password "<%= @password %>"
using tlsv1
with timeout 30 second
After doing this things, our data is still exposed on chef server or our version control account.
Encrypting in Data Bag
A data bag item may be encrypted using sharen secret encryption. This allows each data bag item to store confidental informations (in our case, for example account password).
Create Secret Key for Encryption
We have to take data bag item and encrypt it with shared secret.
First of all we have to create a shared secret. Let’s secure data in bag using openssl:
$ openssl rand -base64 512 | tr -d '\r\n' > my_secret
Encrypt Our Existing Data Bag
Encrypt Data Bag from created my_secret
file:
$ knife data bag from file account_bag ./mail_data.json --secret-file my_secret
If you wnat show item value and specify the secret-file
on the command line, you’ll get the original values back.
$ knife data bag show encrypted mail --secret-file my_secret
Copy Shared Secret to Node
After this, we have to copy out my_secret
file to server and named file encrypted_data_bag_secret
file.
$ scp my_secret [email protected]:/etc/chef/encrypted_data_bag_secret
And, we don’t have to change anything in recepie for mail account, becouse Chef client will look to Data Beg item, find secret on server and decrypt an informations.
Using this approach, it is possible to store sensitive data directly in the repo without exposing those credentials to the wrong individuals.
Now, the secret is available to only the nodes and workstations that have the shared secret.