Category: Vendors


IPv6 firewalling on Vyatta.

A while ago, I described how to set up an IPv6 Tunnel, so you could experiment with IPv6 at home. But while I’ve set it up myself a dozen times by now, I rarely had the tunnel active for a long time. Reason: I’m not too happy about a connection without any sort of firewall applied. So in this post, I’m going to describe how to set up a basic IPv6 firewall on an interface in Vyatta. The Cisco-based solution might follow later. To be honest, I’m not even going to try the Windows Server based solution.

Vyatta allows for three directions to apply the rules: in, out and local. Local means traffic destined for the device itself. This is important: I do not have to define any entries in my rules concerning local packets, like routing protocols, LLDP and IPv6 neighbour discovery and router solicitation.

Also, I cannot just block all ICMPv6 packets. IPv6 routers cannot perform fragmentation, unlike IPv4. This means fragmentation has to be done by end nodes. An ICMPv6 type 2 datagram, “Packet too big”, has to be allowed through, otherwise connections will fail if a too big MTU value is used (because the end nodes never find out why it doesn’t work). ICMPv6 type 3 code 1, “Time exceeded” packets tell when fragments are lost during transit.  Finally, types 133-136 are for router solicitation and neighbour discovery, but are handled as local on the Vyatta. If you’re using other platforms, be aware that these types need to be allowed too.

Now for the real ‘firewalling’ part. I’m going to allow echo replies in, so I can ping outside devices. I will not be allowing echo requests in. Yes, that’s making me feel more secure, although it doesn’t have any added value anymore. I’m also letting IPSec through because I’m doing VPN experiments later on. Apart from that, UDP will be allowed, and TCP packets with the ACK bit set. This is similar to the keyword ‘established’ on a Cisco ACL, and will only allow return packets of active sessions. This is not the same as a stateful firewall, but it provides a basic defense against connection attempts. Here is the code:

reggle@vyatta# set firewall ipv6-name WANFW
[edit]
reggle@vyatta# set firewall ipv6-name WANFW description “Firewall to block incoming connections from IPv6 Tunnel”
[edit]
reggle@vyatta# set firewall ipv6-name WANFW default-action drop
[edit]
reggle@vyatta# set firewall ipv6-name WANFW rule 5 protocol icmpv6
[edit]
reggle@vyatta# set firewall ipv6-name WANFW rule 5 icmpv6 type packet-too-big
[edit]
reggle@vyatta# set firewall ipv6-name WANFW rule 5 action accept
[edit]
reggle@vyatta# set firewall ipv6-name WANFW rule 5 description “Must be allowed or MTU discovery will break”
[edit]
reggle@vyatta# set firewall ipv6-name WANFW rule 10 protocol icmpv6
[edit]
reggle@vyatta# set firewall ipv6-name WANFW rule 10 icmpv6 type pong
[edit]
reggle@vyatta# set firewall ipv6-name WANFW rule 10 action accept
[edit]
reggle@vyatta# set firewall ipv6-name WANFW rule 10 description “Allow ping replies”
[edit]
reggle@vyatta# set firewall ipv6-name WANFW rule 15 protocol icmpv6
[edit]
reggle@vyatta# set firewall ipv6-name WANFW rule 15 icmpv6 type time-exceeded
[edit]
reggle@vyatta# set firewall ipv6-name WANFW rule 15 action accept
[edit]
reggle@vyatta# set firewall ipv6-name WANFW rule 15 description “May cause fragmentation issues otherwise”
[edit]
reggle@vyatta# set firewall ipv6-name WANFW rule 20 ipsec match-ipsec
[edit]
reggle@vyatta# set firewall ipv6-name WANFW rule 20 action accept
[edit]
reggle@vyatta# set firewall ipv6-name WANFW rule 20 description “Allow incoming IPSec connections”
[edit]
reggle@vyatta# set firewall ipv6-name WANFW rule 30 protocol tcp
[edit]
reggle@vyatta# set firewall ipv6-name WANFW rule 30 tcp flags ACK
[edit]
reggle@vyatta# set firewall ipv6-name WANFW rule 30 action accept
[edit]
reggle@vyatta# set firewall ipv6-name WANFW rule 30 description “Allow established TCP connections”
[edit]
reggle@vyatta# set firewall ipv6-name WANFW rule 35 protocol udp
[edit]
reggle@vyatta# set firewall ipv6-name WANFW rule 35 action accept
[edit]
reggle@vyatta# set firewall ipv6-name WANFW rule 35 description “Allow stateless UDP”
[edit]

That’s it. After that, do a ‘set interfaces tunnel tun0 firewall in ipv6-name WANFW’, followed by ‘commit’, and it should work. You can test this by trying to ping an IPv6 host (like ipv6.google.com), which should work (echo reply allowed), while a ping to your computer should fail (echo request not allowed). The latter you can test on this website. Don’t forget to save the configuration if it works!

Advertisements

How to set up an IPv6 tunnel.

In an effort to promote IPv6 a bit more, I’m going to discuss three methods to set up an IPv6 tunnel today.

But first: what is an IPv6 tunnel and why would you need it? An IPv6 tunnel is a tunnel that transports IPv6 packets over an IPv4-only network, which is useful if you, like me, have an ISP that doesn’t use IPv6 addresses yet. By setting up the tunnel you can connect your local IPv6 network with the rest of the IPv6 internet. After configuring it, you should be able to surf to the Google IPv6 site.

Before you can begin configuring, you’ll first need an IPv6 provider. I used Hurricane Electric, others prefer Sixxs. Both are free. After registering on the site, you’ll receive a /64 subnet which is yours to use, as well as some details about setting up the connection. Yes, this means you get more IPv6 addresses for free to use in your living room than there are IPv4 addresses in the entire world.

After you have received your prefix we can begin configuration. Note that you’ll also receive a tunnel prefix which is used to configure the tunnel endpoints, as well as an IPv6 DNS server (which will require a DHCPv6 server to run on the network, annoying, I know). To make things consistent over the three configurations I’ll list example values that will be used:
Local IPv6 subnet:  2001:0:0:1234::/64
Tunnel subnet: 2001:0:0:1235::/64, with ::2 on our side and ::1 on the other endpoint side.
IPv6 DNS: 2000::2000
Device IPv4 address: 192.168.0.10
Tunnel endpoint: 50.60.70.80
Gateway to ISP: 192.168.0.1

I’m going to give the configuration for three types of device/operating system: a (virtualized) Vyatta 6.1, a (virtualized) Windows Server 2008 R2, and a Cisco 2691 router in GNS3. It is also possible to configure the tunnel on other devices (even an Apple Airport), but I have not tested those. Also, the tunnel used is an ipv6ip tunnel which uses IP Protocol 41. Since I’ll be passing through a NAT device (the ISP gateway), one of the tunnel endpoints will be a private address, which will be translated by the NAT device. You may need to put the IP in DMZ to forward the tunnel properly, or in my case, to forward the ICMP keepalives properly. And finally: the tunnel endpoint does not necessarily have two ethernet interfaces: the tunnel can be send out of the interface the IPv6 subnet is on.

Vyatta
Using the Vyatta as an IPv6 endpoint works stable and throughput is good. The basic version is free and it barely uses CPU, even when virtualized and under load, which makes for a nice endpoint without the need for a dedicated device. The configuration in the Vyatta is as following:

vyatta@vyatta:~$ configure
vyatta@vyatta# edit interfaces tunnel tun0
vyatta@vyatta# set encapsulation sit
vyatta@vyatta# set local-ip 192.168.0.10
vyatta@vyatta# set remote-ip 50.60.70.80
vyatta@vyatta# set address 2001:0:0:1235::2/64
vyatta@vyatta# set description “IPv6 Tunnel”
vyatta@vyatta# exit
vyatta@vyatta# set protocols static interface-route6 ::/0 next-hop-interface tun0
vyatta@vyatta# edit interfaces ethernet eth0
vyatta@vyatta# set address 192.168.0.10/24
vyatta@vyatta# set address 2001:0:0:1234::1/64
vyatta@vyatta# set ipv6 router-advert prefix 2001:0:0:1234::/64
vyatta@vyatta# exit
vyatta@vyatta# set system gateway-address 192.168.0.1
vyatta@vyatta# commit

Unfortunately, Vyatta currently does not properly support DHCPv6, so you can’t advertise the IPv6 DNS server to hosts in the subnet. In a dual stack environment this doesn’t break anything as the hosts will query the known IPv4 DNS servers, and those respond with IPv6 addresses in their payload if needed.

Cisco IOS
I can’t configure IPv6 on my 2611 routers, apparently they don’t have enough flash memory to store the right IOS version. The 3560 I have does support it with the Advanced IP Services IOS, but I don’t have that one, so I’m really out of luck here.
Update September 18, 2011: the 3560 has IPv6 support with the IP Services IOS as the Advanced IP Services is no longer used for a 3560, but there’s no support for tunneling as it can only be done in software and puts a heavy load on the CPU.

I resort to GNS3, where I set up a router and connect it to the physical network. The configuration of the tunnel is as following:

Router#configure terminal
Router(config)#ipv6 unicast-routing
Router(config)#interface Tunnel0
Router(config-if)#description IPv6 Tunnel
Router(config-if)#no ip address
Router(config-if)#ipv6 address 2001:0:0:1235::2/64
Router(config-if)#tunnel source 192.168.0.10
Router(config-if)#tunnel destination 50.60.70.80
Router(config-if)#tunnel mode ipv6ip
Router(config-if)#exit
Router(config)#ipv6 route ::/0 Tunnel0
Router(config)#interface FastEthernet0/0
Router(config-if)#ipv6 address 2001:0:0:1234::/64 eui-64
Router(config-if)#ipv6 nd prefix 2001:0:0:1234::/64
Router(config-if)#exit
Router(config)#ip default-gateway 192.168.0.1
Router(config)#end
Router#write

Note that, just like with the Vyatta, you have to tell the router which prefix to advertise over the subnet. I was unable to properly configure DHCPv6 so all hosts could get an IPv6 DNS server, despite best efforts. Either a command is not working as expected or I am doing it wrong, so for now, it will work just like the Vyatta, with hosts querying DNS by IPv4.

Windows Server 2008 R2
Despite that this is the only one of the three devices that has a GUI, most configuration on the Windows Server will be done through the command line as well. The netsh command allows you to manipulate the IP stack in detail, as shown in the following configuration:

C:\>netsh interface teredo set state disabled
C:\>netsh interface ipv6 add v6v4tunnel IPv6Tunnel 192.168.0.10 50.60.70.80
C:\>netsh interface ipv6 add address IPv6Tunnel 2001:0:0:1235::2
C:\>netsh interface ipv6 add route ::/0 IPv6Tunnel 2001:0:0:1235::1

The first command disables the build-in Teredo in Windows, which automatically tries to create an IPv6 tunnel in case such traffic is needed. If you care about security, I would recommend this command on all your Windows 7 computers.

Next, creating a gateway for the subnet. If you go to the Network & Sharing Center, choose Change Adapter Settings, you can give the network card facing the subnet a static IPv6 address, in this case 2001:0:0:1234::1/64. The gateway should be ::, DNS server 2000::2000.

Last, we make sure all hosts receive the DNS address. This requires the DHCP role installed on the Windows Server. If present, go to Server Manager, DHCP, and configure an IPv6 scope 2001:0:0:1234::/64. Next, in the scope options, add option 23, and fill in 2000::2000. Windows accepts this and does not give any warning, but I couldn’t get this to work without rebooting after this.

So, these are three methods to get your IPv6 tunnel working. I hope it is all clear, greetings!

Update October 18, 2011: the Cisco IOS and Vyatta configuration had a missing command: you need to configure a default-gateway, otherwise it will not know where to send the tunnel! Commands updated.

VRRP between Cisco and Vyatta.

I already mentioned in an earlier post that I was doing some experiments with Virtual Router Redundancy Protocol on routers from different vendors. For those of you not familiar with VRRP: it’s a protocol that allows multiple routers to share the same IP address, which then can be used as the default gateway for end devices. This gives you some redundancy in case a router goes down. VRRP is the IETF standard for an earlier protocol: HRSP, which is available on Cisco devices only. For more info, Wikipedia is your friend.

I already managed to get VRRP running on both GNS3 and real Cisco routers, but since it’s supposed to be a standard, why not try it in a multivendor environment? My favorite non-Cisco router is Vyatta: it’s a stripped-down Linux with nothing left but the kernel and network-related packages already installed. The command line handles somewhat like a Cisco IOS. Since it can run on almost any x86 hardware, you can virtualize it too, so it’s an easy solution in my lab. The basic version is free.

I followed the guide I found on openmaniak.com and got it running in no time. I used the following configuration: 192.168.0.2 for the Vyatta, 192.168.0.3 for the Cisco router (a 2611 running 12.3 IOS), and 192.168.0.5 as the virtual IP address.

I started and configured my Vyatta first. Here you see it sending VRRP multicasts to 224.0.0.18, to announce to the other router(s) that he’s currently the master and will handle all packets send to 192.168.0.5, the virtual address.

VRRP Vyatta

Next, I booted and configured the Cisco router. Note that both configurations used the ‘preempt’ command, which means that if a ‘better’ router is present in the subnet, it will immediately assume the master role, instead of waiting until the current leader (the Vyatta) goes down. The ‘better’ router here means the one with the higher priority, or in case of a tie, the one with the highest IP address.

Since the Cisco router has a higher IP address, it takes the master role after a few seconds:

After the Cisco router becomes the master, it will handle any packet destined for 192.168.0.5. Should the router fail, for example by me unplugging the ethernet cable, the Vyatta router will take the master role again and the address 192.168.0.5 will stay reachable.

So far so good. But I did come across a small problem in my tests. if you watch both images closely, you’ll notice that the Cisco router is using a source MAC address of 00:00:5e:00:01:01. This is correct, because this is the MAC address that must be used according to the RFC. (The last ’01’ is the VRRP group 1. Had I configured it with VRRP group 5, it would be ’05’.)

The Vyatta router does not use this MAC address but instead uses his own (00:0c:29:fd:d5:23, VMWare virtual NIC). I’ve done some research around the web and could not find anything conclusive, but I’ve heard of Linux versions having trouble using multiple source MAC addresses, so this may be the cause. It does create a problem though, because if a router fails in this configuration, the end devices are left with the wrong ARP information, making the 192.168.0.5 address unreachable after all. It’s possible to solve this issue by sending a Gratuitous ARP packet in case of a failure, but I didn’t notice such a packet in my tests, and it would still make things more complex than they are supposed to be. At this moment I am uncertain if VRRP works well in Vyatta. But that aside, I did learn a lot today.