{"id":19418,"date":"2023-08-23T09:23:52","date_gmt":"2023-08-23T13:23:52","guid":{"rendered":"https:\/\/qxf2.com\/blog\/?p=19418"},"modified":"2023-09-05T06:38:46","modified_gmt":"2023-09-05T10:38:46","slug":"auditing-os-level-resources-with-chef-inspec-beginners-guide","status":"publish","type":"post","link":"https:\/\/qxf2.com\/blog\/auditing-os-level-resources-with-chef-inspec-beginners-guide\/","title":{"rendered":"Auditing OS level resources with Chef InSpec"},"content":{"rendered":"<p>Many of <a href=\"https:\/\/qxf2.com\/?utm_source=Chef%20InSpec_os_level_resource_auditing&#038;utm_medium=click&#038;utm_campaign=From%20blog\" rel=\"noopener\" target=\"_blank\">Qxf2<\/a>&#8216;s clients store their Infrastructure as Code. This means that new infrastructure is spun using code and then the application is deployed. So, as testers, we now have to verify that the right infrastructure was spun up and configured correctly. In this post, I will show you how to use <a href=\"https:\/\/docs.chef.io\/inspec\/\" rel=\"noopener\" target=\"_blank\">Chef InSpec<\/a> &#8211; a tool to write tests for your infrastructure. It will help you catch annoying errors like misconfigurations, dead services, etc.  <\/p>\n<h3>1.Introduction<\/h3>\n<p>Chef InSpec is an open source framework tool used for testing and auditing applications and infrastructure. The tool:<\/p>\n<p>a) compares the actual state of the system with desired state<br \/>\nb) validates configurations and behaviour of your systems<br \/>\nc) identifies compliance and security violations<br \/>\nd) generates a detailed report for further analysis and action<\/p>\n<p>The good news is that Chef InSpec is easy to pick up. It offers a rich collection of ready-to-use resources, and also you can write custom code to extend it.<\/p>\n<h3>2.Purpose of this post<\/h3>\n<p>The decision to write this post on the Chef InSpec tool, is to cater to testers who are eager to learn how to <a href=\"https:\/\/qxf2.com\/blog\/testing-infrastructure-as-code-beginner\/\" rel=\"noopener\" target=\"_blank\">test infrastructure<\/a>, especially when it is stored as code. In a previous client project, I utilized Chef InSpec to test deployments by the TestOps team. However, my ability to delve deeply into test creation was limited at that time, due to limited access to resources. This limitation has motivated me to explore this tool further and to share my acquired knowledge. <\/p>\n<p>I will cover testing a server that has been setup with an application in this post. We do this with something called <a href=\"https:\/\/docs.chef.io\/inspec\/resources\/\" rel=\"noopener\" target=\"_blank\">OS resources<\/a>. In a following post, I will delve into testing the configuration of AWS resources. These sequential discussions are primarily intended for beginners who possess an interest in familiarizing themselves with the Chef InSpec tool.<\/p>\n<hr\/>\n<h3>3.Setup<\/h3>\n<p>Users can <a href=\"https:\/\/docs.chef.io\/inspec\/install\/\" rel=\"noopener\" target=\"_blank\">download<\/a> Chef InSpec from the official website and choose between Operating Systems of MacOS, Windows, and Linux.<\/p>\n<h6>3.1 MacOS:<\/h6>\n<p>It is available as a standalone Homebrew package. Run the following command.<\/p>\n<pre lang=\"inspec\">brew install chef\/chef\/inspec<\/pre>\n<h6>3.2 CLI:<\/h6>\n<p>You can download using curl script. Run the following command.<\/p>\n<pre lang=\"inspec\">curl https:\/\/omnitruck.chef.io\/install.sh | sudo bash -s -- -P inspec<\/pre>\n<h6>3.3 Windows:<\/h6>\n<p>Download the latest package and click the <strong>.msi<\/strong> file to launch the installer and follow the prompts.<\/p>\n<h6>3.4 Linux:<\/h6>\n<p>The following command used to install it on Ubuntu and Red Hat Enterprise Linux.<\/p>\n<pre lang=\"inspec\">curl https:\/\/omnitruck.chef.io\/install.sh | sudo bash -s -- -P inspec <\/pre>\n<hr \/>\n<h3>4.Keywords<\/h3>\n<p>In the next sections, you will encounter the following technical words: <em>controls<\/em>, <em>resource<\/em> and <em>profiles<\/em>. Here is an inaccurate but useful mental-model for these words:<\/p>\n<p>a) resource: &#8220;infrastructure&#8221; we want our tests to interact with. Example: OS, AWS, GCP, Azure, etc.<br \/>\nb) controls: a directory where our tests go<br \/>\nc) profile: helps you organize and partition your tests at a higher level (example: one profile per app, or profile per service and so on)<\/p>\n<p>Additionally, each profile will be associated with a <code> inspec.yml<\/code> file that stores the meta-information about the profile.<\/p>\n<h3>5.Profiles<\/h3>\n<p>Profiles play an important role in Chef InSpec as it encompasses a collection of controls, with each control representing individual tests targeting specific system aspects. The Chef InSpec profile maintains a standalone structure that necessitates the inclusion of both the <code>inspec.yml<\/code> a metadata file and the <code>controls folder<\/code>. Both are mandatory.<br \/>\n-The <code>inspec.yml<\/code> metadata file gives information about the profile. While only the Name field is mandatory, all other profile settings are optional. It is possible to specify the targeted platform (example: Ubuntu) for running tests within this file. Additionally, one can list all the dependencies required for the tests. The path from which the profile is accessible can also be defined; this could be a local path, a URL (HTTP\/HTTPS), or a Git repository.<br \/>\n-The Controls folder is where you store all your tests. By default, it contains a sample test file created during the profile creation. To initiate the creation of a new profile, execute the command below.<\/p>\n<h6>Command to create standard profile:<\/h6>\n<pre lang=\"chef\">inspec init profile test_profile\r\n<\/pre>\n<p> This command will create a new profile named <strong>test_profile<\/strong> with default structure.<\/p>\n<h6>Command to verify the profile creation:<\/h6>\n<pre lang=\"chef\">inspec check [profile_name] \r\n<\/pre>\n<p> When run against profile, it will pop up errors, warnings if any<\/p>\n<hr \/>\n<h3>6.Test to verify OS resources<\/h3>\n<p>The following section describes the syntax and shows some simple examples of using Chef InSpec&#8217;s OS resources. It would be nice if you could follow along and practice against some server that you work with. The Chef InSpec language is Ruby DSL(domain-specific languages) for writing audit controls, which includes audit resources. As testers we need to write tests for Infrastructure as Code.<\/p>\n<h5>6.1 File resource:<\/h5>\n<p>We sometimes want to make sure that certain files exist (or do not exist) after a deploy. Using <code>File<\/code> Chef InSpec auditing resource to test system file types including directories, symbolic links.<br \/>\nExample: Test if a configuration file exists and has specific permissions.<\/p>\n<pre lang=\"ruby\">describe file('\/etc\/hosts') do\r\n  it { should exist }\r\n  it { should be_readable.by('owner') }\r\nend\r\n<\/pre>\n<p>I will try to explain the code using <a href=\"https:\/\/docs.chef.io\/inspec\/glossary\/\" rel=\"noopener\" target=\"_blank\">Chef InSpec glossary<\/a>.<br \/>\nEach line within the resource block begins with <strong>&#8220;it&#8221;<\/strong> and is used to access resource-specific matchers like <code>{ should exist }<\/code> . Matcher <code>{ should be_readable }<\/code> tests if the existing file is readable. The Matchers perform the actual assertion against resource or the properties of the resource.<\/p>\n<hr\/>\n<h5>6.2 Package resource:<\/h5>\n<p>Package resource holds significance to confirm the installation of specific packages and validate their corresponding versions. This task can be accomplished through the utilization of the <code>package<\/code> auditing resource.<br \/>\nExample: Test the package &#8216;nginx&#8217; is installed and its version using the <code>package<\/code> resource.<\/p>\n<pre lang=\"ruby\">describe apt('nginx') do\r\n  it { should be_installed }\r\n  its('version') { should eq '1.9.5' }\r\nend\r\n<\/pre>\n<hr\/>\n<h5>6.3 Docker container resource:<\/h5>\n<p>Testing of the existence and operational state of a deployed Docker image is vital. <code>docker_container<\/code> auditing resource can be used to validate this.<br \/>\nExample: Test if a specific docker container is running.<\/p>\n<pre lang=\"ruby\">describe docker_container('myapp') do\r\n  it { should exist }\r\n  it { should be_running }\r\nend\r\n<\/pre>\n<hr\/>\n<h5>6.4 HTTP resource:<\/h5>\n<p><code>http<\/code> auditing resource can be used to perform a health check before commencing testing of the web application.<br \/>\nExample:Test if specific domain is accessible and returns a specific status code.<\/p>\n<pre lang=\"ruby\">describe http('http:\/\/example.com') do\r\n  its('status') { should cmp 200 }\r\nend\r\n<\/pre>\n<p>A universal matcher is a matcher that can be used on the properties of a resource. Universal matchers are always used with the &#8220;its&#8221; keyword. In this example used against a property of a resource. &#8220;cmp&#8221; matcher is used to check the value of the properties.<\/p>\n<hr \/>\n<h5>6.5 Nginx resource:<\/h5>\n<p>Nginx, an open-source web server software, is commonly utilized for hosting applications. Validating the availability of Nginx is significant. This can be achieved by using <code>nginx<\/code> auditing resource.<br \/>\nExample: Test Nginx service is running and enabled.<\/code><\/code><\/p>\n<pre lang=\"ruby\">describe service('nginx') do\r\n  it { should be_enabled }\r\n  it { should be_running }\r\nend\r\n<\/pre>\n<hr \/>\n<h5>6.6 Passwd resource:<\/h5>\n<p>Using the <code>passwd<\/code> auditing resource allows you to test the contents of the <strong>&#8216;\/etc\/passwd&#8217;<\/strong> file.<br \/>\nExample: test if \u2018root\u2019 and \u2018www-data\u2019 users exist and count is  equal to one.<\/p>\n<pre lang=\"ruby\">describe passwd.uids(0) do\r\n    its('users') { should cmp 'root' }\r\n    its('count') { should eq 1 }\r\nend\r\ndescribe passwd.where { user == 'www-data' } do\r\n    its('uids') { should cmp 33 }\r\n    its('count') { should eq 1 }\r\nend\r\n<\/pre>\n<hr \/>\n<h5>6.7 Service resource:<\/h5>\n<p>When testing Infrastructure, it is essential to assess the status of the services. The service auditing resource serves this purpose by enabling the testing of specific services for installation, running status, and activation. In few cases, to verify specific service manager by using one of the service manager specific resources like &#8220;systemd_resource&#8221;, &#8220;launchd_service&#8221;.<br \/>\nExample: test if mysql systemd service and prometheus launchd service are installed, enabled and in running status.<\/p>\n<pre lang=\"ruby\">describe systemd_service('MYSQL') do\r\n    it { should_not be_enabled }\r\n    it { should_not be_installed }\r\n    it { should_not be_running }\r\nend\r\ndescribe launchd_service('prometheus') do\r\n    it { should_not be_enabled }\r\n    it { should_not be_installed }\r\n    it { should_not be_running }\r\nend\r\n<\/pre>\n<hr \/>\n<h6>Command to execute Chef InSpec test:<\/h6>\n<pre lang=\"inspec\">\r\ninspec exec  [profile_name]\r\n<\/pre>\n<h6>Sample run of service resource test:<\/h6>\n<p><img decoding=\"async\" src=\"https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2023\/08\/chefinspec_os_resource_blog.png\" alt=\"Chef InSpec test output\" \/><\/p>\n<hr \/>\n<p>To wrap up this post, Chef InSpec is a good tool to test compliance and security of the infrastructure. I like it\u2019s user-friendly syntax. It not only lets us use predefined resources out of the box. But it also allows us to customize the resources and extend them. My intention is to inspire each one of you to take into the world of testing infrastructure using Chef Inspec. Let&#8217;s have more secure, reliable, and compliant infrastructure with Chef InSpec!<\/p>\n<hr>\n<h3>Hire technical testers from Qxf2<\/h3>\n<p>Hire <a href=\"https:\/\/qxf2.com\/?utm_source=Chef%20InSpec_os_level_resource_auditing&#038;utm_medium=click&#038;utm_campaign=From%20blog\">Qxf2<\/a> testers for testing your infrastructure. Our testers possess deep technical expertise and practical experience in testing modern technical stacks. Gain access to skilled testers who can navigate the intricacies of Infrastructure as Code by partnering with Qxf2.<\/p>\n<hr>\n<h3>References:<\/h3>\n<p><a href=\"https:\/\/docs.chef.io\/inspec\/\">https:\/\/docs.chef.io\/inspec\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Many of Qxf2&#8216;s clients store their Infrastructure as Code. This means that new infrastructure is spun using code and then the application is deployed. So, as testers, we now have to verify that the right infrastructure was spun up and configured correctly. In this post, I will show you how to use Chef InSpec &#8211; a tool to write tests [&hellip;]<\/p>\n","protected":false},"author":37,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[367,380,316],"tags":[],"class_list":["post-19418","post","type-post","status-publish","format-standard","hentry","category-chef-inspec","category-iac","category-infrastructure"],"_links":{"self":[{"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/posts\/19418","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/users\/37"}],"replies":[{"embeddable":true,"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/comments?post=19418"}],"version-history":[{"count":123,"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/posts\/19418\/revisions"}],"predecessor-version":[{"id":20048,"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/posts\/19418\/revisions\/20048"}],"wp:attachment":[{"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/media?parent=19418"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/categories?post=19418"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/tags?post=19418"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}