diff options
author | Kelley Spoon <kelley.spoon@linaro.org> | 2018-04-05 17:14:38 -0500 |
---|---|---|
committer | Kelley Spoon <kelley.spoon@linaro.org> | 2018-04-13 17:51:12 +0000 |
commit | 40e0981a379f50e888df3b62ef20a7cdca1d00b5 (patch) | |
tree | 8de8c2bccaab5c62fecfc6d9b76cf5efe8efdf21 | |
parent | 04087ec2c64ed3d9e9a2db67f811442d8f067fa4 (diff) |
Docs: add example of ad hoc command used to do SSL audit
Change-Id: If4906ea2522bc28a072e3d7bbd03734e7a056a3c
Reviewed-on: https://review.linaro.org/24580
Reviewed-by: Benjamin Copeland <ben.copeland@linaro.org>
-rw-r--r-- | docs/README.audit_ssl.md | 33 | ||||
-rwxr-xr-x | docs/examples/audit_ssl.sh | 22 | ||||
-rwxr-xr-x | docs/examples/parse_audit.py | 128 |
3 files changed, 183 insertions, 0 deletions
diff --git a/docs/README.audit_ssl.md b/docs/README.audit_ssl.md new file mode 100644 index 00000000..cd535011 --- /dev/null +++ b/docs/README.audit_ssl.md @@ -0,0 +1,33 @@ +Overview +======== + +This is an example of using the "ad-hoc" feature of ansible to scan through +all hosts in our inventory, as well an example of using the "script" module +to execute a local script on an ansible_host. + +The purpose of this script is to generate a quick report on the disposition +our SSL certificates in our inventory and determine if the server: + +- appears to be managed by CTT or ITS +- has the Go Daddy bundle installed +- has a LetsEncrypt/certbot certificate installed +- has the letsencrypt program installed +- has the certbot program installed + + +Ansible Command +=============== + +The command to run the audit is: + + ansible all -i hosts -m script --limit 'all:!jenkins_slaves' -a "docs/examples/audit_ssl.sh" > ssl_audit.txt + +Root/sudo privs are not be required to run this script, but ssh access to the +server is. + + +parse_audit.py +============== + +This is an extremely ugly script that's meant to convert the output from +the above ansible command into a csv file. diff --git a/docs/examples/audit_ssl.sh b/docs/examples/audit_ssl.sh new file mode 100755 index 00000000..4dc6b9fc --- /dev/null +++ b/docs/examples/audit_ssl.sh @@ -0,0 +1,22 @@ +#!/bin/sh + +echo -n "Apache managed by: " +grep j2 /etc/apache2/sites-enabled/* > /dev/null 2>&1 && echo "ITS" || echo "CTT" + +echo -n "Go Daddy: " +test -f /etc/ssl/certs/wildcard.linaro.org.crt && echo -n "PRESENT" +echo + +echo -n "LE dir: " +test -d /etc/letsencrypt && echo -n "PRESENT" +echo + +echo -n "letsencrypt: " +which letsencrypt > /dev/null 2>&1 +[ $? = 0 ] && echo -n "PRESENT" +echo + +echo -n "certbot: " +which certbot > /dev/null 2>&1 +[ $? = 0 ] && echo -n "PRESENT" +echo diff --git a/docs/examples/parse_audit.py b/docs/examples/parse_audit.py new file mode 100755 index 00000000..37be1a9c --- /dev/null +++ b/docs/examples/parse_audit.py @@ -0,0 +1,128 @@ +#!/usr/bin/env python + +import re +import sys +import json +import csv +import os, subprocess + +le_hosts ={} + +row = {} + +#row.host +#row.result +#row.apache_manager +#row.has_le_cert +#row.has_gd_cert +#row.has_letsencrypt +#row.has_certbot +#row.error + + +ANSIBLE_CMD = 'ansible-playbook -i hosts --list-hosts --list-tasks ' +ANSIBLE_PLAYBOOK_DIR = '.' + +# returns a list of playbooks that contain a role +def has_role( playbook, role ): + cmd = ANSIBLE_CMD.split() + cmd.append(f) + output = subprocess.check_output( cmd ) + lines = output.split('\n') + + hosts = [] + temp_hosts = [] + + in_hosts = False + in_tasks = False + for x in lines: + if re.search('\s+play #\d+',x): + in_hosts = False + in_tasks = False + temp_hosts = [] + elif re.search('\s+hosts.*:',x): + in_hosts = True + in_tasks = False + elif re.search('\s+tasks.*:',x): + in_hosts = False + in_tasks = True + else: + if in_hosts: + temp_hosts.append( x.strip() ) + if in_tasks and x is not '': + fields = x.split(':') + if fields[0].strip() == role: + + for h in temp_hosts: + if h not in hosts: + hosts.append( h ) + + return hosts + +le_hosts = {} + +# find all playbooks that are using letsencrypt role +for f in os.listdir(ANSIBLE_PLAYBOOK_DIR): + if re.search('.*\.yml$', f): + hosts = has_role( f, 'letsencrypt' ) + if hosts: + for x in hosts: + if not le_hosts.has_key( x ): + le_hosts[x] = [] + le_hosts[x].append( f ) + +with open('ssl_audit.csv', 'w') as csvfile: + fieldnames = ["host","result","apache_manager","ansible_le","has_le_cert","has_gd_cert","has_letsencrypt","has_certbot","error"] + + writer = csv.DictWriter(csvfile, fieldnames=fieldnames) + writer.writeheader() + + with open( sys.argv[1], 'r') as audit_file: + buffer = [] + next_line = audit_file.readline().rstrip() + row["host"] = '' + row["result"] = '' + while next_line: + if re.match('}', next_line): + buffer.append( next_line) + + data = json.loads( ''.join(buffer) ) + + if row["result"].strip() == "SUCCESS": + for x in data["stdout_lines"]: + try: + check,val = x.split(':') + if check == "Apache managed by": + row["apache_manager"] = val.strip() + if check == "Go Daddy": + row["has_gd_cert"] = str( val.strip() ) + if check == "LE dir": + row["has_le_cert"] = str( val.strip() ) + if check == "letsencrypt": + row["has_letsencrypt"] = str( val.strip() ) + if check == "certbot": + row["has_certbot"] = str( val.strip() ) + except ValueError as e: + pass + else: + row["error"] = data["msg"] + + h = row["host"] + if le_hosts.has_key(h) and le_hosts[h]: + row["ansible_le"] = ';'.join( le_hosts[h] ) + else: + row["ansible_le"] = None + writer.writerow( row ) + + buffer = [] + row = {} + else: + fields = next_line.split('=>') + if len(fields) > 1: + buffer.append( fields[1] ) + host, result = fields[0].split( '|' ) + row["host"] = host.strip() + row["result"] = result.strip() + else: + buffer.append( next_line) + next_line = audit_file.readline().rstrip() |