The last week I’ve been working on bringing Snort_inline to the Snort 188.8.131.52 level, including it’s IPv6 support. I’m almost ready to commit it to SVN, there are just some issues I need to fix in the inline specific code. The code will get rid of libdnet and use libnet 1.1 for sending reset/reject packets for both IPv4 and IPv6. After committing I will start working on getting the IPv6 features I wrote for NitroSecurity into this tree. This includes more matches, tunnel decoding (including for example the freenet6 tunnel, etc). So stay tuned!
Libnet is a cool packet crafting tool, used by Snort to send TCP reset packets and ICMP unreachable packets as part of active responses. Libnet 1.1 supports IPv6 which is what I needed for my work. After some reading and testing there were a few problems. First, while possible to send TCP reset packets, the packets didn’t have a correct checksum and debugging this with valgrind showed lots of memory errors. Second, ICMPv6 was only partly implemented. The libnet_build_* functions for it are missing. This is, by the way, quite a common picture. Many libraries and projects have some support for IPv6, but generally incomplete and less well tested.
For my work on a IPv6 enabled Snort_inline I’ve only fixed the checksum issue and added a libnet_build_icmpv6_unreach() function. The patch against libnet 1.1.3-RC-01 can be found here. It’s development was funded by the great people of NitroSecurity Inc., who are funding my work to bring IPv6 to Snort_inline. The work is not based on Sourcefire‘s recent IPv6 implementation, so it will be interesting to see if and how those codebases can be used to improve each other. The changes to Snort_inline will be made available as well later, WhenItsDone(tm) 🙂 Like with the support for NFQueue, NitroSecurity gives back to the community, which I really appreciate!
I wrote about my experiments with IPv6 before. These were done for my home network where I have an ISP that offers an IPv6 tunnel broker. The last two months I have not been in my home, but instead using internet ‘on the road’ mostly through wireless LANs. There are a number of techniques for using IPv6 if your provider doesn’t offer it, and today I stumbled on one in this NetworkWorld article, so I decided to give it a try.
The artice is about a new IPv6 portal called go6.net, where you can find IPv6 related news and forums. Next to this access to a free IPv6 broker is offered: freenet6. Freenet6 works by tunneling the IPv6 packets in UDP packets over IPv4. Getting it is easy, register an account and download the software. When you are running Debian or Ubuntu you can even skip the last step, a mere ‘apt-get install freenet6’ will do it. This is what I did. Next I just had to enter the username and password I had entered in the registration process in a file called ‘/etc/tsp/tspc.conf’ and issue the command ‘tspc -f /etc/tsp/tspc.conf’. Opening go6.net and kame.net comfirmed I was using IPv6!
Since I’m behind NAT-router internet hosts can’t connect to my laptop directly, but with IPv6 this changes. My laptop is now using a public IPAdress, so I set up a simple firewall script using ip6tables. I found two sites enabling you to check how the internet sees you, here and here. Both showed that my firewall is working. Good.
So now I wanted to blog about this, so I tried to login to my blog… ‘Access Denied’. Oops! Forgot that I only allow certain IPv4 addresses to the admin interface of my blog. This was a good time to see how ModSecurity deals with IPv6 addresses in its rules:
SecRule REMOTE_ADDR “!(192.168.1.2|2001:5c0:8fff:fffe::62fd)” “chain,phase:1,deny,redirect:http://www.inliniac.net/nologin.html”
SecRule REQUEST_URI “/wp-login.php$”
This rule blocks access to wp-login.php for everyone but 192.168.1.2 and 2001:5c0:8fff:fffe::62fd, and redirects them to a static page called nologin.html. This works using IPv6 as well! As you can see ModSecurity does not only support IPv6, it even allows you to mix IPv4 and IPv6 addresses in rules! Now all that was left was the /wp-admin/ section that didn’t block in ModSecurity, but just with Apache itself:
Deny from all
Allow from 192.168.1.2
Allow from 2001:5c0:8fff:fffe::62fd
After an Apache restart I could write this post using IPv6!
As I wrote before, I’m experimenting with IPv6. I have a tunnel to my ISP from my router. The router is running Linux and uses radvd to advertise my IPv6 prefix to my networks. My dmz, in which this blog is hosted, get the 2001:888:13c5:cafe::/64 prefix. The IPaddresses are then created by taking the MACaddress of a network interface and placing that behind the prefix. It’s a nice and simple autoconfiguration system. So the IPv6 address of the blog is 2001:888:13c5:cafe:20c:29ff:fe13:2b42.
What I didn’t realize when I set this up like this, is that the MACaddress is visible and possibly giving valuable information to an attacker. See for example the output of the following command:
# ipv6calc 2001:888:13c5:cafe:20c:29ff:fe13:2b42 –showinfo
No input type specified, try autodetection…found type: ipv6addr
No output type specified, try autodetection…found type: ipv6addr
Address type: unicast, global-unicast, productive
Address type has SLA: cafe
Registry for address: RIPE NCC
Interface identifier: 020c:29ff:fe13:2b42
EUI-48/MAC address: 00:0c:29:13:2b:42
MAC is a global unique one
MAC is an unicast one
OUI is: VMware, Inc.
The last line said it: I’m running the blog on VMware. This might be interesting info for an attacker, which otherwise would not have been available, or at least not this easy.
To prevent this you can just setup a manual IPaddress, which is wiser from a maintainability point of view anyway, since you don’t want to update your DNS records everytime the server gets a new NIC. But still, it shows that IPv6 has it’s own gotchas and peculiarities in the security area.
My ISP is one of the few here in the Netherlands that provides a IPv6 tunnel broker. I have played with it some during the last year or so, but now decided to get a little more serious with it. So I’ve decided to enable it for my blog. When opening up my site to IPv6 one thing that is important is security. I will describe the status of IPv6 support of my current setup:
Linux firewalling: IPtables supports IPv6 for quite some time, however it only very recently gained stateful packet filtering support. This hasn’t made it into Debian Sarge or even backports yet, so I’m just using stateless filtering now.
Vuurmuur: my own IPtables frontend has no support for IPv6 at all. I’ve been thinking about adding it for years, but decided to wait at least until stateful support would be available. Next to this my coding time is limited, and many other features are probably more interesting to Vuurmuur users.
Snort/Snort_inline: both Snort and Snort_inline lack support for IPv6. Sourcefire is working on it as far as I know, but no code is available from them. I did find a IPv6 patch for Snort 2.3.3, which can be found here. I ran it in sniffer mode and that works. I haven’t played with it much other than that, but I certainly will in the future.
ModSecurity: my Apache 2 installation has IPv6 enabled by default and ModSecurity 2.x just worked with it without any configuration change! I haven’t looked into how to create rules specific for IPv6 addresses however, so maybe surprises will come up here. I do know from looking at the source that the rbl functionality doesn’t support IPv6 addresses yet, but I haven’t even checked if realtime blacklists exist for IPv6.
Sguil/Modsec2sguil: my modsec2sguil script, that takes ModSecurity alerts and feeds them to Sguil, doesn’t act on the IPv6 alerts because it expects IPv4 addresses. This is not a problem however, since Sguil doesn’t support IPv6 addresses. This makes sense since Snort doesn’t support it either.
So compared to my IPv4 access, protection is somewhat limited. I’m only enabling HTTP for now, so ModSecurity should be able to handle that just fine.
Anyway, it seems to be working fine now, but consider the IPv6 support experimental, as I’m playing with how it all works. So don’t be surpised if it’s broken all of a sudden 😉