def test_config_set(mock_requests_post):

    fauxapi = PfsenseFauxapi(host=None, apikey=None, apisecret=None)
    mock_requests_post.return_value.status_code = 200
    mock_requests_post.return_value.text = '{"callid": "5c8db8b4efb90", "action": "config_set", "message": "ok", "data": {"do_backup": true, "do_reload": true, "previous_config_file": "/cf/conf/backup/config-1552791732.xml"}}'

    response = fauxapi.config_set(config={})
    assert response['action'] == 'config_set'
    assert response['message'] == 'ok'
    assert response['data'] is not None
Esempio n. 2
0
    def set_rule_state(self, action):
        """Setup the pfSense Rules platform."""
        import pprint, sys
        from PfsenseFauxapi.PfsenseFauxapi import PfsenseFauxapi

        _LOGGER.debug("Connecting to pfSense firewall to change rule states.")
        try:
            # Setup connection with devices/cloud
            FauxapiLib = PfsenseFauxapi(self._host,
                                        self._api_key,
                                        self._access_token,
                                        debug=True)

            # Get the current set of filters
            filters = FauxapiLib.config_get('filter')
        except:
            _LOGGER.error(
                "Problem retrieving rule set from pfSense host: %s.  Likely due to API key or secret.",
                self._host)

        i = 0
        for rule in filters['rule']:
            if (rule.get('tracker') == self._tracker_id):
                _LOGGER.info("Found rule changing state rule: %s",
                             self._rule_name)
                if (action == True):
                    if ('disabled' in rule):
                        del filters['rule'][i]['disabled']
                        _LOGGER.debug(
                            "Rule %s enabled in config (this has not been pushed back to firewall yet!)",
                            self._rule_name)
                elif (action == False):
                    filters['rule'][i]['disabled'] = ""
                    _LOGGER.debug(
                        "Rule %s disabled in config (this has not been pushed back to firewall yet!)",
                        self._rule_name)
            i = i + 1

        try:
            _LOGGER.debug("Sending updated rule set to pfSense firewall")
            # Push the config back to pfSense
            filters = FauxapiLib.config_set(filters, 'filter')

            _LOGGER.debug(
                "Reloading the config on pfSense firewall to accept rule changes"
            )
            # Reload the config
            FauxapiLib.send_event("filter reload")
        except:
            _LOGGER.error(
                "Problem sending & reloading rule set from pfSense host: %s.  Likely due to API key or secret.",
                self._host)
Esempio n. 3
0
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 = PfsenseFauxapi(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
Esempio n. 4
0
FauxapiLib = PfsenseFauxapi(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
# =============================================================================
# perform a second config_get > config_set this time within the 'aliases' section only
# NB: again, nothing amazing happening in this example, we are are again only writing back the same (section)
# configuration, the developer more likely wants to perform some kind of operation on `config_aliases` before calling
# the config_set function again.
config_aliases = FauxapiLib.config_get('aliases')
print(json.dumps(
    FauxapiLib.config_set(config_aliases, 'aliases'))
)

# config_patch
# =============================================================================
Esempio n. 5
0
class PfSense:
    """
    PfSense Thingy...
    ...
    Methods
    -------
    get_openvpn_settings(self) -> dict:
    set_pfsense_config(self, data: dict, vpnid: list, refresh: bool = None) -> dict:
    get_pf_openvpn_clients(self) -> dict:
    get_pf_openvpn_locations(self, vpn_clients: dict) -> set:
    """
    def __init__(self):
        self.host = getenv("HOST_ADDRESS")
        self.port = 443
        self.key = getenv("FAUXAPI_KEY")
        self.secret = getenv("FAUXAPI_SECRET")
        try:
            PfsenseFauxapi(f"{self.host}:{self.port}", self.key, self.secret)
        except PfsenseFauxapiException as e:
            print(f"error: {str(e)}")
        else:
            self.pfapi = PfsenseFauxapi(f"{self.host}:{self.port}", self.key,
                                        self.secret)

    def get_openvpn_settings(self) -> dict:
        try:
            pf_openvpn_settings = self.pfapi.config_get('openvpn')
        except PfsenseFauxapiException as e:
            return {"error": str(e)}
        else:
            return pf_openvpn_settings

    def set_pfsense_config(self,
                           data: dict,
                           vpnid: list,
                           refresh: bool = None) -> dict:
        """
        Parameters
        ----------
        data : dict
            .
        vpnid : list
            .
        refresh : bool
            .
        """
        try:
            resp = self.pfapi.config_set(data, 'openvpn')
        except PfsenseFauxapiException as e:
            return {"error": str(e)}
        else:
            if refresh:
                self.pfapi.config_reload()
            if len(vpnid):
                for vid in vpnid:
                    data = self.pfapi.function_call({
                        "function":
                        "openvpn_restart_by_vpnid",
                        "args": ["client", f"{vid}"]
                    })
            return resp

    def get_pf_openvpn_clients(self) -> dict:
        clients: list = []
        vpn_clients = self.get_openvpn_settings()
        if "error" in vpn_clients.keys():
            return vpn_clients

        locations: set = self.get_pf_openvpn_locations(vpn_clients)
        for vpnclient in vpn_clients["openvpn-client"]:
            clients.append(vpnclient["server_addr"])

        return {"clients": clients, "locations": list(locations)}

    def get_pf_openvpn_locations(self, vpn_clients: dict) -> set:
        """
        Parameters
        ----------
        vpn_clients : dict
            .
        """
        locations = set()
        for client in vpn_clients["openvpn-client"]:
            loc = is_vpn_address(client["server_addr"])
            if loc is not None:
                locations.add(loc[1].lower())
        return locations
Esempio n. 6
0
FauxapiLib = PfsenseFauxapi(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
# =============================================================================
# perform a second config_get > config_set this time within the 'aliases' section only
# NB: again, nothing amazing happening in this example, we are are again only writing back the same (section)
# configuration, the developer more likely wants to perform some kind of operation on `config_aliases` before calling
# the config_set function again.
config_aliases = FauxapiLib.config_get('aliases')
print(json.dumps(FauxapiLib.config_set(config_aliases, 'aliases')))

# config_patch
# =============================================================================
# in this example we patch a specific set of configuration parameters and then revert them back to what they were
config_patch = {
    'system': {