#!/bin/sh '''': for pyint in python3 python python2; do which $pyint >/dev/null 2>&1 && exec $pyint "$0" "$@" done echo "$0: No python could be found" >&2 exit 1 # ''' import argparse import os import re import shlex import subprocess import sys import syslog parser = argparse.ArgumentParser() parser.add_argument('--verbose', '-v', action='count', default=0) parser.add_argument('--silent', action='store_true', default=False) args = parser.parse_args() if args.silent: args.verbose = -1 if args.verbose >= 0: syslog.openlog( ident=sys.argv[0], logoption=syslog.LOG_PID, facility=syslog.LOG_LOCAL3 | syslog.LOG_ERR ) allowed = [ ##### System informations r'^/usr/bin/lsb_release\s+-d$', # Linux r'^/(usr/)?bin/uname\s+-mrs$', # Linux, BSD & others r'''^/(usr/)?s?bin/awk -F'"' (-e\s*)?'/PRETTY_NAME/{ print \$2; }' /etc/os-release''', # Linux: /etc/os-release via awk for get_os.py ##### Complete command lines (Monitoring-Plugins on Debian) r'^/usr/lib/nagios/plugins/check_disk -w \d+% -c \d+% -p /[/a-z]*$', r'^/usr/lib/nagios/plugins/check_load -w \d+(,\d+,\d+)? -c \d+(,\d+,\d+)?$', r'^/usr/lib/nagios/plugins/check_mysql -u [a-z]+ -p [0-9a-zA-Z]+', r'^/usr/lib/nagios/plugins/check_mysql_health --user(name)?=[a-z]+ --pass(word)?=[0-9a-zA-Z]+ --mode=[a-z-]+$', ##### Simplified/combined (and a little bit less secure) ### most Linux distributions (with "sudo" and "doas") # r'^/usr/lib(64)?/(nagios/plugins|monitoring-plugins)/check_', # r'^sudo\s+/usr/lib(64)?/(nagios/plugins|monitoring-plugins)/check_', # r'^doas\s+/usr/lib(64)?/(nagios/plugins|monitoring-plugins)/check_', ### *BSD (with "sudo" and "doas") # r'^/usr/local/libexec/nagios/check_', # r'^sudo\s+/usr/local/libexec/nagios/check_', # r'^doas\s+/usr/local/libexec/nagios/check_', ] cmdline = os.getenv('SSH_ORIGINAL_COMMAND') if not cmdline: print('This is just a wrapper, no command specified!') if args.verbose >= 0: syslog.syslog('Called without SSH_ORIGINAL_COMMAND') sys.exit(3) for maybe in allowed: if re.match(maybe, cmdline): if args.verbose >= 2: syslog.syslog(syslog.LOG_INFO, 'Found command line >%s< with regexp >%s<' % ( cmdline, maybe ) ) cmdlinelist = shlex.split(cmdline) try: cmd = subprocess.Popen(cmdlinelist, stdout=subprocess.PIPE) except Exception as exc: print('Could not execute plugin: %s' % exc) if args.verbose >= 0: syslog.syslog('Could not execute plugin >%s<' % cmdline) sys.exit(3) else: (out, outerr) = cmd.communicate() out = out.rstrip().decode('utf-8') outerr = (outerr or b'').rstrip().decode('utf-8') print(out) if args.verbose >= 1: syslog.syslog('Executed command line >%s<' % cmdline) if args.verbose >= 3: syslog.syslog('Output >%s<, Error >%s<' % (out, outerr)) sys.exit(cmd.returncode) print('%s: No allowed command found!' % sys.argv[0]) if args.verbose >= 0: syslog.syslog('No allowed command found for >%s<' % cmdline) sys.exit(3)