-
Notifications
You must be signed in to change notification settings - Fork 31
Example #5 Simple stateful firewall
This example shows how P4Pi can be used as a simple stateful firewall, that classifies the TCP flows. By their origin, they can either be internal or external. Every connection that started from the internal network (the TCP SYN packet comes from an internal port) should be allowed, while other external connection requests should be blocked. If a connection establishes, bidirectional communication is allowed between the initial source and destination IP addresses and TCP ports.
To this end, the example requires only one table, which we call check_ports. Check_ports table is responsible for deciding which ports to identify as internal and which ones are external.
The source code of the example is available under P4Pi examples.
This example only works with IPv4 and TCP packets. Every other protocol passes through without any inspection. (See the last section for improvement ideas).
For a TCP packet, we use our check_ports table to identify the direction of the traffic. If it comes from the internal network (WLAN, which is port 0 in the example) we calculate a hash from the srcIP, dstIP, srcPort and dstPort fields. index=hash(srcIp,dstIP,srcPort,dstPort)
. If it is a TCP SYN packet we write 1 into a register to the position of the computed hash reg[index]=1
, and allow the packet to pass through the firewall.
If the packet comes from the external network, we compute the same hash index=hash(srcIp,dstIP,srcPort,dstPort)
and check if reg[index] = 1
. If yes, the packet is forwarded. Otherwise, it's dropped.
The following figure illustrates the setup of a P4Pi node:
For more detailed information check the Simple L2 Switch example
Connect your laptop to the wireless access point called "p4pi". After that your laptop will get an IP address assigned by the DHCP service (from the default address pool 192.168.4.0/24).
echo 'stateful_firewall' > /root/t4p4s-switch
systemctl restart t4p4s.service
If the check_ports
table is not filled up, every port is recognized as external. Therefore no TCP traffic can go through the firewall. You can check it by running the following commands.
Start an iperf server on P4Pi in the network namespace gigport:
sudo ip netns exec gigport iperf -s -B 192.168.4.150
And try to connect to it from your laptop with the iperf client:
iperf -c 192.168.4.150 -t 30 -i 1
Nothing will happen because the traffic is filtered.
The next step is to launch P4Runtime shell, that is used to fill the table. In the SSH terminal run:
t4p4s-p4rtshell stateful_firewall
In this example, port 0 represents the WLAN interface while port 1 is the bridge br1. In the P4Runtime terminal first, assign the ingress port 0 -> egress port 1 direction to internal (dir=0)
te = table_entry["MyIngress.check_ports"](action="MyIngress.set_direction")
te.match["standard_metadata.ingress_port"] = "0"
te.match["standard_metadata.egress_spec"] = "1"
te.action["dir"] = "0";
te.insert
Next ingress port 1 -> egress port 0 direction to external (dir=1)
te = table_entry["MyIngress.check_ports"](action="MyIngress.set_direction")
te.match["standard_metadata.ingress_port"] = "1"
te.match["standard_metadata.egress_spec"] = "0"
te.action["dir"] = "1";
te.insert
With the setup described above, now we should be able to establish TCP connections originated from the WLAN interface.
For example, start an iperf server through the P4Pi's SSH connection in the network namespace gigport:
sudo ip netns exec gigport iperf -s -B 192.168.4.150
And connect to it from your laptop:
iperf -c 192.168.4.150 -t 30 -i 1
Since WLAN (port0) is assigned as an internal port, the client can connect to the server and some performance results start showing up.
Also, check what happens if we run the commands the opposite way, On your laptop check your IP and start the iperf server:
ifconfig wlan0 # Get your IP on Linux
# ipconfig # Get your IP for Wi-Fi adapter on Windows OS
iperf -s -B xyz # Where xyz is your IP address
On the P4Pi run the iperf client in the namespace gigport:
sudo ip netns exec gigport iperf -c xyz -t 60 -i 1 # Where xyz is your IP address
The following figure depicts another setup where P4Pi node acts as a low level relay or proxy between your laptop and your home router (or a private network) connected to the 1GE wired Ethernet port.
Connect to the p4pi wireless access point and open an SSH to the management IP (192.168.4.101).
We first launch the stateful firewall program. In the SSH terminal:
echo 'stateful_firewall' > /root/t4p4s-switch
systemctl restart t4p4s.service
The following script should be executed to turn your P4Pi node into gateway mode:
sudo /root/setup_eth_wlan_bridge.sh
This script will create the settings shown in the previous figure: setup bridge br2 and connect port 1 of T4P4S switch to the 1GE wired interface and configure new management IPs. The possible management IPs through which you can access the P4Pi node (incl. SSH, web interface, etc.) are reported by the script like this example output:
+-------------------------------------------------------------
| Management IP on the wired interface: 192.168.1.146/24
| Management IP on the wireless interface: 192.168.1.83/24
| Management IP on the wireless interface: 192.168.4.1/24
+-------------------------------------------------------------
The last IP address is configured statically and can be used as a backdoor to the P4Pi node.
It may happen that you should disconnect your laptop from the p4pi access point and reconnect again (or at least renew your IP from the local DHCP server). After that you will be able to access the networking domains (e.g., Internet) behind your P4Pi node. For example, if the wired port of your P4Pi is connected to your home router, you should be able to access the Internet. Just open your browser to test it. Note that in this case all the traffic go through th P4 pipeline running inside the T4P4S switch.
Your laptop will not have internet access. Browsing will not work until the tables are configured.
Same as step 4 in the Testing with WiFi access only chapter.
Internet access should work properly on your laptop.
- P4Pi should drop ICMP echo requests from the external network.
- UDP traffic can be filtered similarly (use the first packet instead of the SYN)
-
Bmv2 Exercises