test_webserver/test/security_test.rb

99 lines
2.4 KiB
Ruby

require 'test_helper'
require 'mechanize'
class SecurityTest < Minitest::Test
include WebserverHelper
def test_certificate_level
level = "intermediate"
output = `#{analyze_cmd(domain, level)}`
assert_match %r|has intermediate ssl/tls\nand complies with the '#{level}' level|, output, "Expected to comply with #{level} level :\n#{output.inspect}"
refute_match %r|consider enabling OCSP Stapling|, output, 'Expected to have OCSP stapling enabled'
end
def test_certificate
output = `#{check_ssl_cert_cmd(domain)}`
assert_match(/\ASSL_CERT OK/, output, output)
end
def test_accepts_tls_v1
output = `#{openssl_verify_cmd(domain, "-tls1")}`
assert_match(/Verify return code: 0 \(ok\)/, output, "Expected to accept TLSv1")
end
def test_refuse_ssl_v3
output = `#{openssl_verify_cmd(domain, "-ssl3")}`
assert_match(/sslv3 alert handshake failure/, output, "Expected to refuse SSLv3")
end
def test_hsts_header
agent = Mechanize.new { |a|
a.follow_redirect = false
}
page = agent.get("https://#{domain}")
assert_has_header("Strict-Transport-Security", page)
end
def check_ssl_cert_cmd(domain)
# check_ssl_cert is a Nagios plugin, usable outside of Nagios
# cf. https://trac.id.ethz.ch/projects/nagios_plugins/wiki/check_ssl_cert
args = [
"--rootcert", root_certificate,
"--openssl", openssl_path(:system),
"--issuer", %Q("Gandi Standard SSL CA 2"),
"--warning", 60,
"--critical", 30,
"--cn", %Q("*.example.com"),
"--host-cn",
"--ocsp",
"--host", domain,
].join(" ")
"vendor/check_ssl_cert/check_ssl_cert #{args}"
end
def analyze_cmd(domain, level = "intermediate")
# Cipherscan helps audit SSL configuration
# cf. https://github.com/jvehent/cipherscan
args = [
"-o", openssl_path(:local),
"-l", level,
"-t", domain
].join(' ')
"vendor/cipherscan/analyze.py #{args}"
end
def openssl_verify_cmd(domain, options = "")
args = [
"-CAfile", "#{root_certificate}",
"-connect", "#{domain}:443",
options,
"2>&1",
].join(" ")
"echo QUIT | #{openssl_path} s_client #{args}"
end
def openssl_path(variant = :system)
case variant
when :local
"vendor/cipherscan/openssl-darwin64"
else
`which openssl`.chop
end
end
def root_certificate
"test/certs/AddTrust_External_CA_Root.pem"
end
end