summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKelley Spoon <kelley.spoon@linaro.org>2018-04-05 17:14:38 -0500
committerKelley Spoon <kelley.spoon@linaro.org>2018-04-13 17:51:12 +0000
commit40e0981a379f50e888df3b62ef20a7cdca1d00b5 (patch)
tree8de8c2bccaab5c62fecfc6d9b76cf5efe8efdf21
parent04087ec2c64ed3d9e9a2db67f811442d8f067fa4 (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.md33
-rwxr-xr-xdocs/examples/audit_ssl.sh22
-rwxr-xr-xdocs/examples/parse_audit.py128
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()