Add log filter for sensitive info such as API keys
This commit is contained in:
		
							parent
							
								
									983467b035
								
							
						
					
					
						commit
						cb6249d31c
					
				
					 2 changed files with 106 additions and 37 deletions
				
			
		|  | @ -4,16 +4,17 @@ from sys import exit | ||||||
| from os.path import join, exists | from os.path import join, exists | ||||||
| 
 | 
 | ||||||
| from varken.helpers import clean_sid_check | from varken.helpers import clean_sid_check | ||||||
|  | from varken.varkenlogger import BlacklistFilter | ||||||
| from varken.structures import SonarrServer, RadarrServer, OmbiServer, TautulliServer, InfluxServer, CiscoASAFirewall | from varken.structures import SonarrServer, RadarrServer, OmbiServer, TautulliServer, InfluxServer, CiscoASAFirewall | ||||||
| 
 | 
 | ||||||
| logger = logging.getLogger() |  | ||||||
| 
 |  | ||||||
| 
 | 
 | ||||||
| class INIParser(object): | class INIParser(object): | ||||||
|     def __init__(self, data_folder): |     def __init__(self, data_folder): | ||||||
|         self.config = configparser.ConfigParser(interpolation=None) |         self.config = configparser.ConfigParser(interpolation=None) | ||||||
|         self.data_folder = data_folder |         self.data_folder = data_folder | ||||||
| 
 | 
 | ||||||
|  |         self.logger = logging.getLogger() | ||||||
|  | 
 | ||||||
|         self.influx_server = InfluxServer() |         self.influx_server = InfluxServer() | ||||||
| 
 | 
 | ||||||
|         self.sonarr_enabled = False |         self.sonarr_enabled = False | ||||||
|  | @ -33,25 +34,36 @@ class INIParser(object): | ||||||
| 
 | 
 | ||||||
|         self.parse_opts() |         self.parse_opts() | ||||||
| 
 | 
 | ||||||
|  |         self.filtered_strings = None | ||||||
|  | 
 | ||||||
|  |     def config_blacklist(self): | ||||||
|  |         filtered_strings = [section.get(k) for key, section in self.config.items() | ||||||
|  |                                  for k in section if k in BlacklistFilter.blacklisted_strings] | ||||||
|  |         self.filtered_strings = list(filter(None, filtered_strings)) | ||||||
|  |          | ||||||
|  |         for handler in self.logger.handlers: | ||||||
|  |             handler.addFilter(BlacklistFilter(set(self.filtered_strings))) | ||||||
|  | 
 | ||||||
|     def enable_check(self, server_type=None): |     def enable_check(self, server_type=None): | ||||||
|         t = server_type |         t = server_type | ||||||
|         try: |         try: | ||||||
|             global_server_ids = self.config.get('global', t) |             global_server_ids = self.config.get('global', t) | ||||||
|             if global_server_ids.lower() in ['false', 'no', '0']: |             if global_server_ids.lower() in ['false', 'no', '0']: | ||||||
|                 logger.info('%s disabled.', t.upper()) |                 self.logger.info('%s disabled.', t.upper()) | ||||||
|             else: |             else: | ||||||
|                 sids = clean_sid_check(global_server_ids, t) |                 sids = clean_sid_check(global_server_ids, t) | ||||||
|                 return sids |                 return sids | ||||||
|         except configparser.NoOptionError as e: |         except configparser.NoOptionError as e: | ||||||
|             logger.error(e) |             self.logger.error(e) | ||||||
| 
 | 
 | ||||||
|     def read_file(self): |     def read_file(self): | ||||||
|         file_path = join(self.data_folder, 'varken.ini') |         file_path = join(self.data_folder, 'varken.ini') | ||||||
|         if exists(file_path): |         if exists(file_path): | ||||||
|             with open(file_path) as config_ini: |             with open(file_path) as config_ini: | ||||||
|                 self.config.read_file(config_ini) |                 self.config.read_file(config_ini) | ||||||
|  |             self.config_blacklist() | ||||||
|         else: |         else: | ||||||
|             exit('Config file missing (varken.ini) in {}'.format(self.data_folder)) |             exit('Config file missing (varken.ini) in %s', self.data_folder) | ||||||
| 
 | 
 | ||||||
|     def parse_opts(self): |     def parse_opts(self): | ||||||
|         self.read_file() |         self.read_file() | ||||||
|  | @ -72,16 +84,23 @@ class INIParser(object): | ||||||
|                 try: |                 try: | ||||||
|                     url = self.config.get(sonarr_section, 'url') |                     url = self.config.get(sonarr_section, 'url') | ||||||
|                     apikey = self.config.get(sonarr_section, 'apikey') |                     apikey = self.config.get(sonarr_section, 'apikey') | ||||||
|                     scheme = 'https://' if self.config.getboolean(sonarr_section, 'ssl') else 'http://' |                     scheme = 'https://' if self.config.getboolean( | ||||||
|                     verify_ssl = self.config.getboolean(sonarr_section, 'verify_ssl') |                         sonarr_section, 'ssl') else 'http://' | ||||||
|  |                     verify_ssl = self.config.getboolean( | ||||||
|  |                         sonarr_section, 'verify_ssl') | ||||||
|                     if scheme != 'https://': |                     if scheme != 'https://': | ||||||
|                         verify_ssl = False |                         verify_ssl = False | ||||||
|                     queue = self.config.getboolean(sonarr_section, 'queue') |                     queue = self.config.getboolean(sonarr_section, 'queue') | ||||||
|                     missing_days = self.config.getint(sonarr_section, 'missing_days') |                     missing_days = self.config.getint( | ||||||
|                     future_days = self.config.getint(sonarr_section, 'future_days') |                         sonarr_section, 'missing_days') | ||||||
|                     missing_days_run_seconds = self.config.getint(sonarr_section, 'missing_days_run_seconds') |                     future_days = self.config.getint( | ||||||
|                     future_days_run_seconds = self.config.getint(sonarr_section, 'future_days_run_seconds') |                         sonarr_section, 'future_days') | ||||||
|                     queue_run_seconds = self.config.getint(sonarr_section, 'queue_run_seconds') |                     missing_days_run_seconds = self.config.getint( | ||||||
|  |                         sonarr_section, 'missing_days_run_seconds') | ||||||
|  |                     future_days_run_seconds = self.config.getint( | ||||||
|  |                         sonarr_section, 'future_days_run_seconds') | ||||||
|  |                     queue_run_seconds = self.config.getint( | ||||||
|  |                         sonarr_section, 'queue_run_seconds') | ||||||
| 
 | 
 | ||||||
|                     server = SonarrServer(server_id, scheme + url, apikey, verify_ssl, missing_days, |                     server = SonarrServer(server_id, scheme + url, apikey, verify_ssl, missing_days, | ||||||
|                                           missing_days_run_seconds, future_days, future_days_run_seconds, |                                           missing_days_run_seconds, future_days, future_days_run_seconds, | ||||||
|  | @ -89,7 +108,8 @@ class INIParser(object): | ||||||
|                     self.sonarr_servers.append(server) |                     self.sonarr_servers.append(server) | ||||||
|                 except configparser.NoOptionError as e: |                 except configparser.NoOptionError as e: | ||||||
|                     self.radarr_enabled = False |                     self.radarr_enabled = False | ||||||
|                     logger.error('%s disabled. Error: %s', sonarr_section, e) |                     self.logger.error( | ||||||
|  |                         '%s disabled. Error: %s', sonarr_section, e) | ||||||
| 
 | 
 | ||||||
|         # Parse Radarr options |         # Parse Radarr options | ||||||
|         self.radarr_enabled = self.enable_check('radarr_server_ids') |         self.radarr_enabled = self.enable_check('radarr_server_ids') | ||||||
|  | @ -100,21 +120,27 @@ class INIParser(object): | ||||||
|                 try: |                 try: | ||||||
|                     url = self.config.get(radarr_section, 'url') |                     url = self.config.get(radarr_section, 'url') | ||||||
|                     apikey = self.config.get(radarr_section, 'apikey') |                     apikey = self.config.get(radarr_section, 'apikey') | ||||||
|                     scheme = 'https://' if self.config.getboolean(radarr_section, 'ssl') else 'http://' |                     scheme = 'https://' if self.config.getboolean( | ||||||
|                     verify_ssl = self.config.getboolean(radarr_section, 'verify_ssl') |                         radarr_section, 'ssl') else 'http://' | ||||||
|  |                     verify_ssl = self.config.getboolean( | ||||||
|  |                         radarr_section, 'verify_ssl') | ||||||
|                     if scheme != 'https://': |                     if scheme != 'https://': | ||||||
|                         verify_ssl = False |                         verify_ssl = False | ||||||
|                     queue = self.config.getboolean(radarr_section, 'queue') |                     queue = self.config.getboolean(radarr_section, 'queue') | ||||||
|                     queue_run_seconds = self.config.getint(radarr_section, 'queue_run_seconds') |                     queue_run_seconds = self.config.getint( | ||||||
|                     get_missing = self.config.getboolean(radarr_section, 'get_missing') |                         radarr_section, 'queue_run_seconds') | ||||||
|                     get_missing_run_seconds = self.config.getint(radarr_section, 'get_missing_run_seconds') |                     get_missing = self.config.getboolean( | ||||||
|  |                         radarr_section, 'get_missing') | ||||||
|  |                     get_missing_run_seconds = self.config.getint( | ||||||
|  |                         radarr_section, 'get_missing_run_seconds') | ||||||
| 
 | 
 | ||||||
|                     server = RadarrServer(server_id, scheme + url, apikey, verify_ssl, queue, queue_run_seconds, |                     server = RadarrServer(server_id, scheme + url, apikey, verify_ssl, queue, queue_run_seconds, | ||||||
|                                           get_missing, get_missing_run_seconds) |                                           get_missing, get_missing_run_seconds) | ||||||
|                     self.radarr_servers.append(server) |                     self.radarr_servers.append(server) | ||||||
|                 except configparser.NoOptionError as e: |                 except configparser.NoOptionError as e: | ||||||
|                     self.radarr_enabled = False |                     self.radarr_enabled = False | ||||||
|                     logger.error('%s disabled. Error: %s', radarr_section, e) |                     self.logger.error( | ||||||
|  |                         '%s disabled. Error: %s', radarr_section, e) | ||||||
| 
 | 
 | ||||||
|         # Parse Tautulli options |         # Parse Tautulli options | ||||||
|         self.tautulli_enabled = self.enable_check('tautulli_server_ids') |         self.tautulli_enabled = self.enable_check('tautulli_server_ids') | ||||||
|  | @ -124,21 +150,27 @@ class INIParser(object): | ||||||
|                 tautulli_section = 'tautulli-' + str(server_id) |                 tautulli_section = 'tautulli-' + str(server_id) | ||||||
|                 try: |                 try: | ||||||
|                     url = self.config.get(tautulli_section, 'url') |                     url = self.config.get(tautulli_section, 'url') | ||||||
|                     fallback_ip = self.config.get(tautulli_section, 'fallback_ip') |                     fallback_ip = self.config.get( | ||||||
|  |                         tautulli_section, 'fallback_ip') | ||||||
|                     apikey = self.config.get(tautulli_section, 'apikey') |                     apikey = self.config.get(tautulli_section, 'apikey') | ||||||
|                     scheme = 'https://' if self.config.getboolean(tautulli_section, 'ssl') else 'http://' |                     scheme = 'https://' if self.config.getboolean( | ||||||
|                     verify_ssl = self.config.getboolean(tautulli_section, 'verify_ssl') |                         tautulli_section, 'ssl') else 'http://' | ||||||
|  |                     verify_ssl = self.config.getboolean( | ||||||
|  |                         tautulli_section, 'verify_ssl') | ||||||
|                     if scheme != 'https://': |                     if scheme != 'https://': | ||||||
|                         verify_ssl = False |                         verify_ssl = False | ||||||
|                     get_activity = self.config.getboolean(tautulli_section, 'get_activity') |                     get_activity = self.config.getboolean( | ||||||
|                     get_activity_run_seconds = self.config.getint(tautulli_section, 'get_activity_run_seconds') |                         tautulli_section, 'get_activity') | ||||||
|  |                     get_activity_run_seconds = self.config.getint( | ||||||
|  |                         tautulli_section, 'get_activity_run_seconds') | ||||||
| 
 | 
 | ||||||
|                     server = TautulliServer(server_id, scheme + url, fallback_ip, apikey, verify_ssl, get_activity, |                     server = TautulliServer(server_id, scheme + url, fallback_ip, apikey, verify_ssl, get_activity, | ||||||
|                                             get_activity_run_seconds) |                                             get_activity_run_seconds) | ||||||
|                     self.tautulli_servers.append(server) |                     self.tautulli_servers.append(server) | ||||||
|                 except configparser.NoOptionError as e: |                 except configparser.NoOptionError as e: | ||||||
|                     self.tautulli_enabled = False |                     self.tautulli_enabled = False | ||||||
|                     logger.error('%s disabled. Error: %s', tautulli_section, e) |                     self.logger.error( | ||||||
|  |                         '%s disabled. Error: %s', tautulli_section, e) | ||||||
| 
 | 
 | ||||||
|         # Parse Ombi options |         # Parse Ombi options | ||||||
|         self.ombi_enabled = self.enable_check('ombi_server_ids') |         self.ombi_enabled = self.enable_check('ombi_server_ids') | ||||||
|  | @ -149,21 +181,28 @@ class INIParser(object): | ||||||
|                 try: |                 try: | ||||||
|                     url = self.config.get(ombi_section, 'url') |                     url = self.config.get(ombi_section, 'url') | ||||||
|                     apikey = self.config.get(ombi_section, 'apikey') |                     apikey = self.config.get(ombi_section, 'apikey') | ||||||
|                     scheme = 'https://' if self.config.getboolean(ombi_section, 'ssl') else 'http://' |                     scheme = 'https://' if self.config.getboolean( | ||||||
|                     verify_ssl = self.config.getboolean(ombi_section, 'verify_ssl') |                         ombi_section, 'ssl') else 'http://' | ||||||
|  |                     verify_ssl = self.config.getboolean( | ||||||
|  |                         ombi_section, 'verify_ssl') | ||||||
|                     if scheme != 'https://': |                     if scheme != 'https://': | ||||||
|                         verify_ssl = False |                         verify_ssl = False | ||||||
|                     request_type_counts = self.config.getboolean(ombi_section, 'get_request_type_counts') |                     request_type_counts = self.config.getboolean( | ||||||
|                     request_type_run_seconds = self.config.getint(ombi_section, 'request_type_run_seconds') |                         ombi_section, 'get_request_type_counts') | ||||||
|                     request_total_counts = self.config.getboolean(ombi_section, 'get_request_total_counts') |                     request_type_run_seconds = self.config.getint( | ||||||
|                     request_total_run_seconds = self.config.getint(ombi_section, 'request_total_run_seconds') |                         ombi_section, 'request_type_run_seconds') | ||||||
|  |                     request_total_counts = self.config.getboolean( | ||||||
|  |                         ombi_section, 'get_request_total_counts') | ||||||
|  |                     request_total_run_seconds = self.config.getint( | ||||||
|  |                         ombi_section, 'request_total_run_seconds') | ||||||
| 
 | 
 | ||||||
|                     server = OmbiServer(server_id, scheme + url, apikey, verify_ssl, request_type_counts, |                     server = OmbiServer(server_id, scheme + url, apikey, verify_ssl, request_type_counts, | ||||||
|                                         request_type_run_seconds, request_total_counts, request_total_run_seconds) |                                         request_type_run_seconds, request_total_counts, request_total_run_seconds) | ||||||
|                     self.ombi_servers.append(server) |                     self.ombi_servers.append(server) | ||||||
|                 except configparser.NoOptionError as e: |                 except configparser.NoOptionError as e: | ||||||
|                     self.ombi_enabled = False |                     self.ombi_enabled = False | ||||||
|                     logger.error('%s disabled. Error: %s', ombi_section, e) |                     self.logger.error( | ||||||
|  |                         '%s disabled. Error: %s', ombi_section, e) | ||||||
| 
 | 
 | ||||||
|         # Parse ASA opts |         # Parse ASA opts | ||||||
|         self.ciscoasa_enabled = self.enable_check('ciscoasa_firewall_ids') |         self.ciscoasa_enabled = self.enable_check('ciscoasa_firewall_ids') | ||||||
|  | @ -175,16 +214,21 @@ class INIParser(object): | ||||||
|                     url = self.config.get(ciscoasa_section, 'url') |                     url = self.config.get(ciscoasa_section, 'url') | ||||||
|                     username = self.config.get(ciscoasa_section, 'username') |                     username = self.config.get(ciscoasa_section, 'username') | ||||||
|                     password = self.config.get(ciscoasa_section, 'password') |                     password = self.config.get(ciscoasa_section, 'password') | ||||||
|                     scheme = 'https://' if self.config.getboolean(ciscoasa_section, 'ssl') else 'http://' |                     scheme = 'https://' if self.config.getboolean( | ||||||
|                     verify_ssl = self.config.getboolean(ciscoasa_section, 'verify_ssl') |                         ciscoasa_section, 'ssl') else 'http://' | ||||||
|  |                     verify_ssl = self.config.getboolean( | ||||||
|  |                         ciscoasa_section, 'verify_ssl') | ||||||
|                     if scheme != 'https://': |                     if scheme != 'https://': | ||||||
|                         verify_ssl = False |                         verify_ssl = False | ||||||
|                     outside_interface = self.config.get(ciscoasa_section, 'outside_interface') |                     outside_interface = self.config.get( | ||||||
|                     get_bandwidth_run_seconds = self.config.getint(ciscoasa_section, 'get_bandwidth_run_seconds') |                         ciscoasa_section, 'outside_interface') | ||||||
|  |                     get_bandwidth_run_seconds = self.config.getint( | ||||||
|  |                         ciscoasa_section, 'get_bandwidth_run_seconds') | ||||||
| 
 | 
 | ||||||
|                     firewall = CiscoASAFirewall(firewall_id, scheme + url, username, password, outside_interface, |                     firewall = CiscoASAFirewall(firewall_id, scheme + url, username, password, outside_interface, | ||||||
|                                                 verify_ssl, get_bandwidth_run_seconds) |                                                 verify_ssl, get_bandwidth_run_seconds) | ||||||
|                     self.ciscoasa_firewalls.append(firewall) |                     self.ciscoasa_firewalls.append(firewall) | ||||||
|                 except configparser.NoOptionError as e: |                 except configparser.NoOptionError as e: | ||||||
|                     self.ciscoasa_enabled = False |                     self.ciscoasa_enabled = False | ||||||
|                     logger.error('%s disabled. Error: %s', ciscoasa_section, e) |                     self.logger.error( | ||||||
|  |                         '%s disabled. Error: %s', ciscoasa_section, e) | ||||||
|  |  | ||||||
|  | @ -3,12 +3,37 @@ import logging | ||||||
| from logging.handlers import RotatingFileHandler | from logging.handlers import RotatingFileHandler | ||||||
| from varken.helpers import mkdir_p | from varken.helpers import mkdir_p | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
| FILENAME = "varken.log" | FILENAME = "varken.log" | ||||||
| MAX_SIZE = 5000000  # 5 MB | MAX_SIZE = 5000000  # 5 MB | ||||||
| MAX_FILES = 5 | MAX_FILES = 5 | ||||||
| LOG_FOLDER = 'logs' | LOG_FOLDER = 'logs' | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | # Taken from Hellowlol/HTPC-Manager/Tautulli | ||||||
|  | class BlacklistFilter(logging.Filter): | ||||||
|  |     """ | ||||||
|  |     Log filter for blacklisted tokens and passwords | ||||||
|  |     """ | ||||||
|  |     blacklisted_strings = ['apikey',  'username',  'password'] | ||||||
|  | 
 | ||||||
|  |     def __init__(self, filteredstrings): | ||||||
|  |         self.filtered_strings = filteredstrings | ||||||
|  | 
 | ||||||
|  |     def filter(self, record): | ||||||
|  |         for item in self.filtered_strings: | ||||||
|  |             try: | ||||||
|  |                 if item in record.msg: | ||||||
|  |                     record.msg = record.msg.replace(item, 8 * '*' + item[-2:]) | ||||||
|  |                 if any(item in str(arg) for arg in record.args): | ||||||
|  |                     record.args = tuple(arg.replace(item, 8 * '*' + item[-2:]) if isinstance(arg, str) else arg | ||||||
|  |                                         for arg in record.args) | ||||||
|  | 
 | ||||||
|  |             except: | ||||||
|  |                 pass | ||||||
|  |         return True | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| class VarkenLogger(object): | class VarkenLogger(object): | ||||||
|     """docstring for .""" |     """docstring for .""" | ||||||
|     def __init__(self, log_path=None, debug=None, data_folder=None): |     def __init__(self, log_path=None, debug=None, data_folder=None): | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue