def main(): print('Starting PfSense Parental Control App') print('Finding LAN devices') devices = find_devices() print('Finding Rule Overides') overrides = get_overrides() print('Finding blocked users') blocked = find_blocked(devices, overrides) print('Resolving IP addresses') blocked_ip = [[build_descr(b), devices.get(b['MAC'])] for b in blocked] print("Configuring Faux API") api = PfsenseFauxapi(PFSENSE_HOST, apikey, apisecret) api.proto = 'http' print("Requesting config") current_block_rules, default_rules = get_rules(api) current_block_ip = dict( (r['descr'], r['source']['address']) for r in current_block_rules) new_rules = build_new_rules(blocked_ip, current_block_ip) new_patch = create_filter_rule_patch(new_rules + default_rules) pprint.pprint(new_patch) print("patching") api.config_patch(new_patch) api.function_call({ 'function': 'filter_configure_sync', 'args': [False], 'includes': ['shaper.inc'], })
def test_function_call(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": "5c8dc7cda6948", "action": "function_call", "message": "ok", "data": {"return": {}}}' response = fauxapi.function_call(None) assert response['action'] == 'function_call' assert response['message'] == 'ok'
print(json.dumps( FauxapiLib.alias_update_urltables()) ) # # system reboot # ============================================================================= # print(json.dumps( # FauxapiLib.system_reboot()) # ) # function_call - examples # ============================================================================= print(json.dumps( FauxapiLib.function_call({ 'function': 'return_gateways_status', 'args': [False] } ))) print(json.dumps( FauxapiLib.function_call({ 'function': 'discover_last_backup' } ))) print(json.dumps( FauxapiLib.function_call({ 'function': 'return_gateways_status', 'includes': ['gwlb.inc'] } )))
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
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 = PfsenseFauxapi(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 = 0 if gateways[gateway]['status'] == "down" else 1 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}