{"id":44410,"date":"2016-12-27T18:15:00","date_gmt":"2016-12-27T12:45:00","guid":{"rendered":"http:\/\/www.tothenew.com\/blog\/?p=44410"},"modified":"2016-12-28T12:14:20","modified_gmt":"2016-12-28T06:44:20","slug":"securing-chef-resources-using-databags","status":"publish","type":"post","link":"https:\/\/www.tothenew.com\/blog\/securing-chef-resources-using-databags\/","title":{"rendered":"Securing Chef Resources Using Databags"},"content":{"rendered":"<p>Configuration management has become a prominent part of DevOps practices. Either be it a matured <a title=\"DevOps Tools\" href=\"http:\/\/www.tothenew.com\/devops-chef-puppet-docker\">Chef and Puppet<\/a> or new entrants Ansible and SaltStack, all of them are better than another in one or other way.\u00a0 However, playing without securing them is a big security risk and is not in the veins <a title=\"DevOps as a Service\" href=\"http:\/\/www.tothenew.com\/devops-automation-consulting\">DevOps<\/a>.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"aligncenter wp-image-44415 size-full\" src=\"\/blog\/wp-ttn-blog\/uploads\/2016\/12\/Screen-Shot-2016-12-25-at-12.44.30-PM.png\" alt=\"Data Bag\" width=\"514\" height=\"159\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2016\/12\/Screen-Shot-2016-12-25-at-12.44.30-PM.png 514w, \/blog\/wp-ttn-blog\/uploads\/2016\/12\/Screen-Shot-2016-12-25-at-12.44.30-PM-300x92.png 300w\" sizes=\"(max-width: 514px) 100vw, 514px\" \/><\/p>\n<p><a title=\"Understanding Chef and Writing Cookbooks\" href=\"http:\/\/www.tothenew.com\/blog\/understanding-chef-and-writing-cookbooks\/\">Chef is the most vastly used<\/a> configuration management tool. In this blog I would be discussing chef use-cases which would help us to secure\/encrypt sensitive data such as passwords, keys, etc. in data-bags and how can we access it in recipes, templates, attributes etc. We will also discuss a use-case related to environments.<\/p>\n<p><b>Creating Data-bags:<br \/>\n<\/b>We would need to create a data-bag to encrypt the sensitive data. The below command will create a data bag on the chef server and will use default secret key to encrypt the data-bag.<\/p>\n<p>[js]knife data bag create my_databag my_databag_item [\/js]<\/p>\n<p>This would create a directory named \u201cmy_databag\u201d which is our data-bag and this directory has created a file named \u201cmy_databag_item.json\u201d which is a data-bag item.<\/p>\n<p>Let\u2019s say the \u201cplain-text\u201d content of that we want to encrypt is:<strong><br \/>\n<\/strong><\/p>\n<p>[js]{<br \/>\n\u00a0&quot;id&quot;: &quot;my_databag&quot;,<br \/>\n&quot;password1&quot;: \u201cabc123\u201d,<br \/>\n &quot;password2&quot;: \u201c123abc\u201d<br \/>\n}[\/js]<\/p>\n<p>And after encryption this file would look like:<\/p>\n<p>[js]{<br \/>\n\u00a0&quot;id&quot;: &quot;my_databag&quot;,<br \/>\n &quot;password1&quot;: {<br \/>\n\u00a0\u00a0 &quot;encrypted_data&quot;: &quot;XXXXXXXXXXXXXXXXXXXXXXXXX&quot;,<br \/>\n\u00a0\u00a0 &quot;iv&quot;: &quot;XYXYXYXYXYYXYXYXYXYXYXY&quot;,<br \/>\n\u00a0\u00a0 &quot;version&quot;: 1,<br \/>\n\u00a0\u00a0 &quot;cipher&quot;: &quot;aes-256-cbc&quot;<br \/>\n\u00a0},<br \/>\n &quot;password2&quot;: {<br \/>\n\u00a0\u00a0 &quot;encrypted_data&quot;: &quot;YYYYYYYYYYYYYYYYYYYYYYYYYY&quot;,<br \/>\n\u00a0\u00a0 &quot;iv&quot;: &quot;YXYXYXYXYXYXYXYXYXYXYXYX&quot;,<br \/>\n\u00a0\u00a0 &quot;version&quot;: 1,<br \/>\n\u00a0\u00a0 &quot;cipher&quot;: &quot;aes-256-cbc&quot;<br \/>\n\u00a0}<br \/>\n}[\/js]<\/p>\n<p>Here are few variation which we generally use:<\/p>\n<ol>\n<li>We do not want to create data-bag on chef-server but want to create a data-bag locally:\n<p>[js]knife data bag create my_databag my_databag_item &#8211;local-mode flag[\/js]<\/p>\n<\/li>\n<li>We do not want to use a default secret key but instead want to use self-created secret key:\n<p>[js]#One of the many ways to create secret key:<br \/>\nopenssl rand -base64 512 | tr -d &#8216;\\r\\n&#8217; &gt; \/path\/to\/my_secret_key<br \/>\n#Create data-bag using my_secret_key<br \/>\nknife data bag create my_databag my_databag_item &#8211;local-mode &#8211;secret-file \u00a0\/path\/to\/my_secret_key[\/js]<\/p>\n<\/li>\n<\/ol>\n<p>Now, let\u2019s see how could we use the encrypted data in recipes, templates etc.<\/p>\n<ol>\n<li><strong>Using data-bags in a recipe:<\/strong> We would first need to load the data-bag in the recipe. Before this, we should know the path of the secret file (say \/path\/to\/my_secret_key) that we have created previously.<br \/>\n#Loading secret key inside the recipe:<\/p>\n<p>[js]my_secret_key = Chef::EncryptedDataBagItem.load_secret(&quot;\/path\/to\/my_secret_key&quot;)[\/js]<\/p>\n<p>#Loading data-bag item inside the recipe:<\/p>\n<p>[js]passwords = Chef::EncryptedDataBagItem.load(&quot;my_databag&quot;, &quot;my_databag_item&quot;, my_secret_key)[\/js]<\/p>\n<p>In order to use \u201cpassword1\u201d, we can use:<\/p>\n<p><strong>Example 1<\/strong>: Below recipe is sourcing DB dump in the MySQL. While using chef variable in a big string as below, we use hash(\u201c#\u201d) followed by curly braces(\u201c{}\u201d) as highlighted\u00a0below:<\/p>\n<p>[js]bash &#8216;create readonly user&#8217; do&lt;\/pre&gt;<br \/>\nuser &#8216;mysql&#8217;<br \/>\ncwd &#8216;\/tmp&#8217;<br \/>\ncode &lt;&lt;-EOH<br \/>\nmysql -uroot -p&lt;b&gt;#{passwords[&#8216;password1&#8217;]}&lt;\/b&gt; \u00a0&lt; \/tmp\/dummy.sql<br \/>\nEOH<br \/>\nend[\/js]<\/p>\n<p><strong>Example 2:<\/strong> We can use it without \u201c#\u201d and \u201c{}\u201d when using it outside a string as below:<\/p>\n<p>[js]mysql_service &#8216;default&#8217; do&lt;\/pre&gt;<br \/>\n\u00a0version &#8216;5.6&#8217;<br \/>\n\u00a0port &#8216;3306&#8217;<br \/>\n\u00a0bind_address &#8216;0.0.0.0&#8217;<br \/>\n\u00a0initial_root_password &lt;b&gt;password[&quot;password1&quot;]<br \/>\n\u00a0action [:create, :start]<br \/>\n\u00a0not_if &#8216;ps -ef | grep [m]ysqld&#8217;<br \/>\nend[\/js]<\/p>\n<p>&nbsp;<\/li>\n<li>We have directly used the path of the secret key while loading the secret key in the above example. We can do a small improvement by storing the path of secret key inside attribute file as below (assuming we are working inside a cookbook directory).\n<p>[js]cat attributes\/default.rb&lt;\/pre&gt;<br \/>\ndefault[&quot;secret_key_path&quot;] = &quot;\/path\/to\/my_secret_key&quot;[\/js]<\/p>\n<p>We could use it inside the recipe to load secret key:<\/p>\n<p>[js]my_secret_key = Chef::EncryptedDataBagItem.load_secret(#{node[:secret_key_path]}&quot;)[\/js]<\/p>\n<p><strong>Note:<\/strong> that we have not done any encryption here. This is just an improvement over point<\/li>\n<li><strong>Using data-bags in a template:<\/strong> We can not directly use data-bags as we have used in recipes. While using templates in a recipe(which is granting a mMySQLuser some privileges), we would have to specifically pass the data-bags as variables inside a template as below:\n<p>[js]my_secret_key = Chef::EncryptedDataBagItem.load_secret(#{node[:secret_key_path]}&quot;)<br \/>\npasswords = Chef::EncryptedDataBagItem.load(&quot;my_databag&quot;, &quot;my_databag_item&quot;, my_secret_key)<br \/>\ntemplate &#8216;\/tmp\/grantPrivileges.txt&#8217; do<br \/>\n\u00a0source &quot;grantPrivileges.txt.erb&quot;<br \/>\n\u00a0owner \u00a0\u00a0&quot;root&quot;<br \/>\n\u00a0group \u00a0\u00a0&quot;root&quot;<br \/>\n\u00a0mode \u00a0\u00a0\u00a00644<br \/>\n\u00a0variables(<br \/>\n\u00a0 :passwords =&gt; passwords<br \/>\n)<br \/>\nend[\/js]<\/p>\n<p>Now, inside the template file, we can use \u201cpassword1\u201d as:<\/p>\n<p>[js]cat templates\/grantPriviliges.txt.erb&lt;\/pre&gt;<br \/>\ngrant all on dbname.* to &#8216;user1&#8217;@&#8217;%&#8217; identified by &#8216;&lt;%= @passwords[&quot;password&quot;] %&gt;&#8217;;[\/js]<\/p>\n<\/li>\n<li><strong>Playing with data-bags while working on environments:<\/strong> We usually work in multiple environments such as production, uat, qa, dev, etc. We have a set up where we have around 20 environment and all can be created\/modified using chef. The problem was that all the passwords were present in plain text in the environment file.\n<p>The task was to secure all the passwords using databags. Let\u2019s do it step-by-step as follows:<\/p>\n<ol>\n<li>Create a new data-bag \u201cenvironment\u201d.<\/li>\n<li>Under \u201cenvironment\u201d data-bag, create a data-bag item for every environment. This is how this will look:<br \/>\n<span style=\"text-decoration: underline;\">Data-bag:<\/span><br \/>\nls ..\/..\/data_bags\/environment\/<br \/>\ndev.json production.json qa.json uat.json<br \/>\n<span style=\"text-decoration: underline;\">Environment<\/span>:<br \/>\nls ..\/..\/environments\/<br \/>\ndev.json production.json qa.json uat.jsonLet\u2019s say we have three passwords inside\u201c..\/..\/environments\/production.json\u201d environment file. We would remove all the three passwords and put them inside \u201c..\/..\/data_bags\/environment\/production.json\u201d data-bag item of \u201cenvironment\u201d databag.<\/li>\n<\/ol>\n<\/li>\n<\/ol>\n<p>Later, we remove all their references from the recipes and templates.<\/p>\n<p>Next time, when to set up a new environment (say staging), we would need to create a environment file and it\u2019s corresponding data-bag item inside the environment data-bag.<\/p>\n<p>Well, these are few use-cases which could most frequently be encountered while dealing with data-bags in chef.<\/p>\n<p>Please share in comments section if anyone has a good use-case to share.<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Configuration management has become a prominent part of DevOps practices. Either be it a matured Chef and Puppet or new entrants Ansible and SaltStack, all of them are better than another in one or other way.\u00a0 However, playing without securing them is a big security risk and is not in the veins DevOps. Chef is [&hellip;]<\/p>\n","protected":false},"author":506,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"iawp_total_views":1},"categories":[1174,2348,1],"tags":[1910,1780,4343,4342,1892,4341],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/44410"}],"collection":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/users\/506"}],"replies":[{"embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/comments?post=44410"}],"version-history":[{"count":0,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/44410\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/media?parent=44410"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/categories?post=44410"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/tags?post=44410"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}