Emulab allows the ability to setup a control-network firewall between an experiment and the outside world. This is not a firewall between nodes within an experiment, that is, the firewall is not part of your NS-specified network topology. The purpose of an Emulab firewall is to prevent experimental traffic from escaping, via the control network, to the internet due to a mis-configured application or router within an experiment. In its initial limited form, the Emulab firewall is intended to prevent accidental misuse and not malicious abuse.
The firewall is implemented by allocating an additional node to the experiment. This node is set as the default route for all other nodes in the experiment. Thus, all outgoing, non-experimental traffic will pass through the node. This firewall node, running IPFW on FreeBSD, can be configured in a number of ways to block or allow certain types of traffic. Inbound traffic directed to the nodes does not pass through the firewall.
To add a firewall to an Emulab experiment, you specify a Firewall object
in your NS file (there is currently no way to add a firewall via the Emulab
client or experiment creation GUI):
This tells Emulab to add a node called "fw" to your experiment, and provides
a handle for adding rules to the firewall. The "style" of the firewall is
one of:
set fw [new Firewall $ns]
$fw set-style <style>
ssh
and ICMP traffic.
$fw add-rule <IPFW format rule string>
In the basic form, rules are numbered starting at 1. Thus, rules are
interpreted in the firewall in the order in which they appear in the NS file.
The default rules for a firewall style are numbered starting at 50000, so
user-specified rules are also interpreted before the default rule set.
There is also a method allowing explicit numbering of rules:
$fw add-numbered-rule <ruleno> <IPFW format rule string>
allowing more precise control over their interpretation and allowing for
linked rules. A complete example is shown below.
One should note carefully the following issues, some of which limit an Emulab firewall from being safely used as a containment environment for Really Bad Stuff. Our ultimate goal is to produce a highly secure containment environment, this implementation is only the first step.
There is a mighty fine line between a "limitation" and a "bug". For now, we are viewing things as the former.
Here is the NS code for a simple two node experiment with a firewall:
Notice that the second added rule filters incoming traffic and
is not strictly necessary right now since inbound traffic does not pass
through the firewall. This NS specification yields a topology that looks like:
source tb_compat.tcl
set ns [new Simulator]
set n1 [$ns node]
tb-set-node-os $n1 FBSD-STD
set n2 [$ns node]
tb-set-node-os $n2 RHL-STD
set link [$ns duplex-link $n1 $n2 100Mb 0ms DropTail]
# create a firewall node
set fw [new Firewall $ns]
$fw set-style basic
# allow tracroute through
$fw add-rule "allow udp from 155.98.36.0/22 to any 33434-33524"
$fw add-rule "allow udp from any 33434-33524 to 155.98.36.0/22"
$ns run
No surprises. Two nodes connected by a link, with a "disconnected" firewall
off to the side.
What isn't shown is that all three are connected via the control net.
The firewall is accessible via a DNS name of
fw
.experiment.project.emulab.net
similarly to
other nodes. You can login to the firewall, reboot it, etc. just as any
other node.
The Experiment Details
web page for the experiment lists
all the rules for the firewall:
Notice the rules involving multicast (224) and 155.98.32/23. These allow all
nodes to talk to Emulab infrastructure.
Firewall information:
ID Type Style Rule# Rule
--------------- -------- -------- ----- -----------------------------------
fw ipfw basic 1 allow udp from 155.98.36.0/22 to any 33434-33524
2 allow udp from any 33434-33524 to 155.98.36.0/22
55000 allow ip from me to me
55100 allow ip from me to 155.98.32.0/23
55101 allow ip from 155.98.32.0/23 to me
55200 allow icmp from any to 155.98.36.0/22
55201 allow icmp from 155.98.36.0/22 to any
55300 allow tcp from any to 155.98.36.0/22 22
55301 allow tcp from 155.98.36.0/22 22 to any
55400 allow tcp from me 16534 to 155.98.36.0/22
55401 allow tcp from 155.98.36.0/22 to me 16534
55500 allow udp from 224.4.0.0/16 2917 to 224.4.0.0/16 2917
65534 deny ip from any to any