Description

Scapy is a powerful Python program that can be used to send, receive and analyze network packets. This capability allows you to quickly build the desired traffic that can probe, scan or attack networks. The traffic generation can be fine tuned with a short python script.

This article demonstrates how to use scapy in a Contrail environment to generate TCP SYN packets. The packets are built and sent out from within a local VM, and target a remote VM. Once the packets get sent out, flows will be triggered and observed in both vRouters. 

Solution

Example:

The Scapy script is running on VM2 with IP address being 51.0.0.4. Traffic is being sent to the remote VM1 whose IP is 51.0.0.3.

    VM1/compute1 ------------- VM2/compute2 (scapy script)
    51.0.0.3                    51.0.0.4


Note: The Python Scapy module can be installed in Ubuntu14.04 based VM via ' apt install python-scapy ' command.  

Scapy References:

For example, to generate one single TCP SYN packet, we connect to the terminal and call the Scapy tool using the name Scapy. Different operating systems have different implementations. Refer to the links above to understand more about the operating system you are using. The following is an example from Ubuntu VM, such as Linux system.

    $ scapy
    >>> target = '51.0.0.3'
    >>> answered, unanswered = sr(
    ...     IP(dst = target) /
    ...     TCP(sport = 10000, dport = 60000, flags = "S"),
    ... )
    Begin emission:
    Finished sending 1 packets.
    ...*
    Received 4 packets, got 1 answers, remaining 0 packets

Searching the flow from the active flow table will return nothing:

    root@comp106:~# flow --match 51.0.0.4:10000
    Flow table(size 80609280, entries 629760)

    Listing flows matching ([51.0.0.4]:10000)

        Index                Source:Port/Destination:Port                      Proto(V)
    -----------------------------------------------------------------------------------

The reason is because when this TCP SYN packet hits the remote VM1, it was rejected due to no service listening on the destination port 10000. However, a flow did get triggered but only moved to "evicted" status. Only any compute we can get similar output as below:

    root@comp106:~# flow --match 51.0.0.3:60000 --show-evicted
    Flow table(size 80609280, entries 629760)

    Listing flows matching ([51.0.0.3]:60000)

        Index                Source:Port/Destination:Port                      Proto(V)
     ----------------------------------------------------------------------------------
        67772                51.0.0.4:10000                                      6 (15)
                             51.0.0.3:60000
    (Gen: 11, K(nh):151, Action:D(Unknown), Flags:E, TCP:, QOS:-1, S(nh):0,
     Stats:1/54,  SPort 0, TTL 0, Sinfo 0.0.0.0)

       188840                51.0.0.3:60000                                      6 (15)
                             51.0.0.4:10000
    (Gen: 12, K(nh):151, Action:D(Unknown), Flags:E, TCP:, QOS:-1, S(nh):0,
     Stats:1/54,  SPort 0, TTL 0, Sinfo 0.0.0.0)

Similarly, to generate 10 TCP SYN packets, provide a range of the source ports:

    target = '51.0.0.3'
    answered, unanswered = sr(
        IP(dst = target) /
        TCP(sport = range( 10000, 10010 ), dport = 60000, flags = "S"),
    )

You will end up with 10 evicted flows. The following is one of them:

    root@comp106:~# flow --match 51.0.0.4:10001 --show-evicted
    Flow table(size 80609280, entries 629760)

    Listing flows matching ([51.0.0.4]:10001)

        Index                Source:Port/Destination:Port                      Proto(V)
     ----------------------------------------------------------------------------------
        16412                51.0.0.4:10001                                      6 (15)
                             51.0.0.3:60000
    (Gen: 12, K(nh):151, Action:D(Unknown), Flags:E, TCP:, QOS:-1, S(nh):0,
     Stats:1/54,  SPort 0, TTL 0, Sinfo 0.0.0.0)

       274452                51.0.0.3:60000                                      6 (15)
                             51.0.0.4:10001
    (Gen: 14, K(nh):151, Action:D(Unknown), Flags:E, TCP:, QOS:-1, S(nh):0,
     Stats:1/54,  SPort 0, TTL 0, Sinfo 0.0.0.0)


With the Scapy Python module, the "TCP SYN flood attack" can be easily emulated in a VM with just a few lines of script. This script can be used to test Contrail vRouter data plane in many different scenarios.