def __init__(self,
              fauxapi_host,
              fauxapi_apikey,
              fauxapi_apisecret,
              debug=False):
     self.FauxapiLib = FauxapiLib(fauxapi_host, fauxapi_apikey,
                                  fauxapi_apisecret, debug)
Пример #2
0
 def __init__(self, config_file):
     """Program to send pfSense information collected from FauxAPI to InfluxDB"""
     self.config = configparser.ConfigParser()
     self.config.read(config_file)
     self.fauxapi = FauxapiLib(self.config['FAUXAPI']['APIHost'],
                               self.config['FAUXAPI']['APIKey'],
                               self.config['FAUXAPI']['APISecret'])
     self.influx_client = InfluxDBClient(
         host=self.config['INFLUXDB']['InfluxDBHost'],
         port=self.config['INFLUXDB']['Port'],
         username=self.config['INFLUXDB']['Username'],
         password=self.config['INFLUXDB']['Password'],
         database=self.config['INFLUXDB']['Database'])
     self.pfSense_config = self.fauxapi.config_get()
     self.pfSense_host = self.pfSense_config['system'][
         'hostname'] + "." + self.pfSense_config['system']['domain']
class UpdateAwsAliasesFauxapi():

    fauxapi_host = None
    fauxapi_apikey = None
    fauxapi_apisecret = None

    system_config= None
    aws_ipranges_uri = 'https://ip-ranges.amazonaws.com/ip-ranges.json'

    FauxapiLib = None

    def __init__(self, fauxapi_host, fauxapi_apikey, fauxapi_apisecret, debug=False):
        self.FauxapiLib = FauxapiLib(fauxapi_host, fauxapi_apikey, fauxapi_apisecret, debug)

    def update(self, regions_match='*', services_match='*', ipv4=True, ipv6=True):

        # Use FauxapiLib to load the remote system config into memory
        self.system_config = self.FauxapiLib.config_get()

        # download ip-ranges.json parse and iterate
        for name, data in sorted(self.get_aws_ipranges().items()):
            if regions_match == '*' or regions_match.replace('*','').replace('-','').lower() in name:
                if services_match == '*' or services_match.replace('*', '').replace('_', '').lower() in name:
                    addresses = []
                    if ipv4 is True and len(data['ipv4']) > 0:
                        addresses += data['ipv4']
                    if ipv6 is True and len(data['ipv6']) > 0:
                        addresses += data['ipv6']
                    self.update_alias_in_config(
                        name=name,
                        description=data['description'],
                        addresses=addresses,
                        aws_create_date=data['aws_create_date']
                    )

        # Use FauxapiLib to save to the remote system the new edited config
        result = self.FauxapiLib.config_set(self.system_config)
        print(json.dumps(result))

    def update_alias_in_config(self, name, description, addresses, aws_create_date):

        addresses.sort()

        # candidate alias to apply
        alias_data = {
            'name': name,
            'type': 'network',
            'address': ' '.join(addresses),
            'descr': description,
            'detail': '||'.join(['ip-ranges.json createDate: {}'.format(aws_create_date)] * len(addresses))
        }

        if 'aliases' not in self.system_config or type(self.system_config['aliases']) is not dict:
            self.system_config['aliases'] = {}

        if 'alias' not in self.system_config['aliases'] or type(self.system_config['aliases']['alias']) is not list:
            self.system_config['aliases']['alias'] = []

        alias_found = False
        for index, alias in enumerate(self.system_config['aliases']['alias']):
            if alias['name'] == name:
                alias_found = True
                if alias['address'] != alias_data['address']:
                    self.system_config['aliases']['alias'][index] = alias_data

        if alias_found is False:
            self.system_config['aliases']['alias'].append(alias_data)

    def get_aws_ipranges(self):

        with urllib.request.urlopen(self.aws_ipranges_uri) as response:
            aws_ipranges_data = json.loads(response.read())

        ipranges = {}
        for prefix in aws_ipranges_data['prefixes'] + aws_ipranges_data['ipv6_prefixes']:

            name = 'aws_{}_{}'.format(
                prefix['region'].replace('-','').lower(),
                prefix['service'].replace('_','').lower()
            )[:32]

            if name not in ipranges:
                ipranges[name] = {
                    'ipv4': [],
                    'ipv6': [],
                    'description': 'AWS {region} {service}'.format(region=prefix['region'], service=prefix['service']),
                    'aws_create_date': aws_ipranges_data['createDate']
                }

            if 'ip_prefix' in prefix and len(prefix['ip_prefix']) > 0:
                ipranges[name]['ipv4'].append(prefix['ip_prefix'])

            if 'ipv6_prefix' in prefix and len(prefix['ipv6_prefix']) > 0:
                ipranges[name]['ipv6'].append(prefix['ipv6_prefix'])

        return ipranges
Пример #4
0
# check args exist
if (len(sys.argv) < 4):
    print('usage: ' + sys.argv[0] +
          ' <host> <apikey> <apisecret> <rule category> <enable|disable>')
    sys.exit(1)

# config
fauxapi_host = sys.argv[1]
fauxapi_apikey = sys.argv[2]
fauxapi_apisecret = sys.argv[3]
rule_category = sys.argv[4]
rule_action = sys.argv[5]

FauxapiLib = FauxapiLib(fauxapi_host,
                        fauxapi_apikey,
                        fauxapi_apisecret,
                        debug=False)

# Get the current set of filters
filters = FauxapiLib.config_get('filter')

# Iterate through and find 'KinderControl' rules, find enable/disable
i = 0
for rule in filters['rule']:
    if (rule['descr'].startswith(rule_prefix)):
        if (rule_category in rule['descr']):
            if (rule_action == "enable"):
                del filters['rule'][i]['disabled']
                print("Rule {} enabled.".format(rule['descr']))
            elif (rule_action == "disable"):
                filters['rule'][i]['disabled'] = ""
class UserGroupManagementFauxapi():

    fauxapi_host = None
    fauxapi_apikey = None
    fauxapi_apisecret = None

    system_config = None

    FauxapiLib = None

    def __init__(self,
                 fauxapi_host,
                 fauxapi_apikey,
                 fauxapi_apisecret,
                 debug=False):
        self.FauxapiLib = FauxapiLib(fauxapi_host, fauxapi_apikey,
                                     fauxapi_apisecret, debug)

    # user functions
    # =========================================================================

    def get_users(self):
        self._reload_system_config()

        response_data = {}
        for user in self.system_config['system']['user']:
            response_data[user['name']] = user
            del (response_data[user['name']]['name'])
        return response_data

    def add_user(self, username):
        self._reload_system_config()

        user_index, user = self._get_entity('user', username)
        if user_index is not None:
            raise UserGroupManagementFauxapiException('user already exists',
                                                      username)

        user = {
            'scope': 'user',
            'bcrypt-hash': 'no-password-set',
            'descr': '',
            'name': username,
            'expires': '',
            'dashboardcolumns': '2',
            'authorizedkeys': '',
            'ipsecpsk': '',
            'webguicss': 'pfSense.css',
            'uid': self._get_next_id('uid'),
        }

        patch_system_user = {
            'system': {
                'user': self.system_config['system']['user']
            }
        }
        patch_system_user['system']['user'].append(user)

        response = self.FauxapiLib.config_patch(patch_system_user)
        if response['message'] != 'ok':
            raise UserGroupManagementFauxapiException('unable to add user',
                                                      response['message'])

        self._increment_next_id('uid')

        return user

    def manage_user(self, username, attributes):
        self._reload_system_config()

        valid_attributes = [
            'password', 'descr', 'expires', 'dashboardcolumns',
            'authorizedkeys', 'ipsecpsk', 'webguicss', 'disabled', 'priv'
        ]

        user_index, user = self._get_entity('user', username)
        if user_index is None:
            raise UserGroupManagementFauxapiException('user does not exist',
                                                      username)

        if type(attributes) != dict:
            raise UserGroupManagementFauxapiException(
                'attributes is incorrect type')

        for attribute, value in attributes.items():
            if attribute not in valid_attributes:
                raise UserGroupManagementFauxapiException(
                    'unsupported attribute type', attribute)

            if attribute == 'disabled':
                if value is True:
                    user[attribute] = ''
                else:
                    if attribute in user:
                        del (user[attribute])
            elif attribute == 'password':
                user['bcrypt-hash'] = bcrypt.hashpw(
                    value.encode('utf8'), bcrypt.gensalt()).decode('utf8')
            else:
                if len(value) == 0 and attribute in user:
                    del (user[attribute])
                elif len(value) > 0:
                    user[attribute] = value

        patch_system_user = {
            'system': {
                'user': self.system_config['system']['user']
            }
        }
        patch_system_user['system']['user'][user_index] = user

        response = self.FauxapiLib.config_patch(patch_system_user)
        if response['message'] != 'ok':
            raise UserGroupManagementFauxapiException('unable to manage user',
                                                      response['message'])

        return user

    def remove_user(self, username):
        self._reload_system_config()

        user_index, user = self._get_entity('user', username)
        if user_index is None:
            raise UserGroupManagementFauxapiException('user does not exist',
                                                      username)

        patch_system_user = {
            'system': {
                'user': self.system_config['system']['user']
            }
        }
        del (patch_system_user['system']['user'][user_index])

        response = self.FauxapiLib.config_patch(patch_system_user)
        if response['message'] != 'ok':
            raise UserGroupManagementFauxapiException('unable to remove user',
                                                      response['message'])

        return user

    # group functions
    # =========================================================================

    def get_groups(self):
        self._reload_system_config()

        response_data = {}
        for group in self.system_config['system']['group']:
            response_data[group['name']] = group
            del (response_data[group['name']]['name'])
        return response_data

    def add_group(self, groupname):
        self._reload_system_config()

        group_index, group = self._get_entity('group', groupname)
        if group_index is not None:
            raise UserGroupManagementFauxapiException('group already exists',
                                                      groupname)

        group = {
            'scope': 'local',
            'description': '',
            'name': groupname,
            'gid': self._get_next_id('gid'),
        }

        patch_system_group = {
            'system': {
                'group': self.system_config['system']['group']
            }
        }
        patch_system_group['system']['group'].append(group)

        response = self.FauxapiLib.config_patch(patch_system_group)
        if response['message'] != 'ok':
            raise UserGroupManagementFauxapiException('unable to add group',
                                                      response['message'])

        self._increment_next_id('gid')

        return group

    def manage_group(self, groupname, attributes):
        self._reload_system_config()

        valid_attributes = ['description', 'member', 'priv']

        group_index, group = self._get_entity('group', groupname)
        if group_index is None:
            raise UserGroupManagementFauxapiException('group does not exist',
                                                      groupname)

        if type(attributes) != dict:
            raise UserGroupManagementFauxapiException(
                'attributes is incorrect type')

        for attribute, value in attributes.items():
            if attribute not in valid_attributes:
                raise UserGroupManagementFauxapiException(
                    'unsupported attribute type', attribute)

            if attribute == 'member':
                if type(value) != list:
                    raise UserGroupManagementFauxapiException(
                        'member attribute is incorrect type')
            elif attribute == 'priv':
                if type(value) != list:
                    raise UserGroupManagementFauxapiException(
                        'priv attribute is incorrect type')

            if len(value) == 0 and attribute in group:
                del (group[attribute])
            elif len(value) > 0:
                group[attribute] = value

        patch_system_group = {
            'system': {
                'group': self.system_config['system']['group']
            }
        }
        patch_system_group['system']['group'][group_index] = group

        response = self.FauxapiLib.config_patch(patch_system_group)
        if response['message'] != 'ok':
            raise UserGroupManagementFauxapiException('unable to manage group',
                                                      response['message'])

        return group

    def remove_group(self, groupname):
        self._reload_system_config()

        group_index, group = self._get_entity('group', groupname)
        if group_index is None:
            raise UserGroupManagementFauxapiException('group does not exist',
                                                      groupname)

        patch_system_group = {
            'system': {
                'group': self.system_config['system']['group']
            }
        }
        del (patch_system_group['system']['group'][group_index])

        response = self.FauxapiLib.config_patch(patch_system_group)
        if response['message'] != 'ok':
            raise UserGroupManagementFauxapiException('unable to remove group',
                                                      response['message'])

        return group

    # internal helper functions
    # =========================================================================

    def _get_entity(self, entity_type, entity_name):

        entity = None
        entity_index = 0
        for entity_data in self.system_config['system'][entity_type]:
            if entity_data['name'] == entity_name:
                entity = entity_data
                break
            entity_index += 1

        if entity is None:
            return None, None

        return entity_index, entity

    def _get_next_id(self, id_type):
        id_name = 'next{}'.format(id_type)
        return self.system_config['system'][id_name]

    def _increment_next_id(self, id_type):
        id_name = 'next{}'.format(id_type)
        next_id = int(self._get_next_id(id_type)) + 1
        patch_system_nextid = {'system': {id_name: str(next_id)}}
        response = self.FauxapiLib.config_patch(patch_system_nextid)
        if response['message'] != 'ok':
            raise UserGroupManagementFauxapiException(
                'unable to increment the nextid', id_type)
        return next_id

    def _reload_system_config(self):
        self.system_config = self.FauxapiLib.config_get()
Пример #6
0
class pfSenseInfluxCollector:
    def __init__(self, config_file):
        """Program to send pfSense information collected from FauxAPI to InfluxDB"""
        self.config = configparser.ConfigParser()
        self.config.read(config_file)
        self.fauxapi = FauxapiLib(self.config['FAUXAPI']['APIHost'],
                                  self.config['FAUXAPI']['APIKey'],
                                  self.config['FAUXAPI']['APISecret'])
        self.influx_client = InfluxDBClient(
            host=self.config['INFLUXDB']['InfluxDBHost'],
            port=self.config['INFLUXDB']['Port'],
            username=self.config['INFLUXDB']['Username'],
            password=self.config['INFLUXDB']['Password'],
            database=self.config['INFLUXDB']['Database'])
        self.pfSense_config = self.fauxapi.config_get()
        self.pfSense_host = self.pfSense_config['system'][
            'hostname'] + "." + self.pfSense_config['system']['domain']

    def run(self):
        """Run enabled modules wuth delay as defined in config file"""
        threading.Timer(int(self.config['GENERAL']['Delay']), self.run).start()
        for function in self.module_dictionary:
            if self.config['MODULES'].getboolean(function):
                self.module_dictionary[function](self)

    def fauxapi_function_call(self, functionName):
        """Call fauxapi function_call without function arguments"""
        data = {"function": functionName}
        return self.fauxapi.function_call(data)['data']['return']

    def fauxapi_function_call_args(self, functionName, args):
        """Call fauxapi function_call function with arguments"""
        data = {"function": functionName, "args": args}
        return self.fauxapi.function_call(data)['data']['return']

    def write_influxdb_data(self, data):
        """Write set of data to InfluxDB."""
        self.influx_client.write_points(data)

    def gateway_status(self):
        """Get and save information about statuses of gateways."""
        gateways = self.fauxapi_function_call_args("return_gateways_status",
                                                   "true")
        for gateway in gateways:
            gateway_status = 1 if gateways[gateway]['status'] == "none" else 0
            gateway_data = [{
                "measurement": "gateway_status",
                "fields": {
                    "name": gateways[gateway]['name'],
                    "rtt": gateways[gateway]['delay'],
                    "rttsd": gateways[gateway]['stddev'],
                    "status": gateway_status
                },
                "tags": {
                    "host": self.pfSense_host
                }
            }]
            self.write_influxdb_data(gateway_data)

    def interface_statistics(self):
        """Get and save information about interfaces statistics."""
        interface_descriptions = self.fauxapi_function_call(
            "get_configured_interface_with_descr")
        for interface in interface_descriptions:
            interface_info = self.fauxapi_function_call_args(
                "get_interface_info", interface)
            interface_data = [{
                "measurement": "interface_statistics",
                "fields": {
                    "bytes_in": interface_info['inbytes'],
                    "bytes_out": interface_info['outbytes'],
                    "collisions": interface_info['collisions'],
                    "errors_in": interface_info['inerrs'],
                    "errors_out": interface_info['outerrs'],
                    "name": interface_descriptions[interface],
                    "packets_in": interface_info['inpkts'],
                    "packets_out": interface_info['outpkts']
                },
                "tags": {
                    "host": self.pfSense_host,
                    "interface": interface_info['if']
                }
            }]
            self.write_influxdb_data(interface_data)

    def interface_status(self):
        """Get and save information about statuses of interfaces."""
        interface_descriptions = self.fauxapi_function_call(
            "get_configured_interface_with_descr")
        for interface in interface_descriptions:
            interface_info = self.fauxapi_function_call_args(
                "get_interface_info", interface)
            interface_data = [{
                "measurement": "interface_status",
                "fields": {
                    "ip_address": interface_info['ipaddr'],
                    "name": interface_descriptions[interface],
                    "status": 1 if interface_info['status'] == 'up' else 0
                },
                "tags": {
                    "host": self.pfSense_host,
                    "interface": interface_info['if']
                }
            }]
            self.write_influxdb_data(interface_data)

    def openvpn_client_status(self):
        """Get and save information about OpenVPN clients."""
        for client in self.fauxapi_function_call("openvpn_get_active_clients"):
            client_data = [{
                "measurement": "openvpn_client_status",
                "fields": {
                    "remote_host": client['remote_host'],
                    "status": 1 if client['status'] == "up" else 0,
                    "virtual_address": client['virtual_addr']
                },
                "tags": {
                    "host": self.pfSense_host,
                    "vpnid": int(client['vpnid']),
                }
            }]
            self.write_influxdb_data(client_data)

    def openvpn_connected_clients(self):
        """Get and save information about connected clients to OpenVPN server."""
        for server in self.fauxapi_function_call("openvpn_get_active_servers"):
            server_name = server['name']
            for connection in server['conns']:
                connection_data = [{
                    "measurement": "openvpn_connected_clients",
                    "fields": {
                        "client_id": int(connection['client_id']),
                        "common_name": connection['common_name'],
                        "remote_host": connection['remote_host'],
                        "virtual_address": connection['virtual_addr']
                    },
                    "tags": {
                        "host": self.pfSense_host,
                        "server": server_name
                    }
                }]
                self.write_influxdb_data(connection_data)
            connected_clients_data = [{
                "measurement": "openvpn_connected_clients",
                "fields": {
                    "connected_clients": len(server['conns'])
                },
                "tags": {
                    "host": self.pfSense_host,
                    "server": server_name
                }
            }]
            self.write_influxdb_data(connected_clients_data)

    def services_status(self):
        """Get and save information about statuses of services."""
        for service in self.fauxapi_function_call("get_services")[1:]:
            service_status = self.fauxapi_function_call_args(
                "get_service_status", [service])
            service_data = [{
                "measurement": "services_status",
                "fields": {
                    "description": service['description'],
                    "status": 1 if service_status else 0
                },
                "tags": {
                    "host": self.pfSense_host,
                    "service": service['name']
                }
            }]
            self.write_influxdb_data(service_data)

    # Module Dictionary to allow dynamic calling of functions depending on config file
    module_dictionary = {
        "Gateway_Status": gateway_status,
        "Interface_Statistics": interface_statistics,
        "Interface_Status": interface_status,
        "OpenVPN_Client_Status": openvpn_client_status,
        "OpenVPN_Connected_Clients": openvpn_connected_clients,
        "Services_Status": services_status
    }
Пример #7
0
if (len(sys.argv) < 4):
    print()
    print('usage: ' + sys.argv[0] + ' <host> <apikey> <apisecret>')
    print()
    print('pipe JSON output through jq for easy pretty print output:-')
    print(' $ ' + sys.argv[0] + ' <host> <apikey> <apisecret> | jq .')
    print()
    sys.exit(1)

# config
fauxapi_host = sys.argv[1]
fauxapi_apikey = sys.argv[2]
fauxapi_apisecret = sys.argv[3]

FauxapiLib = FauxapiLib(fauxapi_host,
                        fauxapi_apikey,
                        fauxapi_apisecret,
                        debug=False)

# config get the full configuration and simply print to console
# =============================================================================
config = FauxapiLib.config_get()
print(json.dumps(config))

# config set the full configuration
# =============================================================================
# NB: nothing amazing is happening here, we are simply writing back the same (full) configuration again, the developer
# most likely wants to make changes to `config` before calling the config_set function again here
print(json.dumps(FauxapiLib.config_set(config)))

# config_get, config_set by section
# =============================================================================