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:
Rony Xavier 2017-09-13 08:15:09 -04:00 committed by Adam Leff
parent dd1d0ca553
commit 7d2da0c199
7 changed files with 275 additions and 0 deletions

View 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

View file

@ -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
View 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

View file

@ -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'),

View file

@ -0,0 +1 @@
nginx is /usr/sbin/nginx

View 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'

View 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