mirror of
https://github.com/inspec/inspec
synced 2024-11-26 14:40:26 +00:00
nginx resource: audit the nginx binary and how it was compiled (#1958)
* nginx base resource Signed-off-by: Aaron Lippold <lippold@gmail.com> Signed-off-by: Rony Xavier <rx294@gmail.com>
This commit is contained in:
parent
dd1d0ca553
commit
7d2da0c199
7 changed files with 275 additions and 0 deletions
72
docs/resources/nginx.md.erb
Normal file
72
docs/resources/nginx.md.erb
Normal file
|
@ -0,0 +1,72 @@
|
|||
---
|
||||
title: The Nginx Resource
|
||||
---
|
||||
|
||||
# nginx
|
||||
|
||||
Use the `nginx` InSpec audit resource to test the fields and validity of nginx.
|
||||
|
||||
Nginx resource extracts and exposes data reported by the command 'nginx -V'
|
||||
|
||||
## Syntax
|
||||
|
||||
An `nginx` InSpec audit resource block extracts configuration settings that should be tested:
|
||||
|
||||
describe nginx do
|
||||
its('attribute') { should eq 'value' }
|
||||
end
|
||||
|
||||
describe nginx('path to nginx') do
|
||||
its('attribute') { should eq 'value' }
|
||||
end
|
||||
|
||||
where
|
||||
|
||||
* `'attribute'` is a configuration parsed from result of the command 'nginx -V'
|
||||
* `'value'` is the value that is expected of the attribute
|
||||
|
||||
## Supported Properties
|
||||
|
||||
* 'compiler_info', 'error_log_path', 'http_client_body_temp_path', 'http_fastcgi_temp_path', 'http_log_path', 'http_proxy_temp_path', 'http_scgi_temp_path', 'http_uwsgi_temp_path', 'lock_path', 'modules', 'modules_path', 'openssl_version', 'prefix', 'sbin_path', 'service', 'support_info', 'version'
|
||||
|
||||
## Property Examples and Return Types
|
||||
|
||||
### version(String)
|
||||
|
||||
`version` returns a string of the version of the running nginx instance
|
||||
|
||||
describe nginx do
|
||||
its('version') { should eq '1.12.0' }
|
||||
end
|
||||
|
||||
### modules(String)
|
||||
|
||||
`modules` returns a array modules in the running nginx instance
|
||||
|
||||
describe nginx do
|
||||
its('modules') { should include 'my_module' }
|
||||
end
|
||||
|
||||
### openssl_version(Hash)
|
||||
|
||||
`openssl_version ` returns a hash with 'version' and 'date' as keys
|
||||
|
||||
describe nginx do
|
||||
its('openssl_version.date') { should eq '11 Feb 2013' }
|
||||
end
|
||||
|
||||
### compiler_info(Hash)
|
||||
|
||||
`compiler_info ` returns a hash with 'compiler' , version' and 'date' as keys
|
||||
|
||||
describe nginx do
|
||||
its('compiler_info.compiler') { should eq 'gcc' }
|
||||
end
|
||||
|
||||
### support_info(String)
|
||||
|
||||
`support_info ` returns a string containing supported protocols
|
||||
|
||||
describe nginx do
|
||||
its('support_info') { should match /TLS/ }
|
||||
end
|
|
@ -114,6 +114,7 @@ require 'resources/mssql_session'
|
|||
require 'resources/mysql'
|
||||
require 'resources/mysql_conf'
|
||||
require 'resources/mysql_session'
|
||||
require 'resources/nginx'
|
||||
require 'resources/nginx_conf'
|
||||
require 'resources/npm'
|
||||
require 'resources/ntp_conf'
|
||||
|
|
97
lib/resources/nginx.rb
Normal file
97
lib/resources/nginx.rb
Normal file
|
@ -0,0 +1,97 @@
|
|||
# encoding: utf-8
|
||||
# author: Aaron Lippold, lippold@gmail.com
|
||||
# author: Rony Xavier, rx294@gmail.com
|
||||
|
||||
require 'pathname'
|
||||
require 'hashie/mash'
|
||||
|
||||
module Inspec::Resources
|
||||
class Nginx < Inspec.resource(1)
|
||||
name 'nginx'
|
||||
desc 'Use the nginx InSpec audit resource to test information about your NGINX instance.'
|
||||
example "
|
||||
describe nginx do
|
||||
its('conf_path') { should cmp '/etc/nginx/nginx.conf' }
|
||||
end
|
||||
describe nginx('/etc/sbin/') do
|
||||
its('version') { should be >= '1.0.0' }
|
||||
end
|
||||
describe nginx do
|
||||
its('modules') { should include 'my_module' }
|
||||
end
|
||||
"
|
||||
attr_reader :params, :bin_dir
|
||||
|
||||
def initialize(nginx_path = '/usr/sbin/nginx')
|
||||
return skip_resource 'The `nginx` resource is not yet available on your OS.' if inspec.os.windows?
|
||||
return skip_resource 'The `nginx` binary not found in the path provided.' unless inspec.command(nginx_path).exist?
|
||||
|
||||
cmd = inspec.command("#{nginx_path} -V 2>&1")
|
||||
if !cmd.exit_status.zero?
|
||||
return skip_resource 'Error using the command nginx -V'
|
||||
end
|
||||
@data = cmd.stdout
|
||||
@params = {}
|
||||
read_content
|
||||
end
|
||||
|
||||
%w{compiler_info error_log_path http_client_body_temp_path http_fastcgi_temp_path http_log_path http_proxy_temp_path http_scgi_temp_path http_uwsgi_temp_path lock_path modules_path openssl_version prefix sbin_path service support_info version}.each do |property|
|
||||
define_method(property.to_sym) do
|
||||
@params[property.to_sym]
|
||||
end
|
||||
end
|
||||
|
||||
def openssl_version
|
||||
result = @data.scan(/built with OpenSSL\s(\S+)\s(\d+\s\S+\s\d{4})/).flatten
|
||||
Hashie::Mash.new({ 'version' => result[0], 'date' => result[1] })
|
||||
end
|
||||
|
||||
def compiler_info
|
||||
result = @data.scan(/built by (\S+)\s(\S+)\s(\S+)/).flatten
|
||||
Hashie::Mash.new({ 'compiler' => result[0], 'version' => result[1], 'date' => result[2] })
|
||||
end
|
||||
|
||||
def support_info
|
||||
support_info = @data.scan(/(.*\S+) support enabled/).flatten
|
||||
support_info.empty? ? nil : support_info.join(' ')
|
||||
end
|
||||
|
||||
def modules
|
||||
@data.scan(/--with-(\S+)_module/).flatten
|
||||
end
|
||||
|
||||
def to_s
|
||||
'Nginx Environment'
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def read_content
|
||||
parse_config
|
||||
parse_path
|
||||
parse_http_path
|
||||
end
|
||||
|
||||
def parse_config
|
||||
@params[:prefix] = @data.scan(/--prefix=(\S+)\s/).flatten.first
|
||||
@params[:service] = 'nginx'
|
||||
@params[:version] = @data.scan(%r{nginx version: nginx\/(\S+)\s}).flatten.first
|
||||
end
|
||||
|
||||
def parse_path
|
||||
@params[:sbin_path] = @data.scan(/--sbin-path=(\S+)\s/).flatten.first
|
||||
@params[:modules_path] = @data.scan(/--modules-path=(\S+)\s/).flatten.first
|
||||
@params[:error_log_path] = @data.scan(/--error-log-path=(\S+)\s/).flatten.first
|
||||
@params[:http_log_path] = @data.scan(/--http-log-path=(\S+)\s/).flatten.first
|
||||
@params[:lock_path] = @data.scan(/--lock-path=(\S+)\s/).flatten.first
|
||||
end
|
||||
|
||||
def parse_http_path
|
||||
@params[:http_client_body_temp_path] = @data.scan(/--http-client-body-temp-path=(\S+)\s/).flatten.first
|
||||
@params[:http_proxy_temp_path] = @data.scan(/--http-proxy-temp-path=(\S+)\s/).flatten.first
|
||||
@params[:http_fastcgi_temp_path] = @data.scan(/--http-fastcgi-temp-path=(\S+)\s/).flatten.first
|
||||
@params[:http_uwsgi_temp_path] = @data.scan(/--http-uwsgi-temp-path=(\S+)\s/).flatten.first
|
||||
@params[:http_scgi_temp_path] = @data.scan(/--http-scgi-temp-path=(\S+)\s/).flatten.first
|
||||
end
|
||||
end
|
||||
end
|
|
@ -370,6 +370,11 @@ class MockLoader
|
|||
# oracle
|
||||
"bash -c 'type \"sqlplus\"'" => cmd.call('oracle-cmd'),
|
||||
"ef04e5199abee80e662cc0dd1dd3bf3e0aaae9b4498217d241db00b413820911" => cmd.call('oracle-result'),
|
||||
# nginx mock cmd
|
||||
%{nginx -V 2>&1} => cmd.call('nginx-v'),
|
||||
%{/usr/sbin/nginx -V 2>&1} => cmd.call('nginx-v'),
|
||||
%{bash -c 'type "/usr/sbin/nginx"'} => cmd.call('bash-c-type-nginx'),
|
||||
# needed for two differnt inspec.command call formats
|
||||
# host resource: dig commands,
|
||||
'dig +short A example.com' => cmd.call('dig-A-example.com'),
|
||||
'dig +short AAAA example.com' => cmd.call('dig-AAAA-example.com'),
|
||||
|
|
1
test/unit/mock/cmd/bash-c-type-nginx
Normal file
1
test/unit/mock/cmd/bash-c-type-nginx
Normal file
|
@ -0,0 +1 @@
|
|||
nginx is /usr/sbin/nginx
|
5
test/unit/mock/cmd/nginx-v
Normal file
5
test/unit/mock/cmd/nginx-v
Normal file
|
@ -0,0 +1,5 @@
|
|||
nginx version: nginx/1.12.0
|
||||
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-4) (GCC)
|
||||
built with OpenSSL 1.0.1e-fips 11 Feb 2013
|
||||
TLS SNI support enabled
|
||||
configure arguments: --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-compat --with-file-aio --with-threads --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-mail --with-mail_ssl_module --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -fPIC' --with-ld-opt='-Wl,-z,relro -Wl,-z,now -pie'
|
94
test/unit/resources/nginx_test.rb
Normal file
94
test/unit/resources/nginx_test.rb
Normal file
|
@ -0,0 +1,94 @@
|
|||
# encoding: utf-8
|
||||
# author: Aaron Lippold, lippold@gmail.com
|
||||
# author: Rony Xavier, rx294@nyu.edu
|
||||
|
||||
require 'helper'
|
||||
require 'inspec/resource'
|
||||
|
||||
describe 'Inspec::Resources::Nginx' do
|
||||
describe 'NGINX Methods' do
|
||||
it 'Verify nginx parsing `support_info` - `TLS SNI`' do
|
||||
resource = load_resource('nginx')
|
||||
_(resource.support_info).must_match 'TLS SNI'
|
||||
end
|
||||
it 'Verify nginx parsing `openssl_version` - `1.0.1e-fips/11 Feb 2013`' do
|
||||
resource = load_resource('nginx')
|
||||
_(resource.openssl_version.date).must_match '11 Feb 2013'
|
||||
_(resource.openssl_version.version).must_match '1.0.1e-fips'
|
||||
end
|
||||
it 'Verify nginx parsing `compiler_info` - `gcc 4.8.5 20150623 (Red Hat 4.8.5-4) (GCC)`' do
|
||||
resource = load_resource('nginx')
|
||||
_(resource.compiler_info.compiler).must_match 'gcc'
|
||||
_(resource.compiler_info.version).must_match '4.8.5'
|
||||
_(resource.compiler_info.date).must_match '20150623'
|
||||
end
|
||||
it 'Verify nginx parsing `version` - 1.12.0' do
|
||||
resource = load_resource('nginx')
|
||||
_(resource.version).must_match '1.12.0'
|
||||
end
|
||||
it 'Verify nginx_module parsing with custom path`version` - 1.12.0' do
|
||||
resource = load_resource('nginx','/usr/sbin/nginx')
|
||||
_(resource.version).must_match '1.12.0'
|
||||
end
|
||||
it 'Verify nginx_module parsing with a broken custom path`version` - 1.12.0' do
|
||||
resource = load_resource('nginx','/usr/sbin/nginx')
|
||||
_(resource.version).must_match '1.12.0'
|
||||
end
|
||||
it 'Verify nginx parsing `service` - `nginx`' do
|
||||
resource = load_resource('nginx')
|
||||
_(resource.service).must_match 'nginx'
|
||||
end
|
||||
it 'Verify nginx parsing `modules` - `nginx`' do
|
||||
resource = load_resource('nginx')
|
||||
_(resource.modules).must_include 'http_addition'
|
||||
end
|
||||
it 'Verify nginx parsing `prefix` - `/etc/nginx`' do
|
||||
resource = load_resource('nginx')
|
||||
_(resource.prefix).must_match '/etc/nginx'
|
||||
end
|
||||
it 'Verify nginx parsing `sbin_path` - `/usr/sbin/nginx`' do
|
||||
resource = load_resource('nginx')
|
||||
_(resource.sbin_path).must_match '/usr/sbin/nginx'
|
||||
end
|
||||
it 'Verify nginx parsing `modules_path` - `/usr/lib64/nginx/modules`' do
|
||||
resource = load_resource('nginx')
|
||||
_(resource.modules_path).must_match '/usr/lib64/nginx/modules'
|
||||
end
|
||||
it 'Verify nginx parsing `error_log_path` - `/var/log/nginx/error.log`' do
|
||||
resource = load_resource('nginx')
|
||||
_(resource.error_log_path).must_match '/var/log/nginx/error.log'
|
||||
end
|
||||
it 'Verify nginx parsing `error_log_path` - `/var/log/nginx/access.log`' do
|
||||
resource = load_resource('nginx')
|
||||
_(resource.http_log_path).must_match '/var/log/nginx/access.log'
|
||||
end
|
||||
it 'Verify nginx parsing `lock_path` - `/var/run/nginx.lock`' do
|
||||
resource = load_resource('nginx')
|
||||
_(resource.lock_path).must_match '/var/run/nginx.lock'
|
||||
end
|
||||
it 'Verify nginx parsing `http_client_body_temp_path` - `/var/cache/nginx/client_temp`' do
|
||||
resource = load_resource('nginx')
|
||||
_(resource.http_client_body_temp_path).must_match '/var/cache/nginx/client_temp'
|
||||
end
|
||||
it 'Verify nginx parsing `http_proxy_temp_path` - `/var/cache/nginx/proxy_temp`' do
|
||||
resource = load_resource('nginx')
|
||||
_(resource.http_proxy_temp_path).must_match '/var/cache/nginx/proxy_temp'
|
||||
end
|
||||
it 'Verify nginx parsing `http_fastcgi_temp_path` - `/var/cache/nginx/fastcgi_temp`' do
|
||||
resource = load_resource('nginx')
|
||||
_(resource.http_fastcgi_temp_path).must_match '/var/cache/nginx/fastcgi_temp'
|
||||
end
|
||||
it 'Verify nginx parsing `http_uwsgi_temp_path` - `/var/cache/nginx/uwsgi_temp`' do
|
||||
resource = load_resource('nginx')
|
||||
_(resource.http_uwsgi_temp_path).must_match '/var/cache/nginx/uwsgi_temp'
|
||||
end
|
||||
it 'Verify nginx parsing `http_scgi_temp_path` - `/var/cache/nginx/scgi_temp`' do
|
||||
resource = load_resource('nginx')
|
||||
_(resource.http_scgi_temp_path).must_match '/var/cache/nginx/scgi_temp'
|
||||
end
|
||||
it 'Verify nginx parsing `http_scgi_temp_path` - `/var/cache/nginx/scgi_temp`' do
|
||||
resource = load_resource('nginx')
|
||||
_(resource.http_scgi_temp_path).must_match '/var/cache/nginx/scgi_temp'
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue