|
| 1 | ++++ |
| 2 | +title = "docker resource" |
| 3 | +draft = false |
| 4 | + |
| 5 | + |
| 6 | +[menu.docker] |
| 7 | + title = "docker" |
| 8 | + identifier = "inspec/resources/docker/docker.md docker resource" |
| 9 | + parent = "inspec/resources/docker" |
| 10 | ++++ |
| 11 | + |
| 12 | +Use the `docker` Chef InSpec audit resource to test configuration data for the Docker daemon. It is a very comprehensive resource. See also: [docker_container](/inspec/resources/docker_container/) and [docker_image](/inspec/resources/docker_image/), too. |
| 13 | + |
| 14 | +## Syntax |
| 15 | + |
| 16 | +A `docker` resource block allows you to write tests for many containers: |
| 17 | + |
| 18 | +```ruby |
| 19 | +describe docker.containers do |
| 20 | + its('images') { should_not include 'u12:latest' } |
| 21 | +end |
| 22 | +``` |
| 23 | + |
| 24 | +or: |
| 25 | + |
| 26 | +```ruby |
| 27 | +describe docker.containers.where { names == 'flamboyant_allen' } do |
| 28 | + it { should be_running } |
| 29 | +end |
| 30 | +``` |
| 31 | + |
| 32 | +where |
| 33 | + |
| 34 | +- `.where()` may specify a specific item and value, to which the resource parameters are compared |
| 35 | +- `commands`, `ids`, `images`, `labels`, `local_volumes`, `mounts`, `names`, `networks`, `ports`, `sizes` and `status` are valid parameters for `containers` |
| 36 | + |
| 37 | +The `docker` resource block also declares allows you to write test for many images: |
| 38 | + |
| 39 | +```ruby |
| 40 | +describe docker.images do |
| 41 | + its('repositories') { should_not include 'insecure_image' } |
| 42 | +end |
| 43 | +``` |
| 44 | + |
| 45 | +or if you want to query specific images: |
| 46 | + |
| 47 | +```ruby |
| 48 | +describe docker.images.where { repository == 'ubuntu' && tag == '12.04' } do |
| 49 | + it { should_not exist } |
| 50 | +end |
| 51 | +``` |
| 52 | + |
| 53 | +where |
| 54 | + |
| 55 | +- `.where()` may specify a specific filter and expected value, against which parameters are compared |
| 56 | + |
| 57 | +## Examples |
| 58 | + |
| 59 | +The following examples show how to use this Chef InSpec audit resource. |
| 60 | + |
| 61 | +### Return all running containers |
| 62 | + |
| 63 | +```ruby |
| 64 | +docker.containers.running?.ids.each do |id| |
| 65 | + describe docker.object(id) do |
| 66 | + its('State.Health.Status') { should eq 'healthy' } |
| 67 | + end |
| 68 | +end |
| 69 | +``` |
| 70 | + |
| 71 | +### Verify a Docker Server and Client version |
| 72 | + |
| 73 | +```ruby |
| 74 | +describe docker.version do |
| 75 | + its('Server.Version') { should cmp >= '1.12'} |
| 76 | + its('Client.Version') { should cmp >= '1.12'} |
| 77 | +end |
| 78 | +``` |
| 79 | + |
| 80 | +### Iterate over all containers to verify host configuration |
| 81 | + |
| 82 | +```ruby |
| 83 | +docker.containers.ids.each do |id| |
| 84 | + # call Docker inspect for a specific container id |
| 85 | + describe docker.object(id) do |
| 86 | + its(%w(HostConfig Privileged)) { should cmp false } |
| 87 | + its(%w(HostConfig Privileged)) { should_not cmp true } |
| 88 | + end |
| 89 | +end |
| 90 | +``` |
| 91 | + |
| 92 | +### Iterate over all images to verify the container was built without ADD instruction |
| 93 | + |
| 94 | +```ruby |
| 95 | +docker.images.ids.each do |id| |
| 96 | + describe command("docker history #{id}| grep 'ADD'") do |
| 97 | + its('stdout') { should eq '' } |
| 98 | + end |
| 99 | +end |
| 100 | +``` |
| 101 | + |
| 102 | +### Verify that health-checks are enabled for a container |
| 103 | + |
| 104 | +```ruby |
| 105 | +describe docker.object('71b5df59442b') do |
| 106 | + its(%w(Config Healthcheck)) { should_not eq nil } |
| 107 | +end |
| 108 | +``` |
| 109 | + |
| 110 | +## How to run the DevSec Docker baseline profile |
| 111 | + |
| 112 | +There are two ways to run the `docker-baseline` profile to test Docker via the `docker` resource. |
| 113 | + |
| 114 | +Clone the profile: |
| 115 | + |
| 116 | +```bash |
| 117 | +git clone https://github.com/dev-sec/cis-docker-benchmark.git |
| 118 | +``` |
| 119 | + |
| 120 | +and then run: |
| 121 | + |
| 122 | +```bash |
| 123 | +inspec exec cis-docker-benchmark |
| 124 | +``` |
| 125 | + |
| 126 | +Or execute the profile directly via URL: |
| 127 | + |
| 128 | +```bash |
| 129 | +inspec exec https://github.com/dev-sec/cis-docker-benchmark |
| 130 | +``` |
| 131 | + |
| 132 | +## Resource Parameters |
| 133 | + |
| 134 | +- `commands`, `ids`, `images`, `labels`, `local_volumes`, `mounts`, `names`, `networks`, `ports`, `sizes` and `status` are valid parameters for `containers` |
| 135 | + |
| 136 | +## Resource Parameter Examples |
| 137 | + |
| 138 | +### containers |
| 139 | + |
| 140 | +`containers` returns information about containers as returned by [docker ps -a](https://docs.docker.com/engine/reference/commandline/ps/). |
| 141 | + |
| 142 | +```ruby |
| 143 | +describe docker.containers do |
| 144 | + its('ids') { should include 'sha:71b5df59...442b' } |
| 145 | + its('commands') { should_not include '/bin/sh' } |
| 146 | + its('images') { should_not include 'u12:latest' } |
| 147 | + its('ports') { should include '0.0.0.0:1234->1234/tcp' } |
| 148 | + its('labels') { should include 'License=GPLv2' } |
| 149 | +end |
| 150 | +``` |
| 151 | + |
| 152 | +### object('id') |
| 153 | + |
| 154 | +`object` returns low-level information about Docker objects. It is calling [docker inspect](https://docs.docker.com/engine/reference/commandline/info/) under the hood. |
| 155 | + |
| 156 | +```ruby |
| 157 | +describe docker.object(id) do |
| 158 | + its('Configuration.Path') { should eq 'value' } |
| 159 | +end |
| 160 | +``` |
| 161 | + |
| 162 | +### images |
| 163 | + |
| 164 | +`images` returns information about a Docker image as returned by [docker images](https://docs.docker.com/engine/reference/commandline/images/). |
| 165 | + |
| 166 | +```ruby |
| 167 | +describe docker.images do |
| 168 | + its('ids') { should include 'sha:12b5df59...442b' } |
| 169 | + its('repositories') { should_not include 'my_image' } |
| 170 | + its('tags') { should_not include 'unwanted_tag' } |
| 171 | + its('sizes') { should_not include '1.41 GB' } |
| 172 | +end |
| 173 | +``` |
| 174 | + |
| 175 | +### plugins |
| 176 | + |
| 177 | +`plugins` returns information about Docker plugins as returned by [docker plugin ls](https://docs.docker.com/engine/reference/commandline/plugin/). |
| 178 | + |
| 179 | +```ruby |
| 180 | +describe docker.plugins do |
| 181 | + its('names') { should include ['store/weaveworks/net-plugin', 'docker4x/cloudstor'] } |
| 182 | + its('ids') { should cmp ['6ea8176de74b', '771d3ee7c7ea'] } |
| 183 | + its('versions') { should cmp ['2.3.0', '18.03.1-ce-aws1'] } |
| 184 | + its('enabled') { should cmp [true, false] } |
| 185 | +end |
| 186 | +``` |
| 187 | + |
| 188 | +### info |
| 189 | + |
| 190 | +`info` returns the parsed result of [docker info](https://docs.docker.com/engine/reference/commandline/info/) |
| 191 | + |
| 192 | +```ruby |
| 193 | +describe docker.info do |
| 194 | + its('Configuration.Path') { should eq 'value' } |
| 195 | +end |
| 196 | +``` |
| 197 | + |
| 198 | +### version |
| 199 | + |
| 200 | +`info` returns the parsed result of [docker version](https://docs.docker.com/engine/reference/commandline/version/) |
| 201 | + |
| 202 | +```ruby |
| 203 | +describe docker.version do |
| 204 | + its('Server.Version') { should cmp >= '1.12'} |
| 205 | + its('Client.Version') { should cmp >= '1.12'} |
| 206 | +end |
| 207 | +``` |
| 208 | + |
| 209 | +## Properties |
| 210 | + |
| 211 | +- `id` |
| 212 | +- `image` |
| 213 | +- `repo` |
| 214 | +- `tag` |
| 215 | +- `ports` |
| 216 | +- `command` |
| 217 | + |
| 218 | +## Property Examples |
| 219 | + |
| 220 | +### id |
| 221 | + |
| 222 | +```ruby |
| 223 | +describe docker_container(name: 'an-echo-server') do |
| 224 | + its('id') { should_not eq '' } |
| 225 | +end |
| 226 | +``` |
| 227 | + |
| 228 | +### image |
| 229 | + |
| 230 | +```ruby |
| 231 | +describe docker_container(name: 'an-echo-server') do |
| 232 | + its('image') { should eq 'busybox:latest' } |
| 233 | +end |
| 234 | +``` |
| 235 | + |
| 236 | +### repo |
| 237 | + |
| 238 | +```ruby |
| 239 | +describe docker_container(name: 'an-echo-server') do |
| 240 | + its('repo') { should eq 'busybox' } |
| 241 | +end |
| 242 | +``` |
| 243 | + |
| 244 | +### tag |
| 245 | + |
| 246 | +```ruby |
| 247 | +describe docker_container(name: 'an-echo-server') do |
| 248 | + its('tag') { should eq 'latest' } |
| 249 | +end |
| 250 | +``` |
| 251 | + |
| 252 | +### ports |
| 253 | + |
| 254 | +```ruby |
| 255 | +describe docker_container(name: 'an-echo-server') do |
| 256 | + its('ports') { should eq '0.0.0.0:1234->1234/tcp' } |
| 257 | +end |
| 258 | +``` |
| 259 | + |
| 260 | +### command |
| 261 | + |
| 262 | +```ruby |
| 263 | +describe docker_container(name: 'an-echo-server') do |
| 264 | + its('command') { should eq 'nc -ll -p 1234 -e /bin/cat' } |
| 265 | +end |
| 266 | +``` |
| 267 | + |
| 268 | +## Matchers |
| 269 | + |
| 270 | +{{< readfile file="content/reusable/md/inspec_matchers_link.md" >}} |
0 commit comments