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("Checking internet for package installation...")
77 if internet_check(host, nodetype):
78 connect.logger.info("Internet Connection OK.")
79 connect.logger.info("Creating temp file structure..")
80 createfiles(host, port, user, localkey)
81 connect.logger.info("Installing OpenSCAP...")
82 install_pkg(host, port, user, localkey)
83 connect.logger.info("Running scan...")
84 run_scanner(host, port, user, localkey, nodetype)
85 clean = cfgparse.get(nodetype, 'clean')
86 connect.logger.info("Post installation tasks....")
87 post_tasks(host, port, user, localkey, nodetype)
89 connect.logger.info("Cleaning down environment....")
90 connect.logger.info("Removing OpenSCAP....")
91 removepkg(host, port, user, localkey, nodetype)
92 connect.logger.info("Deleting tmp file and reports (remote)...")
93 cleandir(host, port, user, localkey, nodetype)
95 connect.logger.error("Internet timeout. Moving on to next node..")
100 # Find compute nodes, active with network on ctlplane
101 for server in nova.servers.list():
102 if server.status == 'ACTIVE' and 'compute' in server.name:
103 networks = server.networks
105 for host in networks['ctlplane']:
106 run_tests(host, nodetype)
107 # Find controller nodes, active with network on ctlplane
108 elif server.status == 'ACTIVE' and 'controller' in server.name:
109 networks = server.networks
110 nodetype = 'controller'
111 for host in networks['ctlplane']:
112 run_tests(host, nodetype)
115 def internet_check(host, nodetype):
117 user = cfgparse.get(nodetype, 'user')
118 port = cfgparse.get(nodetype, 'port')
119 localpath = functest_dir + 'scripts/internet_check.py'
120 remotepath = '/tmp/internet_check.py'
121 com = 'python /tmp/internet_check.py'
122 testconnect = connect.ConnectionManager(host, port, user, localkey,
123 localpath, remotepath, com)
124 connectionresult = testconnect.remotescript()
125 if connectionresult.rstrip() == 'True':
131 def createfiles(host, port, user, localkey):
134 localpath = functest_dir + 'scripts/createfiles.py'
135 remotepath = '/tmp/createfiles.py'
136 com = 'python /tmp/createfiles.py'
137 connect = connect.ConnectionManager(host, port, user, localkey,
138 localpath, remotepath, com)
139 tmpdir = connect.remotescript()
142 def install_pkg(host, port, user, localkey):
144 com = 'sudo yum -y install openscap-scanner scap-security-guide'
145 connect = connect.ConnectionManager(host, port, user, localkey, com)
149 def run_scanner(host, port, user, localkey, nodetype):
151 scantype = cfgparse.get(nodetype, 'scantype')
152 profile = cfgparse.get(nodetype, 'profile')
153 results = cfgparse.get(nodetype, 'results')
154 report = cfgparse.get(nodetype, 'report')
155 secpolicy = cfgparse.get(nodetype, 'secpolicy')
156 # Here is where we contruct the actual scan command
157 if scantype == 'xccdf':
158 cpe = cfgparse.get(nodetype, 'cpe')
159 com = '{0} xccdf eval --profile {1} --results {2}/{3}' \
160 ' --report {2}/{4} --cpe {5} {6}'.format(oscapbin,
167 connect = connect.ConnectionManager(host, port, user, localkey, com)
169 elif scantype == 'oval':
170 com = '{0} oval eval --results {1}/{2} '
171 '--report {1}/{3} {4}'.format(oscapbin, tmpdir.rstrip(),
172 results, report, secpolicy)
173 connect = connect.ConnectionManager(host, port, user, localkey, com)
176 com = '{0} oval-collect '.format(oscapbin)
177 connect = connect.ConnectionManager(host, port, user, localkey, com)
181 def post_tasks(host, port, user, localkey, nodetype):
183 # Create the download folder for functest dashboard and download reports
184 reports_dir = cfgparse.get(nodetype, 'reports_dir')
185 dl_folder = os.path.join(reports_dir, host + "_" +
187 now().strftime('%Y-%m-%d_%H-%M-%S'))
188 os.makedirs(dl_folder, 0755)
189 report = cfgparse.get(nodetype, 'report')
190 results = cfgparse.get(nodetype, 'results')
191 reportfile = '{0}/{1}'.format(tmpdir.rstrip(), report)
192 connect = connect.ConnectionManager(host, port, user, localkey, dl_folder,
193 reportfile, report, results)
194 connect.download_reports()
197 def removepkg(host, port, user, localkey, nodetype):
199 com = 'sudo yum -y remove openscap-scanner scap-security-guide'
200 connect = connect.ConnectionManager(host, port, user, localkey, com)
204 def cleandir(host, port, user, localkey, nodetype):
206 com = 'sudo rm -r {0}'.format(tmpdir.rstrip())
207 connect = connect.ConnectionManager(host, port, user, localkey, com)
211 if __name__ == '__main__':