Running in a “live” environment

Switchyard programs can be either run in an isolated test environment, as described above, or on a live host operating system. Switchyard currently supports Linux and macOS hosts for live execution.

Note

Switchyard uses the libpcap library for receiving and sending packets, which generally requires root privileges. Although hosts can be configured so that root isn’t required for using libpcap, this documentation does not include instructions on how to do so. The discussion below assumes that you are gaining root privileges by using the sudo (i.e., “do this as superuser”) program. Contrary to popular belief, sudo cannot make you a sandwich.

Basic command-line recipe

The basic recipe for running Switchyard on a live host is pretty simple. If we wanted to run the sniff.py Switchyard program (available in the examples folder in the Switchyard github repository) and use all available network interfaces on the system, we could do the following:

$ sudo swyard sniff.py

Again, note that the above line uses sudo to gain the necessary privileges to be able to send and receive “live” packets on a host.

Note

If you can an error when attempting to run swyard with sudo such as this:

sudo: swyard: command not found

you will need to either create a shell script which activates your Python virtual environment and run that script with sudo, or run swyard from a root shell (e.g., by running sudo -s. If doing the latter, you will still need to activate the Python virtual environment once you start the root shell, after which you can run swyard as normal. If using Switchyard in Mininet, in any shell you open (e.g., using the xterm command, which opens a root shell on a virtual host in Mininet) you’ll need to activate the Python virtual environment prior to running swyard.

The sniff.py program will simply print out the contents of any packet received on any interface while the program runs. To stop the program, type Control+c.

Here’s an example of what output from running sniff.py might look like. Note that the following example was run on a macOS host and that the text times/dates have been changed:

Example of Switchyard output from running in a live environment on a macOS host.
 00:00:56 2016/12/00     INFO Enabling pf: No ALTQ support in kernel; ALTQ related functions disabled; pf enabled; Token : 15170097737539790927
 00:00:56 2016/12/00     INFO Using network devices: en1 en0 en2
 00:00:56 2016/12/00     INFO My interfaces: ['en0', 'en1', 'en2']
 00:00:56 2016/12/00     INFO 1482563936.430: en0 Ethernet a4:71:74:49:e2:e6->ac:bc:32:c2:b6:59 IP | IPv4 104.84.41.100->192.168.0.102 TCP | TCP 443->51094 (A 1772379675:466295739) | RawPacketContents (1448 bytes) b'\x17\x03\x03\x0c-\xc5\xeap\xd1L'...
 00:00:56 2016/12/00     INFO 1482563936.430: en0 Ethernet a4:71:74:49:e2:e6->ac:bc:32:c2:b6:59 IP | IPv4 104.84.41.100->192.168.0.102 TCP | TCP 443->51094 (A 1772381123:466295739) | RawPacketContents (1448 bytes) b'\xca5K\xfb\x88\x01\xec\xb4\xf0\x84'...
 00:00:56 2016/12/00     INFO 1482563936.430: en0 Ethernet a4:71:74:49:e2:e6->ac:bc:32:c2:b6:59 IP | IPv4 104.84.41.100->192.168.0.102 TCP | TCP 443->51094 (PA 1772382571:466295739) | RawPacketContents (226 bytes) b'\xb1\x9d\xad8g]\xc3\xech\x9e'...

 ... (more packets, removed for this example)

 ^C
 00:00:58 2016/12/00     INFO Releasing pf: No ALTQ support in kernel; ALTQ related functions disabled; disable request successful. 1 more pf enable reference(s) remaining, pf still enabled.

Note in particular a few things about the above example:

  • First, when started in a live setting, Switchyard saves then clears any current host firewall settings. The saved firewall settings are restored when Switchyard exits (see the final log line, above).

    The default behavior of Switchyard is to block all traffic. This behavior may be undesirable in different situations and can be changed through the swyard command line option -f or --firewall, as described below.

    Switchyard’s manipulation of the host operating system firewall is intended to prevent the host from receiving any traffic that should be the sole domain of Switchyard. For example, if you are creating a Switchyard-based IP router, you want Switchyard, not the host, to be responsible for receiving and forwarding traffic. As another example, if you are implementing a protocol stack for a particular UDP-based application, you will want to prevent the host from receiving any of that UDP traffic.

    Note that on macOS Switchyard configures host firewall settings using pfctl and on Linux Switchyard uses iptables.

  • By default, Switchyard finds and uses all interfaces on the host that are (1) determined to be “up” (according to libpcap), and (2) not a localhost interface. In the above example run, Switchyard finds and uses three interfaces (en0, en1, and en2).

  • The above example shows three packets that were observed by Switchyard, each arriving on interface en0. Notice that the three packets each contain Ethernet, IPv4 and TCP packet headers, as well as payload (in the form of RawPacketContents objects at the end of each packet).

Here is an example of running the Switchyard example sniff.py program on a Linux host (note again that the text times/dates have been changed):

Example of Switchyard output from running in a live environment on a Linux host.
 00:00:11 2016/12/00     INFO Saving iptables state and installing switchyard rules
 00:00:11 2016/12/00     INFO Using network devices: enp0s3
 00:00:11 2016/12/00     INFO My interfaces: ['enp0s3']
 00:00:15 2016/12/00     INFO 1482564855.115: enp0s3 Ethernet 08:00:27:bb:27:89->01:00:5e:00:00:fb IP | IPv4 10.0.2.15->224.0.0.251 UDP | UDP 5353->5353 | RawPacketContents (45 bytes) b'\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00'...
 00:00:16 2016/12/00     INFO 1482564856.172: enp0s3 Ethernet 08:00:27:bb:27:89->33:33:00:00:00:fb IPv6 | IPv6 fe80::a00:27ff:febb:2789->ff02::fb UDP | UDP 5353->5353 | RawPacketContents (45 bytes) b'\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00'...

 ... (more packets, removed for this example)

 ^C
 00:00:23 2016/12/00     INFO Restoring saved iptables state

Comparing the above output to the earlier macOS output, observe that:

  • The firewall save/restore log lines (first and last) are somewhat different, reflecting the fact that iptables is used on Linux instead of pf.
  • There is one interface found and used by Switchyard: enp0s3.
  • Two packets are included in the output above: an IPv4 UDP packet and an IPv6 UDP packet.

As with running Switchyard in a test environment, you may wish to use the -v and/or -d options to increase Switchyard’s output verbosity or to include debugging messages, respectively.

Including or excluding particular interfaces

When running Switchyard in a virtual machine environment such as on a Mininet container host, it is often the case that you want Switchyard to “take over” all available network interfaces on the host. When running Switchyard in other environments, however, you may want to restrict the interfaces that it uses. You may even want Switchyard to use the localhost interface (typically named lo0 or lo). There are two command-line options that can be used for these purposes.

-i <interface-name>

Explicitly include the given interface for use by Switchyard. This option can be used more than once to include more than one interface.

If this option is given, only the interfaces specified by -i options will be used by Switchyard. If no -i option is specified, Switchyard uses all available interfaces except the localhost interface.

To use a localhost interface, you must explicitly include it using this option. If you explicitly include the localhost interface, you can still explicitly include other interfaces.

-x <interface-name>

Explicitly exclude the given interface for use by Switchyard. This option can be used more than once to exclude more than one interface.

Switchyard’s behavior with this option is to first discover all interfaces available on the host, then to remove any specified by -x.

Note that given the semantics described above, it generally makes sense only to specify one of -i or -x.

Firewall options

As noted above, Switchyard’s default behavior is to prevent the host operating system from receiving any traffic while Switchyard is running. This may be undesirable in certain situations, and the -f or --firewall options to swyard are available to change this behavior.

The -f and --firewall options accept a single rule as a parameter (which in many cases needs to be quoted in the shell). The rule syntax is proto[:port], where the [:port] part is optional and proto may be one of tcp, udp, icmp, none or all. If all is specified, the port part should not be included; all will block all traffic on the interfaces used by Switchyard. If none is specified, again, no port should be specified; none will cause no rules to be installed to block traffic. Here are some examples:

tcp
Block the host from receiving all TCP traffic
tcp:8000
Block the host from receiving TCP traffic on port 8000
icmp
Block the host from receiving all ICMP traffic
udp:4567
Block the host from receiving UDP traffic on port 4567
none
Do not block any traffic.
all
Block the host from receiving all traffic. This is the default behavior.

If the -v (verbose) option is given to swyard, the host firewall module will print (to the log) firewall settings that have been enabled. Here are two examples from running swyard in a live environment (on macOS with the pf firewall). First, an example showing Switchyard blocking all traffic on two interfaces:

Running Switchyard in a live environment (macOS) with -v flag: notice log line indicating firewall rules installed (2nd line, 2 rules).
 $ sudo swyard -i lo0 -i en0 -v sniff.py
 11:39:58 2016/12/00     INFO Enabling pf: No ALTQ support in kernel; ALTQ related functions disabled; pf enabled; Token : 16107925605825483691;
 11:39:58 2016/12/00     INFO Rules installed: block drop on en0 all
 block drop on lo0 all
 11:39:58 2016/12/00     INFO Using network devices: en0 lo0
 11:39:58 2016/12/00     INFO My interfaces: ['en0', 'lo0']
 ^C11:40:00 2016/12/00     INFO Releasing pf: No ALTQ support in kernel; ALTQ related functions disabled; disable request successful. 4 more pf enable reference(s) remaining, pf still enabled.;

Here is an example showing Switchyard blocking all ICMP, all TCP, and UDP port 8888:

Running Switchyard in a live environment (macOS) with -v flag: notice log line indicating firewall rules installed (2nd line, 3 rules).
 $ sudo swyard -i lo0 --firewall icmp --firewall tcp --firewall 'udp:8888' -v sniff.py
 11:43:46 2016/12/00     INFO Enabling pf: No ALTQ support in kernel; ALTQ related functions disabled; pf enabled; Token : 16107925605472991531;
 11:43:46 2016/12/00     INFO Rules installed: block drop on lo0 proto icmp all
 block drop on lo0 proto tcp all
 block drop on lo0 proto udp from any port = 8888 to any port = 8888
 11:43:46 2016/12/00     INFO Using network devices: lo0
 11:43:46 2016/12/00     INFO My interfaces: ['lo0']
 ^C11:43:48 2016/12/00     INFO Releasing pf: No ALTQ support in kernel; ALTQ related functions disabled; disable request successful. 4 more pf enable reference(s) remaining, pf still enabled.;

And finally, the same example as previous, but on Linux with iptables:

Running Switchyard in a live environment (Linux) with -v flag: notice log line indicating firewall rules installed (2nd line, 3 rules).
 # swyard -v sniff.py --firewall icmp --firewall udp:8888 --firewall tcp
 19:53:42 2016/12/00     INFO Saving iptables state and installing switchyard rules
 19:53:42 2016/12/00     INFO Rules installed: Chain PREROUTING (policy ACCEPT)
 target     prot opt source               destination
 DROP       icmp --  0.0.0.0/0            0.0.0.0/0
 DROP       udp  --  0.0.0.0/0            0.0.0.0/0            udp dpt:8888
 DROP       tcp  --  0.0.0.0/0            0.0.0.0/0

 Chain OUTPUT (policy ACCEPT)
 target     prot opt source               destination
 19:53:42 2016/12/00     INFO Using network devices: enp0s3
 19:53:42 2016/12/00     INFO My interfaces: ['enp0s3']
 ^C19:53:45 2016/12/00     INFO Restoring saved iptables state

Note

When using a loopback interface, there are a couple things to be aware of. First, while Switchyard normally uses libpcap for sending and receiving packets, a raw socket is used for sending packets on the localhost interface. This is done due to limitations on some operating systems, notably Linux. Receiving packets is still done with libpcap, though on different operating systems you may observe that packets are encapsulated differently. In particular, on Linux, an Ethernet header with zeroed addresses is used, while on macOS the BSD Null header is used, which just consists of a protocol number (i.e., the ethertype value normally found in the Ethernet header).