def check_transport_value(ipaddr, transport): """ Check the given transport version against the given IP address. :param ipaddr: IP address to check. :param transport: ipt.TRANSPORT_AUTO, ipt.TRANSPORT_IPV4 or ipt.TRANSPORT_IPV6 :return: The correct ipt transport version. """ if transport == ipt.TRANSPORT_AUTO: if is_valid_ipv6_address(ipaddr): transport = ipt.TRANSPORT_IPV6 elif is_valid_ipv4_address(ipaddr): transport = ipt.TRANSPORT_IPV4 else: raise ValueError('Invalid transport version ({0}:{1})'.format(ipaddr, str(transport))) elif transport == ipt.TRANSPORT_IPV4: if not is_valid_ipv4_address(ipaddr): raise ValueError('Invalid transport version ({0}:{1})'.format(ipaddr, str(transport))) elif transport == ipt.TRANSPORT_IPV6: if not is_valid_ipv6_address(ipaddr): raise ValueError('Invalid transport version ({0}:{1})'.format(ipaddr, str(transport))) else: raise ValueError('Invalid transport version ({0}:{1})'.format(ipaddr, str(transport))) return transport
def check_transport_value(ipaddr, transport): """ Check the given transport version against the given IP address. :param ipaddr: IP address to check. :param transport: ipt.TRANSPORT_AUTO, ipt.TRANSPORT_IPV4 or ipt.TRANSPORT_IPV6 :return: The correct ipt transport version. """ if transport == ipt.TRANSPORT_AUTO: if is_valid_ipv6_address(ipaddr): transport = ipt.TRANSPORT_IPV6 elif is_valid_ipv4_address(ipaddr): transport = ipt.TRANSPORT_IPV4 else: raise ValueError('Invalid transport version ({0})'.format(transport)) elif transport == ipt.TRANSPORT_IPV4: if not is_valid_ipv4_address(ipaddr): raise ValueError('Invalid transport version ({0})'.format(transport)) elif transport == ipt.TRANSPORT_IPV6: if not is_valid_ipv6_address(ipaddr): raise ValueError('Invalid transport version ({0})'.format(transport)) else: raise ValueError('Invalid transport version ({0})'.format(transport)) return transport
def validate_config(self, config): """ Virtual Override Validate configuration file arguments and save values to our config object. :param config: A ConfigParser object. """ server = config.get(self._config_section_name, 'server') # Check for valid IPv4 address if '.' in server: if not is_valid_ipv4_address(server): _logger.error('{0}: Config value for "server" is invalid ip address'.format(self.get_name())) return False # Check for valid IPv6 address if ':' in server: if not is_valid_ipv6_address(server): _logger.error('{0}: Config value for "server" is invalid ip address'.format(self.get_name())) return False self._server = config.get(self._config_section_name, 'server') self._port = config.get(self._config_section_name, 'port') self._no_tls = True if config.get(self._config_section_name, 'use_tls').lower() == 'yes' else False self._bundle_name = config.get(self._config_section_name, 'bundle') return True
def validate_config(self, config): """ Virtual Override Validate configuration file arguments and save values to our config object. :param config: A ConfigParser object. """ server = config.get(self._config_section_name, 'server') # Check for valid IPv4 address if '.' in server: if not is_valid_ipv4_address(server): _logger.error( '{0}: Config value for "server" is invalid ip address'. format(self.get_name())) return False # Check for valid IPv6 address if ':' in server: if not is_valid_ipv6_address(server): _logger.error( '{0}: Config value for "server" is invalid ip address'. format(self.get_name())) return False self._server = config.get(self._config_section_name, 'server') self._port = config.get(self._config_section_name, 'port') self._no_tls = True if config.get( self._config_section_name, 'use_tls').lower() == 'yes' else False self._bundle_name = config.get(self._config_section_name, 'bundle') return True
def validate_arguments(self, args): """ Virtual Override Validate command line arguments and save values to our configuration object. :param args: An argparse object. """ # Check for conflicting arguments. if '--server-mod-disable' in sys.argv and ( '--server' in sys.argv or '--server-bundle' in sys.argv or '--server-user' in sys.argv or '--server-password' in sys.argv or '--server-no-tls' in sys.argv or '--server-port' in sys.argv): print('sdc-install: argument --server-mod-disable conficts with other server module arguments.') return False if args.server_mod_disable: self._enabled = False else: if not args.server: print('sdc-install: argument --server is required.') return False if not args.server_bundle: print('sdc-install: argument --server-bundle is required.') return False if not args.server_user: print('sdc-install: argument --server-user is required.') return False if not args.server_password: print('sdc-install: argument --server-password is required.') return False # Check for valid IPv4 address if '.' in args.server: if not is_valid_ipv4_address(args.server): print('sdc-install: argument --server is invalid ip address') return False # Check for valid IPv6 address if ':' in args.server: if not is_valid_ipv6_address(args.server): print('sdc-install: argument --server is invalid ip address') return False self._server = args.server self._port = args.server_port self._no_tls = args.server_no_tls self._bundle_name = args.server_bundle # User and password are only used during the install process self._user = args.server_user self._password = args.server_password return True
def validate_arguments(self, args): """ Virtual Override Validate command line arguments and save values to our configuration object. :param args: An argparse object. """ # Check for conflicting arguments. if '--server-mod-disable' in sys.argv and ( '--server' in sys.argv or '--server-bundle' in sys.argv or '--server-user' in sys.argv or '--server-password' in sys.argv or '--server-no-tls' in sys.argv or '--server-port' in sys.argv): print( 'sdc-install: argument --server-mod-disable conficts with other server module arguments.' ) return False if args.server_mod_disable: self._enabled = False else: if not args.server: print('sdc-install: argument --server is required.') return False if not args.server_bundle: print('sdc-install: argument --server-bundle is required.') return False if not args.server_user: print('sdc-install: argument --server-user is required.') return False if not args.server_password: print('sdc-install: argument --server-password is required.') return False # Check for valid IPv4 address if '.' in args.server: if not is_valid_ipv4_address(args.server): print('sdc-install: argument --server is invalid ip address') return False # Check for valid IPv6 address if ':' in args.server: if not is_valid_ipv6_address(args.server): print('sdc-install: argument --server is invalid ip address') return False self._server = args.server self._port = args.server_port self._no_tls = args.server_no_tls self._bundle_name = args.server_bundle # User and password are only used during the install process self._user = args.server_user self._password = args.server_password return True
def validate_config(self, config): """ Virtual Override Validate configuration file arguments and save values to our config object. :param config: A ConfigParser object. """ # See if we are enabled or not try: self._enabled = True if config.get( self._config_section_name, 'enabled').lower() == 'yes' else False except: _logger.debug( '{0} configuration section not found in configuration file.'. format(self._config_section_name)) self._enabled = False # Only worry about the rest of the configuration items if we are enabled. if self._enabled: server = config.get(self._config_section_name, 'server') # Check for valid IPv4 address if '.' in server: if not is_valid_ipv4_address(server): _logger.error( '{0}: Config value for "server" is invalid ip address'. format(self.get_name())) return False # Check for valid IPv6 address if ':' in server: if not is_valid_ipv6_address(server): _logger.error( '{0}: Config value for "server" is invalid ip address'. format(self.get_name())) return False self._server = config.get(self._config_section_name, 'server') self._no_tls = False if config.get( self._config_section_name, 'use_tls').lower() == 'yes' else True # Make sure the port value is an integer and in range try: self._port = int(config.get(self._config_section_name, 'port')) if not (1 < self._port <= 65536): _logger.error('{0}: port value out of range ({1})'.format( self.get_name(), self._port)) except ValueError: self._port = 80 if self._no_tls else 443 self._bundle_name = config.get(self._config_section_name, 'bundle') return True
def validate_arguments(self, args): """ Virtual Override Validate command line arguments and save values to our configuration object. :param args: An argparse object. """ # See if we have been enabled or not if '--server-mod-enable' not in sys.argv: return True if args.server_mod_enable: self._enabled = True if not args.server: print('sdc-install: argument --server is required.') return False if not args.server_bundle: print('sdc-install: argument --server-bundle is required.') return False if not args.server_user: print('sdc-install: argument --server-user is required.') return False if not args.server_password: print('sdc-install: argument --server-password is required.') return False # Check for valid IPv4 address if '.' in args.server: if not is_valid_ipv4_address(args.server): print('sdc-install: argument --server is invalid ip address') return False # Check for valid IPv6 address if ':' in args.server: if not is_valid_ipv6_address(args.server): print('sdc-install: argument --server is invalid ip address') return False self._server = args.server self._port = args.server_port self._no_tls = args.server_no_tls self._bundle_name = args.server_bundle # User and password are only used during the install process self._user = args.server_user self._password = args.server_password return True
def validate_config(self, config): """ Virtual Override Validate configuration file arguments and save values to our config object. :param config: A ConfigParser object. """ # See if we are enabled or not try: self._enabled = True if config.get(self._config_section_name, 'enabled').lower() == 'yes' else False except: _logger.debug('{0} configuration section not found in configuration file.'.format( self._config_section_name)) self._enabled = False # Only worry about the rest of the configuration items if we are enabled. if self._enabled: server = config.get(self._config_section_name, 'server') # Check for valid IPv4 address if '.' in server: if not is_valid_ipv4_address(server): _logger.error('{0}: Config value for "server" is invalid ip address'.format(self.get_name())) return False # Check for valid IPv6 address if ':' in server: if not is_valid_ipv6_address(server): _logger.error('{0}: Config value for "server" is invalid ip address'.format(self.get_name())) return False self._server = config.get(self._config_section_name, 'server') self._no_tls = False if config.get(self._config_section_name, 'use_tls').lower() == 'yes' else True # Make sure the port value is an integer and in range try: self._port = int(config.get(self._config_section_name, 'port')) if not (1 < self._port <= 65536): _logger.error('{0}: port value out of range ({1})'.format(self.get_name(), self._port)) except ValueError: self._port = 80 if self._no_tls else 443 self._bundle_name = config.get(self._config_section_name, 'bundle') return True
def apply_remote_config(self): rules = list() try: if self._uri.scheme == 'file': with open(self._uri.path) as handle: rq = handle.read().decode('utf-8') else: rq = requests.get(self._remote_config_url, verify=False) if rq.status_code != 200: _logger.error('{0}: unable to retrieve remote configuration'.format(self.get_name())) return except: _logger.error('{0}: unable to retrieve remote config rules'.format(self.get_name())) return try: if self._uri.scheme == 'file': rc = RemoteConfig(json.loads(rq)) rule_text = rq else: rc = RemoteConfig(rq.json()) rule_text = rq.text except: _logger.error('{0}: parsing remote configuration file failed'.format(self.get_name())) return # See if we should check the hash value against a DNS TXT lookup hash value if self._remote_config_dns_name: if not rc.hash_method or rc.hash_method not in ['sha1', 'sha256', 'sha512']: _logger.error('{0}: unsupported hashing algorithm in remote config ({1})'.format( self.get_name(), rc.hash_method)) return if rc.hash_method == 'sha1': hash_value = hashlib.sha1(rule_text).hexdigest() elif rc.hash_method == 'sha256': hash_value = hashlib.sha256(rule_text).hexdigest() elif rc.hash_method == 'sha512': hash_value = hashlib.sha512(rule_text).hexdigest() if self.get_remote_dns_hash() != hash_value: _logger.error('{0}: remote DNS TXT hash value does not match calculated hash'.format(self.get_name())) return _logger.debug('{0}: deleting rules for slot {1}'.format(self.get_name(), self._slot_config_apply)) task = QueueTask(TASK_FIREWALL_DELETE_SLOT, src_module=self.get_name(), dest_module=SilentDuneClientFirewallModule().get_name(), data=self._slot_config_apply) self.send_parent_task(task) for rule in rc.rules: try: # See if we need to try and resolve the host name if not is_valid_ipv6_address(rule.host) and not is_valid_ipv6_address(rule.host): addrs = self.get_ip_from_hostname(rule.host, rule.port) if not addrs: _logger.error('{0}: error: unable to resolve host {1}'.format(rule.host)) return for addr in addrs: _logger.debug('{0}: adding rules slot: {1}, ip address: {2}, port: {3}, protocol: {4}'.format( self.get_name(), self._slot_config_apply, addr, rule.port, rule.protocol)) rules.append(create_iptables_remote_config(addr, rule.mask, rule.port, rule.protocol, self._slot_config_apply, rule.uid, rule.gid, transport=ipt.TRANSPORT_AUTO)) else: _logger.debug('{0}: adding rules slot: {1}, ip address: {2}, port: {3}, protocol: {4}'.format( self.get_name(), self._slot_config_apply, rule.host, rule.port, rule.protocol)) rules.append(create_iptables_remote_config(rule.host, rule.mask, rule.port, rule.protocol, self._slot_config_apply, rule.uid, rule.gid, transport=ipt.TRANSPORT_AUTO)) except: _logger.error('{0}: parsing remote config rule failed.'.format(self.get_name())) if rules: task = QueueTask(TASK_FIREWALL_INSERT_RULES, src_module=self.get_name(), dest_module=SilentDuneClientFirewallModule().get_name(), data=rules) self.send_parent_task(task)
def apply_remote_config(self): rules = list() try: if self._uri.scheme == 'file': with open(self._uri.path) as handle: rq = handle.read().decode('utf-8') else: rq = requests.get(self._remote_config_url, verify=False) if rq.status_code != 200: _logger.error( '{0}: unable to retrieve remote configuration'.format( self.get_name())) return False except: _logger.error('{0}: unable to retrieve remote config rules'.format( self.get_name())) return False try: if self._uri.scheme == 'file': rc = RemoteConfig(json.loads(rq)) rule_text = rq else: rc = RemoteConfig(rq.json()) rule_text = rq.text except: _logger.error('{0}: parsing configuration json failed'.format( self.get_name())) return False # See if we should check the hash value against a DNS TXT lookup hash value if self._remote_config_dns_name: if not rc.hash_method or rc.hash_method not in [ 'sha1', 'sha256', 'sha512' ]: _logger.error( '{0}: unsupported hashing algorithm in remote config ({1})' .format(self.get_name(), rc.hash_method)) return False if rc.hash_method == 'sha1': hash_value = hashlib.sha1(rule_text).hexdigest() elif rc.hash_method == 'sha256': hash_value = hashlib.sha256(rule_text).hexdigest() elif rc.hash_method == 'sha512': hash_value = hashlib.sha512(rule_text).hexdigest() if self.get_remote_dns_hash() != hash_value: _logger.error( '{0}: remote DNS TXT hash value does not match calculated hash' .format(self.get_name())) return False _logger.debug('{0}: deleting rules for slot {1}'.format( self.get_name(), self._slot_config_apply)) task = QueueTask( TASK_FIREWALL_DELETE_SLOT, src_module=self.get_name(), dest_module=SilentDuneClientFirewallModule().get_name(), data=self._slot_config_apply) self.send_parent_task(task) for rule in rc.rules: try: # See if we need to try and resolve the host name if not is_valid_ipv6_address( rule.host) and not is_valid_ipv6_address(rule.host): addrs = self.get_ip_from_hostname(rule.host, rule.port) if not addrs: _logger.error( '{0}: error: unable to resolve rule host {1}'. format(self.get_name(), rule.host)) return False for addr in addrs: _logger.debug( '{0}: adding rules slot: {1}, ip address: {2}, port: {3}, protocol: {4}' .format(self.get_name(), self._slot_config_apply, addr, rule.port, rule.protocol)) rules.append( create_iptables_remote_config( addr, rule.mask, rule.port, rule.protocol, self._slot_config_apply, rule.uid, rule.gid, transport=ipt.TRANSPORT_AUTO)) else: _logger.debug( '{0}: adding rules slot: {1}, ip address: {2}, port: {3}, protocol: {4}' .format(self.get_name(), self._slot_config_apply, rule.host, rule.port, rule.protocol)) rules.append( create_iptables_remote_config( rule.host, rule.mask, rule.port, rule.protocol, self._slot_config_apply, rule.uid, rule.gid, transport=ipt.TRANSPORT_AUTO)) except: _logger.error('{0}: parsing remote config rule failed.'.format( self.get_name())) return False if rules: task = QueueTask( TASK_FIREWALL_INSERT_RULES, src_module=self.get_name(), dest_module=SilentDuneClientFirewallModule().get_name(), data=rules) self.send_parent_task(task) return True
def create_tcp_server_conn_rule(addr, port, transport=ipt.TRANSPORT_AUTO, slot=120, desc=''): """ Create a rule that allows access to the given addr and port. :param addr: IP address, not host name. :param port: :return: """ # Example: a = ipt.get_match(name='state', options=[ipt.get_match_option('--state', 'ESTABLISHED')]) if transport == ipt.TRANSPORT_AUTO: if is_valid_ipv6_address(addr): transport = ipt.TRANSPORT_IPV6 elif is_valid_ipv4_address(addr): transport = ipt.TRANSPORT_IPV4 else: raise ValueError elif transport == ipt.TRANSPORT_IPV4: if not is_valid_ipv4_address(addr): raise ValueError elif transport == ipt.TRANSPORT_IPV6: if not is_valid_ipv6_address(addr): raise ValueError else: raise ValueError return ipt.get_machine_subset( desc, slot, [ ipt.get_chain( 'filter', [ ipt.get_ring( 'input', transport, [ ipt.get_rule( ip_protocol_name='tcp', source_address=addr, matches=[ ipt.get_match('state', [ipt.get_jump_option('--state', 'ESTABLISHED'), ], ), ipt.get_match('tcp', [ipt.get_match_option('--sport', port), ], ), ], jump=ipt.get_jump(target='ACCEPT') )]), ipt.get_ring( 'output', transport, [ ipt.get_rule( ip_protocol_name='tcp', dest_address=addr, matches=[ ipt.get_match('state', [ipt.get_jump_option('--state', 'NEW,ESTABLISHED'), ], ), ipt.get_match('tcp', [ipt.get_match_option('--dport', port), ], ), ], jump=ipt.get_jump(target='ACCEPT') ) ] ), ] ) ] )