layer2.tap
This Model Component provides the capability to insert a passive tap on any link within an experiment. This use case is explicitly for cases where the collector/analysis platform is placed within the experiment. Examples of collectors include Zeek, Splunk, Elastic Stack, etc.
This Model Component walks the graph looking for Edges
that have the tap
attribute set.
Specifically, the tap
attribute on the Edge
must specify a list of collectors that will receive the mirrored traffic.
The list of of collectors can contain either the actual Vertex
object (recommended) or the name of the collector Vertex
.
Once all tapped Edges
are found, an additional IP network is added to all the specified collectors.
Each collector gets its own IP subnet to communicate to its associated taps.
This isolates the mirrored traffic from flowing over other taps in the experiment and thus eliminates the risk of accidentally duplicating traffic.
The following is the process that this model component follows to insert taps:
Tap objects are created from
layer2.ovs.OpenvSwitch
objects, which areUbuntu1604Server
with Open vSwitch (OVS) installed.The specified link is then “broken” and reconnected at layer 2 through the tap object. The original edge is maintained to show the original logical connection between the two nodes. The new edges created are also decorated with
base_objects.FalseEdge
.OVS is then set to create a bridge and add all layer 2 interfaces are added to the specified bridge.
This provides a place where the traffic can be mirrored or even man-in-the-middled if desired.
A new “monitor” network is added to the collector and all taps associated with that collector
GRE tunnel endpoints are created on both the tap and the collector.
This is the mechanism that delivers the mirrored traffic to the collector.
- Attribute Depends:
graph
- Attribute Provides:
tap
- Model Component Dependencies:
Plugin
- class layer2.tap_plugin.InsertTaps(graph, log)[source]
Bases:
AbstractPlugin
This plugin inserts a passive tap on designated edges and tunnels all mirrored traffic to the “collector” (i.e. Splunk, Bro, etc) specified on the
Edge
.Each “collector” gets an additional IP network in order to have the mirrored traffic from the taps GRE tunneled to it. Each tunnel gets its own interface of the form
tap<integer>
where integer is the GRE key. For example, if there is a tunnel between the “collector” and a tap using a GRE key of 1000 then the “collector” will have an interface namedtap1000
. ThetapX
interfaces should then be listened on by the collecting software (i.e Bro).- __annotations__ = {}
- run(collector_network='10.100.0.0/16')[source]
Walk the graph and drop in passive taps on links that have been specified to be tapped.
- Parameters:
collector_network (str, optional) – IP space to pull subnets from. The subnets are added to the various collectors and associated taps in order to tunnel mirrored traffic to the collector. Defaults to
'10.100.0.0/16'
.- Raises:
RuntimeError – If the collector specified on the
Edge
is not a name of the collectorVertex
nor the actualVertex
object.
- class layer2.tap_plugin._EdgeTapper(edge, network)[source]
Bases:
object
A transient object used to tap an
Edge
.- __init__(edge, network)[source]
Initialize the Object.
- Parameters:
edge (Edge) – The edge to tap.
network (netaddr.IPNetwork) – The network used by the tap VM and the associated collectors.
- _g
The NetworkX graph for the given edge.
- Type:
- network
The network used by the tap VM and the associated collectors.
- Type:
- _ips
An iterator for all the IP addresses in
network
.- Type:
iter
- _create_switch(switch_name)[source]
Create a new
base_objects.Switch
.- Parameters:
switch_name (str) – The name of the new
base_objects.Switch
.- Returns:
The new
base_objects.Switch
.- Return type:
- _create_tap(tap_name)[source]
Create a new node that is a
layer2.tap.Tap
.- Parameters:
tap_name (str) – The name of the new
layer2.tap.Tap
.- Returns:
The newly created
layer2.tap.Tap
.- Return type:
- _gre_key = 1000
- _mirror_traffic(tap, tap_ip, tap_collector_switch, collector_ips)[source]
Mirror traffic along the original tapped edge to the collectors.
Connect the tap to a “monitor” network so that mirrored traffic can be tunneled to the collector. In theory this could go over the same network that already exists, but you run the risk of tapping other mirrored traffic at upstream taps, therefore it’s best to isolate mirrored traffic to its own network.
- Parameters:
tap (Vertex) – The tap VM from which traffic is mirrored.
tap_ip (netaddr.IPAddress) – The IP address of the tap VM on the collector subnet.
tap_collector_switch (Vertex) – The switch connecting the tap VM to the collectors.
collector_ips (dict) – A dictionary mapping collector vertices to their IP address in the subnet defined for this tap.
- _reconstruct_edge(endpoint, orig_switch, tap, tap_switch)[source]
Reconstruct the original edge.
Using the the new tap switch, reconstruct the original edge so that it now connects the original switch to the endpoint via the tap and the tap switch.
- Parameters:
endpoint (Vertex) – The VM endpoint of the edge to be reconstructed.
orig_switch (Vertex) – The original switch terminating the edge to be reconstructed.
tap (Vertex) – The new VM endpoint to add into the reconstructed edge segments.
tap_switch (Vertex) – The new switch to add into the reconstructed edge segments.
- _refresh_endpoint_interface(endpoint, tap_switch)[source]
Refresh the endpoint interface.
- Parameters:
- Returns:
The new edge created by connecting the endpoint to the tap switch.
- Return type:
- Raises:
RuntimeError – If an interface cannot be found for tapping the endpoint.
- _set_up_gre_tunnel_endpoint(collector, collector_ip, tap_ip)[source]
Add the tap via the GRE tunnel endpoint.
- Parameters:
collector (Vertex) – The collector on which to set the tap.
collector_ip (netaddr.IPAddress) – The IP of the collector vertex in the subnet defined for this tap.
tap_ip (netaddr.IPAddress) – The IP of the tapping VM in the subnet defined for this tap.
- _validate_collector(collector)[source]
Ensure that a given collector is a VM endpoint (or look it up).
- Parameters:
collector (Vertex) – A collector to be validated (or, if the collector is provided as a name, find the corresponding
Vertex
.- Returns:
The validated collector vertex.
- Return type:
- Raises:
RuntimeError – If the collector specified is not a name of the collector
Vertex
nor the actualVertex
object.
- tap_edge(collectors)[source]
Tap the edge using all of the collectors.
For each tapped edge, break the current link and drop in the passive tap. Then hook up the link through the tap. Each tap then mirrors the traffic through a GRE tunnel back to the collector that was specified on the edge.
- Parameters:
collectors (list) – A list of Vertex objects designated to tap the edge.
Available Objects
- class layer2.tap.Tap(*args, **kwargs)[source]
Bases:
object
Create a tap object. This is essentially an
OpenvSwitch
object with additional functions to man-in-the-middle and/or mirror traffic.- l2_mitm(bridge_name='br0')[source]
Create a layer 2 bridge that “breaks” the link, thus providing a position to mirror or man-in-the-middle traffic.
Note
This function will pick up all interfaces on the VM that are not configured to have an IP address. The absence of layer 3 configuration is assumed to mean that the interface is only a layer 2 interface.
- Parameters:
bridge_name (str) – Name of the bridge to be created on the VM. All layer 2 interfaces then get dropped on the bridge
- mirror_traffic(bridge, *tunnel_params)[source]
Once the layer 2 interfaces are all on the same bridge, mirror all traffic to the specified IP address. This is done by creating a GRE tunnel with the specified key. It is expected that the VM hosting the specified IP has a GRE endpoint configured.
- Parameters:
bridge (str) – Name of the bridge holding the interfaces that will have their traffic mirrored.
*tunnel_params (tuple) – Each parameter set is a tuple in the form of
(ip, key)
whereip
is the remote IP of the GRE tunnel andkey
is the GRE key, which is just an integer, but the key must be set in the same way on both the local and remote GRE endpoints. This key also helps us distinguish various port/mirror IDs.
- Raises:
ValueError – If the tunnel parameters are not provided.