Sunday, March 13, 2016

v6Brouter Part 2: v6Bridge Firewall

by Craig Miller

In the last post (see NATiness and the v6Brouter), I introduced the concept of a v6Brouter, part bridge, and part router. Bridging IPv6 is a good way to extend already allocated IPv6 networks (e.g. a /64 already allocated by an upstream ISP) to overcome networks segmented by  IPv4 NAT. But typically bridging does not include any kind of firewall. After all, bridging is simple, just doing a MAC DA lookup, and sending the packet on its way.

But although you may want to extend the IPv6 network, you may not trust all those unknown hosts upstream. It would be nice to have a v6Bridge Firewall.

Netfilter to the rescue

Fortunately the creators of Netfilter (better known as iptables, and ip6tables on Linux) created a layer 2 filtering tool called ebtables. With ebtables, it is possible to inspect bridged packets and forward them as we saw with the v6brouter, or send them up the stack to be inspected by ip6tables.

Challenges to ip6tables when bridging

A challenge of ip6tables when bridging (IPv6) is that it thinks all packets come from the bridge interface (br-lan on OpenWRT). This makes it difficult to filter upstream packets, but allow your trusted downstream packets to pass unfiltered.

The concept of Mark

Fortunately Netfilter created the concept of mark, where a packet is marked with a number (uint32). It is possible to mark a packet (with set-mark) and later filter on that marked value. Fortunately, ebtables and ip6tables share the same mark value.

Solving ip6tables challenge

Since ip6tables can't distinguish which port a bridged packet came from, and ebtables can, it is a simple task of having ebtables mark a packet that comes from the upstream port, and then later having ip6ables filter on that marked value of the packet.

Tying it all together

Now that is is possible to mark a packet at L2 ingress port, and then read the marked value at L3, it is possible to create a v6Bridge Firewall. Here's a diagram which explains the path of a packet in a v6Bridge Firewall.
v6Brouter with v6Bridge Firewall

For example, let's say you want to filter SSH from the outside, but permit the inside network (the extended trusted network) to be able to SSH to the outside and the internet. Or to put it another way, block incoming SSH, while allowing outbound SSH.

The v6Bridge Firewall inspects the packet at ISO layers 2, 3, and 4.

  • Layer 2 - Check ethertype for IPv6, check ingress port, if outside network, mark packet with the value of 16
  • Layer 3 - Read marked value, if 16, go to L4
  • Layer 4 - Check if the destination port = 22 (SSH), if so drop, if not forward to L2
  • Back at Layer 2, Check MAC Destination Address, and send out correct port

All of this happens in the blink of an eye*. Netfilter is highly optimized code running in kernel space. Without hardware support, it would be difficult to find faster code.

v6Brouter and your Firewall too

The v6Brouter project (on github) now includes v6bridge firewall. When extending your IPv6 network across all those cascaded IPv4 NAT situations, you can now have your bridge and firewall it too.


* Running thruput tests on OpenWRT with and without firewall enabled using netcat over IPv6/TCP transferring a 100MB file  yielded no appreciable difference at 100Mbit speeds.

No comments:

Post a Comment