Added diagnostics script (#141)
This commit is contained in:
parent
5091308d0b
commit
9939dc3bf4
191
server/backend/diagnostics.py
Normal file
191
server/backend/diagnostics.py
Normal file
@ -0,0 +1,191 @@
|
||||
#!/usr/bin/python
|
||||
import os
|
||||
import subprocess
|
||||
import platform
|
||||
import socket
|
||||
import pkg_resources
|
||||
import psutil
|
||||
|
||||
__author__ = 'Eugeny N Ablesov'
|
||||
__version__ = '1.0.17'
|
||||
|
||||
def collect_accounts_info():
|
||||
""" This call collects generic information about
|
||||
user accounts presented on system running TinyCheck.
|
||||
|
||||
No personal information collected or provided by this call.
|
||||
"""
|
||||
accs = { }
|
||||
users = psutil.users()
|
||||
for user in users:
|
||||
accs[user.name + '@' + user.host] = {
|
||||
'started': user.started,
|
||||
'term': user.terminal
|
||||
}
|
||||
alt_user = os.getenv('SUDO_USER', os.getenv('USER'))
|
||||
usr = 'root' if os.path.expanduser('~') == '/root' else alt_user
|
||||
pid = psutil.Process().pid
|
||||
term = psutil.Process().terminal() if 'Linux' in platform.system() else 'win'
|
||||
accs[usr + '@' + term] = { 'pid': pid }
|
||||
return accs
|
||||
|
||||
def collect_os_info():
|
||||
""" This call collects generic information about
|
||||
operating system running TinyCheck.
|
||||
|
||||
No personal information collected or provided by this call.
|
||||
"""
|
||||
os_info = { }
|
||||
os_info['system'] = platform.system()
|
||||
os_info['release'] = platform.release()
|
||||
os_info['version'] = platform.version()
|
||||
os_info['platform'] = platform.platform(aliased=True)
|
||||
if 'Windows' in os_info['system']:
|
||||
os_info['dist'] = platform.win32_ver()
|
||||
if 'Linux' in os_info['system']:
|
||||
os_info['dist'] = platform.libc_ver()
|
||||
return os_info
|
||||
|
||||
def collect_hardware_info():
|
||||
""" This call collects information about hardware running TinyCheck.
|
||||
|
||||
No personal information collected or provided by this call.
|
||||
"""
|
||||
hw_info = { }
|
||||
hw_info['arch'] = platform.architecture()
|
||||
hw_info['machine'] = platform.machine()
|
||||
hw_info['cpus'] = psutil.cpu_count(logical=False)
|
||||
hw_info['cores'] = psutil.cpu_count()
|
||||
hw_info['load'] = psutil.getloadavg()
|
||||
disk_info = psutil.disk_usage('/')
|
||||
hw_info['disk'] = {
|
||||
'total': disk_info.total,
|
||||
'used': disk_info.used,
|
||||
'free': disk_info.free
|
||||
}
|
||||
return hw_info
|
||||
|
||||
def collect_network_info():
|
||||
""" This call collects information about
|
||||
network configuration and state running TinyCheck.
|
||||
|
||||
No personal information collected or provided by this call.
|
||||
"""
|
||||
net_info = { }
|
||||
net_info['namei'] = socket.if_nameindex()
|
||||
addrs = psutil.net_if_addrs()
|
||||
state = psutil.net_io_counters(pernic=True)
|
||||
for interface in addrs.keys():
|
||||
net_info[interface] = { }
|
||||
int_info = state[interface]
|
||||
props = [p for p in dir(int_info)
|
||||
if not p.startswith("_")
|
||||
and not p == "index"
|
||||
and not p == "count"]
|
||||
for prop in props:
|
||||
net_info[interface][prop] = getattr(int_info, prop)
|
||||
return net_info
|
||||
|
||||
def collect_dependency_info(package_list):
|
||||
""" This call collects information about
|
||||
python packages required to run TinyCheck.
|
||||
|
||||
No personal information collected or provided by this call.
|
||||
"""
|
||||
dependencies = { }
|
||||
installed_packages = list(pkg_resources.working_set)
|
||||
installed_packages_list = sorted(["%s==%s"
|
||||
% (installed.key, installed.version)
|
||||
for installed in installed_packages])
|
||||
for pkg in installed_packages_list:
|
||||
[package_name, package_version] = pkg.split('==')
|
||||
if package_name in package_list:
|
||||
dependencies[package_name] = package_version
|
||||
return dependencies
|
||||
|
||||
def collect_db_tables_records_count(db_path, tables):
|
||||
result = { }
|
||||
for table in tables:
|
||||
query = 'SELECT COUNT(*) FROM %s' % (table)
|
||||
sqlite_call = subprocess.Popen(['sqlite3', db_path, query], stdout = subprocess.PIPE)
|
||||
stout, sterr = sqlite_call.communicate()
|
||||
val = stout.decode("utf-8")
|
||||
recs = int(val) if val else 0
|
||||
result[table] = recs
|
||||
return result
|
||||
|
||||
def collect_internal_state(db_path, tables, to_check):
|
||||
""" This call collects information about
|
||||
installed TinyCheck instance and its internal state.
|
||||
|
||||
No personal information collected or provided by this call.
|
||||
"""
|
||||
state_ = { }
|
||||
available = os.path.isfile(db_path)
|
||||
dbsize = 0
|
||||
state_['db'] = {
|
||||
'available': available,
|
||||
'size': dbsize
|
||||
}
|
||||
state_['db']['records'] = { }
|
||||
if available:
|
||||
state_['db']['size'] = os.stat(db_path).st_size
|
||||
state_['db']['records'] = collect_db_tables_records_count(db_path, tables)
|
||||
|
||||
services_ = { }
|
||||
for alias in to_check:
|
||||
status = subprocess.call(['systemctl', 'is-active', '--quiet', '%s' % (to_check[alias])])
|
||||
state = ''
|
||||
if status != 0:
|
||||
sysctl_call = subprocess.Popen(
|
||||
["systemctl", "status", "%s" % (to_check[alias]),
|
||||
r"|",
|
||||
"grep",
|
||||
r"''"],
|
||||
stdout = subprocess.PIPE,
|
||||
stderr = subprocess.PIPE)
|
||||
stout, sterr = sysctl_call.communicate()
|
||||
state = stout.decode("utf-8")
|
||||
errs = sterr.decode("utf-8")
|
||||
if "could not be found" in errs:
|
||||
state = 'Service not found'
|
||||
services_[alias] = {
|
||||
'running': status == 0,
|
||||
'status': status,
|
||||
'state': state
|
||||
}
|
||||
state_['svc'] = services_
|
||||
return state_
|
||||
|
||||
def main():
|
||||
print("TinyCheck diagnostics script.\nVersion: %s" % (__version__))
|
||||
print("")
|
||||
|
||||
db_path = '/usr/share/tinycheck/tinycheck.sqlite3'
|
||||
tables = ['iocs', 'whitelist', 'misp']
|
||||
services = { }
|
||||
services['frontend'] = 'tinycheck-frontend.service'
|
||||
services['backend'] = 'tinycheck-backend.service'
|
||||
services['kiosk'] = 'tinycheck-kiosk.service'
|
||||
services['watchers'] = 'tinycheck-watchers.service'
|
||||
|
||||
deps = [
|
||||
'pymisp', 'sqlalchemy', 'ipwhois',
|
||||
'netaddr', 'flask', 'flask_httpauth',
|
||||
'pyjwt', 'psutil', 'pydig', 'pyudev',
|
||||
'pyyaml', 'wifi', 'qrcode', 'netifaces',
|
||||
'weasyprint', 'python-whois', 'six' ]
|
||||
|
||||
diagnostics = { }
|
||||
diagnostics['acc'] = collect_accounts_info()
|
||||
diagnostics['os'] = collect_os_info()
|
||||
diagnostics['hw'] = collect_hardware_info()
|
||||
diagnostics['net'] = collect_network_info()
|
||||
diagnostics['deps'] = collect_dependency_info(deps)
|
||||
diagnostics['state'] = collect_internal_state(db_path, tables, services)
|
||||
report = { 'diagnostics': diagnostics }
|
||||
print(report)
|
||||
print("")
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
Loading…
Reference in New Issue
Block a user