Modify Opscode's Postfix Cookbook to Use an Encrypted Data Bag - nshenry03/chef-repo GitHub Wiki

From Joshua Timberman's Encrypted Data Bag for Postfix SASL Authentication post.

To begin, I forked Opscode's Postfix Cookbook and then cloned it to a directory on my machine where I work on cookbooks (outside of the chef repository). I then added the original repository as another remote named 'upstream' so that I can keep track of the original repository: git remote add upstream [email protected]:opscode-cookbooks/postfix.git.

Okay, on to editing the code...


First I modify the metadata.rb. I change the 'maintainer' and 'maintainer_email' settings (since we will be responsible for keeping up with Opscode's updates and we will be responsible for any code that we add). I then change README.md to document that this cookbook was forked from

I follow Josh's post and create a secret key:

openssl rand -base64 512 > .chef/encrypted_data_bag_secret

Next, I created the actual data bag.

knife data bag create encrypted_data_bags

Next I created the data bag item using the secret key. This is created directly on the Chef Server, rather than a plain text file (see next steps for file contents).

knife data bag create encrypted_data_bags postfix --secret-file ~/.chef/encrypted_data_bag_secret

I’m not saving the plaintext data bag item, but will store the encrypted item, so I’ll retrieve it from the Chef Server and redirect the output to a JSON file.

mkdir data_bags/encrypted_data_bags
knife data bag show encrypted_data_bags postfix -Fj > data_bags/encrypted_data_bags/postfix.json

Contents of data_bags/encrypted_data_bags/postfix.json:

{
  "id": "postfix",
  "production" : {
    "user": "encrypted string here",
    "passwd": "encrypted string here"
  },
  "staging" : {
    "user": "encrypted string here",
    "passwd": "encrypted string here"
  },
  "test" : {
    "user": "encrypted string here",
    "passwd": "encrypted string here"
  },
  "development" : {
    "user": "encrypted string here",
    "passwd": "encrypted string here"
  },
  "_default" : {
    "user": "encrypted string here",
    "passwd": "encrypted string here"
  }
}

The current recipe doesn’t support using an encrypted data bag item, so I had to modify it. First, load the encrypted data bag item.

smtp_sasl = encrypted_data_bag_item("encrypted_data_bags", "postfix")

This access the "encrypted_data_bags" data bag for the "postfix" item, and uses the default value for the secret key file (which is “/etc/chef/encrypted_data_bag_secret”.

Next, I update the sasl_passwd template to pass in the user and password from the data bag item.

template "/etc/postfix/sasl_passwd" do
  #...
  variables(
    :smtp_sasl_passwd => smtp_sasl[node.chef_environment]['passwd'],
    :smtp_sasl_user_name => smtp_sasl[node.chef_environment]['user']
  ) 
  #...
end

Then, update the sasl template to use the new values:

<%= node[:postfix][:relayhost] %> <%= @smtp_sasl_user_name %>:<%= @smtp_sasl_passwd %>

Finally, we want to modify the cookbook to support the 'smtp_tls_security_level' configuration option...

In attributes/default.rb, add the following line (under 'smtp_tls_cafile'):

default['postfix']['smtp_tls_security_level'] = ""

In templates/default/main.cf.erb, add the following line (under 'smtp_tls_cafile'):

smtp_tls_security_level = <%= node['postfix']['smtp_tls_security_level'] %>

NOTE: You can see the changes I've made by cloning my postfix repo and running the following:

git diff '3d18ce0e397a5dfb996848c9db44e0e794b332f8' '2.1.7'