예제 #1
0
 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
예제 #2
0
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'
예제 #3
0
 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')
예제 #4
0
    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))
예제 #5
0
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="")
예제 #6
0
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="")
예제 #7
0
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,
        )
    ]
예제 #8
0
    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())
예제 #10
0
 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
예제 #12
0
 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
예제 #13
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)
예제 #14
0
 def __init__(self):
     self.header = HeaderConstraints(dstIps="host1", dstPorts="22")
     self.path = PathConstraints(startLocation="/as3/")