def eval(self, ori_snapshot: str, new_snapshot: str) -> bool: answer = bfq.reachability(headers=HeaderConstraints(dstIps=self.dst), pathConstraints=PathConstraints(startLocation=self.src)) \ .answer(snapshot=new_snapshot) if hasattr(answer, "frame"): return answer.frame().size > 0 else: return False
def test_answer_traceroute(traceroute_network): bf_session.additional_args = {'debugflags': 'traceroute'} answer = bfq.traceroute(startLocation="hop1", headers=HeaderConstraints( dstIps="1.0.0.2")).answer().frame() list_traces = answer.iloc[0]['Traces'] assert len(list_traces) == 1 trace = list_traces[0] assert trace.disposition == "ACCEPTED" hops = trace.hops assert len(hops) == 2 assert hops[-1].steps[-1].action == 'ACCEPTED'
def check_traffic(self, snapshot: str, reference_snapshot: str): # bf_set_snapshot(name) load_questions() header = HeaderConstraints(srcIps="0.0.0.0/0", dstIps="0.0.0.0/0", ipProtocols=["tcp"]) path = PathConstraints(startLocation="/as2/", endLocation="/as3/") # result = bfq.differentialReachability(headers=header) \ # .answer(snapshot=snapshot, reference_snapshot=reference_snapshot).frame() result = bfq.reachability(headers=header, pathConstraints=path) \ .answer(snapshot=reference_snapshot).frame() result.to_csv('out.csv')
def _unidirectional_virtual_traceroute(self, source_ip, destination_ip, addresses): for address in addresses.rows: if address.get('IP') == source_ip: node = address.get('Node').get('name') int = address.get('Interface') headers = HeaderConstraints(srcIps=source_ip, dstIps=destination_ip, ipProtocols=['ICMP']) try: tracert = bfq.traceroute(startLocation="{}[{}]".format(node, int), headers=headers).answer() return tracert except: logger.warn('{} address has not been found'.format(source_ip))
def test_header_constraints_serialization(): hc = HeaderConstraints() hcd = hc.dict() fields = (set(map(attrgetter('name'), attr.fields(HeaderConstraints))) - {'firewallClassifications'} | {'flowStates'}) for field in fields: assert hcd[field] is None hc = HeaderConstraints(srcIps="1.1.1.1") assert hc.dict()["srcIps"] == "1.1.1.1" hc = HeaderConstraints(dstPorts=["10-20", "33-33"]) assert hc.dict()["dstPorts"] == "10-20,33-33" hc = HeaderConstraints(dstPorts="10-20,33") assert hc.dict()["dstPorts"] == "10-20,33" hc = HeaderConstraints(applications="dns,ssh") assert hc.dict()["applications"] == ['dns', 'ssh'] hc = HeaderConstraints(applications=['dns', 'ssh']) assert hc.dict()["applications"] == ['dns', 'ssh'] hc = HeaderConstraints(ipProtocols=" , dns,") assert hc.dict()["ipProtocols"] == ['dns'] hc = HeaderConstraints(ipProtocols=['tcp', 'udp']) assert hc.dict()["ipProtocols"] == ['tcp', 'udp'] with pytest.raises(ValueError): HeaderConstraints(applications="")
def test_header_constraints_serialization(): hc = HeaderConstraints() hcd = hc.dict() fields = (set(map(attrgetter('name'), attr.fields(HeaderConstraints))) - {'firewallClassifications'} | {'flowStates'}) for field in fields: assert hcd[field] is None hc = HeaderConstraints(srcIps="1.1.1.1") assert hc.dict()["srcIps"] == "1.1.1.1" hc = HeaderConstraints(dstPorts=["10-20", "33-33"]) assert hc.dict()["dstPorts"] == "10-20,33-33" hc = HeaderConstraints(dstPorts="10-20,33") assert hc.dict()["dstPorts"] == "10-20,33" for dp in [10, "10", [10], ["10"]]: hc = HeaderConstraints(dstPorts=dp) assert hc.dict()["dstPorts"] == "10" hc = HeaderConstraints(applications="dns,ssh") assert hc.dict()["applications"] == ['dns', 'ssh'] hc = HeaderConstraints(applications=['dns', 'ssh']) assert hc.dict()["applications"] == ['dns', 'ssh'] hc = HeaderConstraints(ipProtocols=" , dns,") assert hc.dict()["ipProtocols"] == ['dns'] hc = HeaderConstraints(ipProtocols=['tcp', 'udp']) assert hc.dict()["ipProtocols"] == ['tcp', 'udp'] match_syn = MatchTcpFlags(tcpFlags=TcpFlags(syn=True), useSyn=True) hc1 = HeaderConstraints(tcpFlags=match_syn) hc2 = HeaderConstraints(tcpFlags=[match_syn]) assert hc1.dict() == hc2.dict() with pytest.raises(ValueError): HeaderConstraints(applications="")
def test_header_constraints_of(): hc = HeaderConstraints.of( Flow( ipProtocol='ICMP', icmpCode=7, srcIp="1.1.1.1", dstIp="2.2.2.2", dscp=0, dstPort=0, srcPort=0, ecn=0, fragmentOffset=0, icmpVar=0, ingressInterface='', ingressNode='', ingressVrf='', packetLength=0, state='new', tag='tag', tcpFlagsAck=0, tcpFlagsCwr=0, tcpFlagsEce=0, tcpFlagsFin=0, tcpFlagsPsh=0, tcpFlagsRst=0, tcpFlagsSyn=0, tcpFlagsUrg=0, )) assert hc.srcIps == "1.1.1.1" assert hc.dstIps == "2.2.2.2" assert hc.ipProtocols == ['ICMP'] assert hc.icmpCodes == '7' assert hc.srcPorts is None assert hc.dstPorts is None assert hc.tcpFlags is None hc = HeaderConstraints.of( Flow( ipProtocol='TCP', srcPort=1000, dstPort=2000, tcpFlagsAck=True, srcIp="1.1.1.1", dstIp="2.2.2.2", dscp=0, ecn=0, fragmentOffset=0, icmpCode=0, icmpVar=0, ingressInterface='', ingressNode='', ingressVrf='', packetLength=0, state='new', tag='tag', tcpFlagsCwr=0, tcpFlagsEce=0, tcpFlagsFin=0, tcpFlagsPsh=0, tcpFlagsRst=0, tcpFlagsSyn=0, tcpFlagsUrg=0, )) assert hc.srcIps == "1.1.1.1" assert hc.dstIps == "2.2.2.2" assert hc.ipProtocols == ['TCP'] assert hc.icmpCodes is None assert hc.icmpTypes is None assert hc.srcPorts == '1000' assert hc.dstPorts == '2000' assert hc.tcpFlags == [ MatchTcpFlags( TcpFlags(ack=True), useAck=True, useCwr=True, useEce=True, useFin=True, usePsh=True, useRst=True, useSyn=True, useUrg=True, ) ]
acl_def = """ no ip access-list extended TEST_ACL ip access-list extended TEST_ACL 10 permit tcp any any 20 permit udp any any 30 deny tcp any any eq ssh """ load_questions() snap_gen = create_inline_snapshot(acl_def) print("#"*100) print("TEST ACL LINE REACHABILITY (here seq 30 should be useless and thus 'unreachable')") reacha = bfq.filterLineReachability().answer(snap_gen) print(reacha.frame()) print("#"*100) print("CHECK IF ACL REALLY BLOCKS THE PACKET SPECIFIED") test_behav = bfq.searchfilters( action="permit", headers=HeaderConstraints( applications=["ssh"], srcIps="1.2.3.4", dstIps="4.5.6.7" ) ).answer() print(test_behav) print("#"*100) print("DEFINES ON WHICH ENTRY THE PACKET SPECIFIED IS MATCHED") test_acl = bfq.testfilters( headers=HeaderConstraints( applications=["ssh"], srcIps="1.2.3.4", dstIps="4.5.6.7" ) ).answer() print(test_acl)
from pybatfish.client.commands import * from pybatfish.question import bfq from pybatfish.question.question import load_questions from pybatfish.datamodel.flow import (HeaderConstraints, PathConstraints) load_questions() # Check if a representative host can reach the DNS server dns_flow = HeaderConstraints(srcIps="192.168.0.1", dstIps="192.168.0.1", applications=["www"]) answer = bfq.testFilters(headers=dns_flow, nodes="rtr-with-acl", filters="acl_in").answer() show(answer.frame())
def build(self) -> HeaderConstraints: return HeaderConstraints(**self.__dict__)
def get_differential_reachability(bf_snapshot_base, bf_snapshot_fail): answer = (bfq.differentialReachability(headers=HeaderConstraints( dstIps=DST_IP_REACHABILITY)).answer( snapshot=bf_snapshot_fail, reference_snapshot=bf_snapshot_base).frame()) return answer
def eval(self, ori_snapshot: str, new_snapshot: str) -> bool: result = bfq.reachability(headers=HeaderConstraints(dstIps=self.dst), pathConstraints=PathConstraints(transitLocations=self.waypoint, startLocation=self.src)) \ .answer(snapshot=new_snapshot).frame() return result.size > 0
def run_module(): # define the available arguments/parameters that a user can pass to # the module module_args = dict(action=dict(type='str', required=False, default='permit'), destination_ips=dict(type='str', required=False, default=None), destination_ports=dict(type='str', required=False, default=None), filters=dict(type='str', required=False, default=".*"), host=dict(type='str', required=False, default='localhost'), invert_search=dict(type='bool', required=False, default=False), ip_protocols=dict(type='list', required=False, default=None), network=dict(type='str', required=True), nodes=dict(type='str', required=False, default=".*"), reference_snapshot=dict(type='str', required=False, default=None), source_ips=dict(type='str', required=False, default=None), source_ports=dict(type='str', required=False, default=None), name=dict(type='str', required=True)) # seed the result dict in the object # we primarily care about changed and state # change is if this module effectively modified the target # state will include any data that you want your module to pass back # for consumption, for example, in a subsequent task result = dict( changed=False, result_verbose='', ) # the AnsibleModule object will be our abstraction working with Ansible # this includes instantiation, a couple of common attr would be the # args/params passed to the execution, as well as if the module # supports check mode module = AnsibleModule( argument_spec=module_args, supports_check_mode=True, mutually_exclusive=[['action', 'reference_snapshot']]) if not pybatfish_found: module.fail_json(msg='Python module Pybatfish is required') if module.check_mode: return result snapshot = module.params['name'] reference_snapshot = module.params['reference_snapshot'] try: bf_session.coordinatorHost = module.params['host'] network = bf_set_network(module.params['network']) except Exception as e: module.fail_json(msg='Failed to set network: {}'.format(e), **result) try: load_questions() except Exception as e: module.fail_json(msg='Failed to load questions: {}'.format(e), **result) try: headers = HeaderConstraints( srcIps=module.params['source_ips'], dstIps=module.params['destination_ips'], ipProtocols=module.params['ip_protocols'], srcPorts=module.params['source_ports'], dstPorts=module.params['destination_ports']) except Exception as e: module.fail_json( msg='Failed to create header constraint: {}'.format(e), **result) try: filters = module.params['filters'] nodes = module.params['nodes'] action = module.params['action'] invert_search = module.params['invert_search'] q = bfq.searchfilters(headers=headers, filters=filters, nodes=nodes, action=action, invertSearch=invert_search) q_name = q.get_name() answer_obj = q.answer(snapshot=snapshot, reference_snapshot=reference_snapshot) answer_dict = bf_get_answer(questionName=q_name, snapshot=snapshot, reference_snapshot=reference_snapshot) except Exception as e: module.fail_json(msg='Failed to answer question: {}'.format(e), **result) answer_element = answer_dict["answerElements"][0] result['result_verbose'] = answer_element[ "rows"] if "rows" in answer_element else [] module.exit_json(**result)
def __init__(self): self.header = HeaderConstraints(dstIps="host1", dstPorts="22") self.path = PathConstraints(startLocation="/as3/")