mirror of
https://github.com/inspec/inspec
synced 2024-12-18 00:53:22 +00:00
75f39e74f2
shadow file. After much thought the deprecations from #2642 were for the wrong methods. Plural method names feel much more natural when working with this resource because you can have more than a single result. Consider a match like `shadow.user(/^www/)`, this could return multiple users, so `shadow.users` feels more natural here. The problem is that the fields we're matching in the shadow file itself are singular. Each entry is for a user, which has a password, and some other fields. A user never has `passwords` in the shadow file, only a `password`. This is made more obvious when you use the `filter` method. When we use this filter: `shadow.filter(min_days: 20, max_days: 30)` we are matching fields in the shadow file and not using our matcher methods. This means that if there is a discrepancy between our matcher methods, and the shadow fields the user could end up confused. Like I did =) This PR changes: Changed matchers to match shadow fields. Updated documentation to reflect changes. Updated tests to reflect changes. Re-add `filter` method, and add a test for it. Renamed variable for FilterTable to be less confusing. Renamed query argument for methods to be consistent. Cleanup docs based on comments from @jerryaldrichiii Make Rubocop happy <3 Signed-off-by: Miah Johnson <miah@chia-pet.org>
146 lines
3.6 KiB
Text
146 lines
3.6 KiB
Text
---
|
|
title: About the shadow Resource
|
|
platform: linux
|
|
---
|
|
|
|
# shadow
|
|
|
|
Use the `shadow` InSpec audit resource to test the contents of `/etc/shadow`, which contains password details that are only readable by the `root` user. The format for `/etc/shadow` includes:
|
|
|
|
* A username
|
|
* The password for that user (on newer systems passwords should be stored in `/etc/shadow` )
|
|
* The last time a password was changed
|
|
* The minimum number of days a password must exist, before it may be changed
|
|
* The maximum number of days after which a password must be changed
|
|
* The number of days a user is warned about an expiring password
|
|
* The number of days a user must be inactive before the user account is disabled
|
|
* The number of days a user account has been disabled
|
|
|
|
These entries are defined as a colon-delimited row in the file, one row per user:
|
|
|
|
dannos:Gb7crrO5CDF.:10063:0:99999:7:::
|
|
|
|
<br>
|
|
|
|
## Syntax
|
|
|
|
A `shadow` resource block declares one (or more) users and associated user information to be tested:
|
|
|
|
describe shadow do
|
|
its('user') { should_not include 'forbidden_user' }
|
|
end
|
|
|
|
or with a single query:
|
|
|
|
describe shadow.user('root') do
|
|
its('count') { should eq 1 }
|
|
end
|
|
|
|
or with a filter:
|
|
|
|
describe shadow.filter(min_days: '0', max_days: '99999') do
|
|
its('count') { should eq 1 }
|
|
end
|
|
|
|
The following properties are available:
|
|
|
|
* `user`
|
|
* `password`
|
|
* `last_change`
|
|
* `min_days`
|
|
* `max_days`
|
|
* `warn_days`
|
|
* `inactive_days`
|
|
* `expiry_date`
|
|
* `reserved`
|
|
|
|
Properties can be used as a single query or can be joined together with the `.filter` method.
|
|
|
|
<br>
|
|
|
|
## Examples
|
|
|
|
The following examples show how to use this InSpec audit resource.
|
|
|
|
### Test for a forbidden user
|
|
|
|
describe shadow do
|
|
its('user') { should_not include 'forbidden_user' }
|
|
end
|
|
|
|
### Test that a user appears one time
|
|
|
|
describe shadow.user('bin') do
|
|
its('password') { should cmp 'x' }
|
|
its('count') { should eq 1 }
|
|
end
|
|
|
|
<br>
|
|
|
|
## Matchers
|
|
|
|
For a full list of available matchers, please visit our [matchers page](https://www.inspec.io/docs/reference/matchers/).
|
|
|
|
### count
|
|
|
|
The `count` matcher tests the number of times the named user appears in `/etc/shadow`:
|
|
|
|
its('count') { should eq 1 }
|
|
|
|
This matcher is best used in conjunction with filters. For example:
|
|
|
|
describe shadow.user('dannos') do
|
|
its('count') { should eq 1 }
|
|
end
|
|
|
|
### user
|
|
|
|
The `user` matcher tests if the username exists `/etc/shadow`:
|
|
|
|
its('user') { should eq 'root' }
|
|
|
|
### password
|
|
|
|
The `password` matcher returns the encrypted password string from the shadow file. The returned string may not be an encrypted password, but rather a `*` or similar which indicates that direct logins are not allowed.
|
|
|
|
For example:
|
|
|
|
its('password') { should cmp '*' }
|
|
|
|
### last_change
|
|
|
|
The `last_change` matcher tests the last time a password was changed:
|
|
|
|
its('last_change') { should be_empty }
|
|
|
|
### min_days
|
|
|
|
The `min_days` matcher tests the minimum number of days a password must exist, before it may be changed:
|
|
|
|
its('min_days') { should eq 0 }
|
|
|
|
### max_days
|
|
|
|
The `max_days` matcher tests the maximum number of days after which a password must be changed:
|
|
|
|
its('max_days') { should eq 90 }
|
|
|
|
### warn_days
|
|
|
|
The `warn_days` matcher tests the number of days a user is warned about an expiring password:
|
|
|
|
its('warn_days') { should eq 7 }
|
|
|
|
### inactive_days
|
|
|
|
The `inactive_days` matcher tests the number of days a user must be inactive before the user account is disabled:
|
|
|
|
its('inactive_days') { should be_empty }
|
|
|
|
### expiry_date
|
|
|
|
The `expiry_date` matcher tests the number of days a user account has been disabled:
|
|
|
|
its('expiry_date') { should be_empty }
|
|
|
|
|