3 # Copyright (c) 2016 Red Hat
4 # Luke Hinds (lhinds@redhat.com)
5 # This program and the accompanying materials
6 # are made available under the terms of the Apache License, Version 2.0
7 # which accompanies this distribution, and is available at
9 # http://www.apache.org/licenses/LICENSE-2.0
11 # 0.1: This script installs OpenSCAP on the remote host, and scans the
12 # nominated node. Post scan a report is downloaded and if '--clean' is passed
13 # all trace of the scan is removed from the remote system.
21 from ConfigParser import SafeConfigParser
22 from keystoneclient.auth.identity import v2
23 from keystoneclient import session
24 from novaclient import client
27 __author__ = 'Luke Hinds (lhinds@redhat.com)'
28 __url__ = 'https://wiki.opnfv.org/display/functest/Functest+Security'
31 INSTALLER_IP = os.getenv('INSTALLER_IP')
32 oscapbin = 'sudo /bin/oscap'
33 functest_dir = '/home/opnfv/repos/functest/testcases/security_scan/'
35 # Apex Spefic var needed to query Undercloud
36 if os.getenv('OS_AUTH_URL') is None:
37 connect.logger.error(" Enviroment variable OS_AUTH_URL is not set")
40 OS_AUTH_URL = os.getenv('OS_AUTH_URL')
43 parser = argparse.ArgumentParser(description='OPNFV OpenSCAP Scanner')
44 parser.add_argument('--config', action='store', dest='cfgfile',
45 help='Config file', required=True)
46 args = parser.parse_args()
49 cfgparse = SafeConfigParser()
50 cfgparse.read(args.cfgfile)
53 remotekey = cfgparse.get('undercloud', 'remotekey')
54 localkey = cfgparse.get('undercloud', 'localkey')
55 setup = connect.SetUp(remotekey, localkey)
59 # Configure Nova Credentials
60 com = 'sudo /usr/bin/hiera admin_password'
61 setup = connect.SetUp(com)
62 keypass = setup.keystonepass()
63 auth = v2.Password(auth_url=OS_AUTH_URL,
65 password=str(keypass).rstrip(),
67 sess = session.Session(auth=auth)
68 nova = client.Client(2, session=sess)
71 def run_tests(host, nodetype):
72 user = cfgparse.get(nodetype, 'user')
73 port = cfgparse.get(nodetype, 'port')
74 connect.logger.info("Host: {0} Selected Profile: {1}".format(host,
76 connect.logger.info("Creating temp file structure..")
77 createfiles(host, port, user, localkey)
78 connect.logger.info("Installing OpenSCAP...")
79 install_pkg(host, port, user, localkey)
80 connect.logger.info("Running scan...")
81 run_scanner(host, port, user, localkey, nodetype)
82 clean = cfgparse.get(nodetype, 'clean')
83 connect.logger.info("Post installation tasks....")
84 post_tasks(host, port, user, localkey, nodetype)
86 connect.logger.info("Cleaning down environment....")
87 connect.logger.info("Removing OpenSCAP....")
88 removepkg(host, port, user, localkey, nodetype)
89 connect.logger.info("Deleting tmp file and reports (remote)...")
90 cleandir(host, port, user, localkey, nodetype)
94 # Find compute nodes, active with network on ctlplane
95 for server in nova.servers.list():
96 if server.status == 'ACTIVE' and 'compute' in server.name:
97 networks = server.networks
99 for host in networks['ctlplane']:
100 run_tests(host, nodetype)
101 # Find controller nodes, active with network on ctlplane
102 elif server.status == 'ACTIVE' and 'controller' in server.name:
103 networks = server.networks
104 nodetype = 'controller'
105 for host in networks['ctlplane']:
106 run_tests(host, nodetype)
109 def createfiles(host, port, user, localkey):
112 localpath = functest_dir + 'scripts/createfiles.py'
113 remotepath = '/tmp/createfiles.py'
114 com = 'python /tmp/createfiles.py'
115 connect = connect.ConnectionManager(host, port, user, localkey,
116 localpath, remotepath, com)
117 tmpdir = connect.remotescript()
120 def install_pkg(host, port, user, localkey):
122 com = 'sudo yum -y install openscap-scanner scap-security-guide'
123 connect = connect.ConnectionManager(host, port, user, localkey, com)
127 def run_scanner(host, port, user, localkey, nodetype):
129 scantype = cfgparse.get(nodetype, 'scantype')
130 profile = cfgparse.get(nodetype, 'profile')
131 results = cfgparse.get(nodetype, 'results')
132 report = cfgparse.get(nodetype, 'report')
133 secpolicy = cfgparse.get(nodetype, 'secpolicy')
134 # Here is where we contruct the actual scan command
135 if scantype == 'xccdf':
136 cpe = cfgparse.get(nodetype, 'cpe')
137 com = '{0} xccdf eval --profile {1} --results {2}/{3}' \
138 ' --report {2}/{4} --cpe {5} {6}'.format(oscapbin,
145 connect = connect.ConnectionManager(host, port, user, localkey, com)
147 elif scantype == 'oval':
148 com = '{0} oval eval --results {1}/{2} '
149 '--report {1}/{3} {4}'.format(oscapbin, tmpdir.rstrip(),
150 results, report, secpolicy)
151 connect = connect.ConnectionManager(host, port, user, localkey, com)
154 com = '{0} oval-collect '.format(oscapbin)
155 connect = connect.ConnectionManager(host, port, user, localkey, com)
159 def post_tasks(host, port, user, localkey, nodetype):
161 # Create the download folder for functest dashboard and download reports
162 reports_dir = cfgparse.get(nodetype, 'reports_dir')
163 dl_folder = os.path.join(reports_dir, host + "_" +
165 now().strftime('%Y-%m-%d_%H-%M-%S'))
166 os.makedirs(dl_folder, 0755)
167 report = cfgparse.get(nodetype, 'report')
168 results = cfgparse.get(nodetype, 'results')
169 reportfile = '{0}/{1}'.format(tmpdir.rstrip(), report)
170 connect = connect.ConnectionManager(host, port, user, localkey, dl_folder,
171 reportfile, report, results)
172 connect.download_reports()
175 def removepkg(host, port, user, localkey, nodetype):
177 com = 'sudo yum -y remove openscap-scanner scap-security-guide'
178 connect = connect.ConnectionManager(host, port, user, localkey, com)
182 def cleandir(host, port, user, localkey, nodetype):
184 com = 'sudo rm -r {0}'.format(tmpdir.rstrip())
185 connect = connect.ConnectionManager(host, port, user, localkey, com)
189 if __name__ == '__main__':