[ Posted by James Harton
Tue, 22 Dec 2009 20:13:02 GMT ]
The project I'm working on requires some pretty fancy twiddling of IP addresses and prefixes, so I've slowly been adding functionality to Ruby's IPAddr class. Here's a couple of new features;
You can download the whole file from gist.github.com
Tags addr.arpa, delegation, ip, ip6.arpa, ipaddr, ipv4, ipv6, network, prefix, reverse, ruby, scope | no comments
[ Posted by James Harton
Wed, 08 Jul 2009 23:28:05 GMT ]
In my experience firewalling IPv6 connected hosts is a little more complex than IPv4. If you're giving it a go you probably want to keep your eyes out for the following gotchas:
Link local
Every IPv6 connected interface must have a unicast link local address, unicast link local addresses are dynamically generated using the interface's hardware address (via RFC2373) and will be within the fe80::/10 subnet. For example on my linux box at home:
eth0 Link encap:Ethernet HWaddr 00:08:74:e5:b7:00
inet6 addr: fe80::208:74ff:fee5:b700/64 Scope:Link
When writing your rules you need to allow for the fact that these unicast link local addresses are used extensively for router solicitation and neighbour discovery when using autoconfiguration. For my boxes that means I use a rule something like this:
ip6tables -A INPUT -i eth0 -s fe80::/10 -d fe80::/10 -j ACCEPT
ip6tables -A OUTPUT -o eth0 -s fe80::/10 -d fe80::/10 -j ACCEPT
Of course, this means that you need to be able to trust all machines on the same subnet. This is a big issue.
You also need to allow unicast link local addresses to send to multicast link local addresses, as IPv6 has no network and broadcast addresses in the IPv4 sense (ie x.x.x.255 or x.x.x.0 for a /24 IPv4 subnet) and the only way of sending a broadcast message on your subnet is by using multicast link local addresses. There are several well known addresses that you need to be aware of, but the most commonly used for neighbour discovery are ff02::1 (all nodes) and ff02::2 (all routers).
Link local scoped multicast subnets are defined as ffx2::/16 (ie; ff02::/16, ff12::/16 through fff2::/16). Technically neighbour discovery can happen on any of these subnets (ie fff2::1/16 is equivalent to ff02::1/16). This means that you need to filter to allow unicast link local addresses to send to multicast link local addresses (it's at this point that I wish netfilter had tables like pf):
ip6tables -A INPUT -i eth0 -s fe80::/10 -d ff02::1/16 -j ACCEPT
ip6tables -A INPUT -i eth0 -s fe80::/10 -d ff12::1/16 -j ACCEPT
ip6tables -A INPUT -i eth0 -s fe80::/10 -d ff22::1/16 -j ACCEPT
ip6tables -A INPUT -i eth0 -s fe80::/10 -d ff32::1/16 -j ACCEPT
ip6tables -A INPUT -i eth0 -s fe80::/10 -d ff42::1/16 -j ACCEPT
ip6tables -A INPUT -i eth0 -s fe80::/10 -d ff52::1/16 -j ACCEPT
ip6tables -A INPUT -i eth0 -s fe80::/10 -d ff62::1/16 -j ACCEPT
ip6tables -A INPUT -i eth0 -s fe80::/10 -d ff72::1/16 -j ACCEPT
ip6tables -A INPUT -i eth0 -s fe80::/10 -d ff82::1/16 -j ACCEPT
ip6tables -A INPUT -i eth0 -s fe80::/10 -d ff92::1/16 -j ACCEPT
ip6tables -A INPUT -i eth0 -s fe80::/10 -d ffa2::1/16 -j ACCEPT
ip6tables -A INPUT -i eth0 -s fe80::/10 -d ffb2::1/16 -j ACCEPT
ip6tables -A INPUT -i eth0 -s fe80::/10 -d ffc2::1/16 -j ACCEPT
ip6tables -A INPUT -i eth0 -s fe80::/10 -d ffd2::1/16 -j ACCEPT
ip6tables -A INPUT -i eth0 -s fe80::/10 -d ffe2::1/16 -j ACCEPT
ip6tables -A INPUT -i eth0 -s fe80::/10 -d fff2::1/16 -j ACCEPT
Admin local multicast
The admin local multicast scope is defined as ffx4::/16 and is somewhat cryptically defined as "the smallest scope that must be administratively configured". This is generally accepted to mean bigger than a single subnet and smaller than a "site". You will need to drop packets destined to these subnets at the defined border.
Site local multicast
Site local multicast is defined as ffx5::/16 and allows you to send packets within a single site, whether this be a room, building, branch office or campus is up to you. You will need to drop packets destined to these subnets at the border of your "site".
Organisation local multicast
Organisation local multicast is defined as ffx8::/16. Packets destined for these subnets must never leave your organisation's network. For a larger organisation I would suggest you filter organisation local multicast at the edge of your AS, for smaller organisations at the router for your internet connection. As with the previous two scopes, you can filter this traffic a number of ways; dropping it with the firewall, with routing policy or by squashing the packet's TTL.
Global multicast
Global multicast is used to deliver services like live streams and video conferencing, especially within academic and research networks. You should probably allow traffic destined to ffxe::/16.
Unique local unicast
Unique local unicast is the IPv6 equivalent of our old RFC1918 addresses in the IPv4 world. These networks should never be seen on the public internet, and you should drop them at the border of your organisation for spoof protection. Unique local unicast is defined as fc00::/7.
Global unicast
The entire IPv6 internet resides within the 2000::/3 subnet. This is important; where with IPv4 you might allow connections from ANY with IPv6 you allow connections from 2000::/3. Like so:
ip6tables -A INPUT -s 2000::/3 -p tcp --dport 22 -m state --state NEW -j ACCEPT
ip6tables -A INPUT -s 2000::/3 -p tcp --dport 80 -m state --state NEW -j ACCEPT
Conclusion
There's a whole bunch of stuff you need to take into consideration when configuring firewalls for the IPv6 internet, and I'm sure there's stuff I've missed so please leave comments telling me what they are.
Tags firewall, ip, ip6tables, iptables, ipv6, netfilter, packetfilter, pf, security, v6 | 4 comments
[ Posted by James Harton
Tue, 19 May 2009 00:48:42 GMT ]
Around the end of last year I wrote a IP and IPv6 flow handler in Pike for some packet analysis I wanted to do.
The code is available here under the GNU LGPL.
It's simple to use, and there is a demonstration app which simply keeps track of all your flows and periodically prints out all your active connections:

Just take a look at flow.pike in the archive. The important part being void capture_cb(). It takes the packet from libpcap and explodes it with the Ethernet.Frame module, it then takes a look at the frame type. It passes IP packets to either IP.v4.Packet or IP.v6.Packet and then on to IP.Flow.Engine for processing into a flow. Something I threw in to show how easy it is to work with is de-encapsulation of 6to4 packets from within IPv4 packets.
I should write some documentation, but in the mean time just email me if you have questions. Thanks to Bill for Public.Network.Pcap.
Posted in Projects, Culvert, Pike | Tags analysis, flow, ip, ipv4, ipv6, packets, pcap, pike, state | no comments