This article is part of a series which depicts some of the notes I took during several sessions in the Palo Alto Networks Ignite conference in Las Vegas.
IPv6 Security Notes
- Ensure that the IPv6 Firewalling option has been enabled under device > settings otherwise the PaloAlto will just route IPv6 traffic. Post PAN-OS v5 will enable this option by default
- When writing IPv6 security policies targeting ICMP traffic, use the ipv6-icmp application object. Contrast this to IPv4 traffic which uses the icmp and ping address objects
- ICMP plays a much more important role in IPv6 than it did in IPv4, so do not completely block ICMP. This will definitely break some features such as Path MTU discovery and possibly others such as neighbor discovery.
Checklist when buying or migrating to IPv6 capable equipment
- Ensure routers and switches are IPv6 capable. Unless these are very old, they tend to be very feature rich and generally only a software upgrade is needed to obtain IPv6 capabilities
- IPv6 management capability
- IPv6 High Availability features
- IPv6 application and user based policies
- Reporting and visibility into IPv6 traffic
- IPv6 SSL decryption
- IPv6 Holistic threat prevention
- Check for IPv6 ready certification:
The above checks for compliance with several IPv6 features, such as:
- Correct header processing
- Extension header processing
- Fragmentation behavior
- Neighbor discovery and auto configuration
- Router redirects
- ICMPv6 behavior
- However, note that the above do not include any security considerations
Illustration of IPv6 security issues
- Tunneling and other transitional mechanisms can circumvent IPv4 based security policies
- Example: SLAAC [stateless autoconfiguration] attack
The above described attack is easy and normally successfully carried out because:
- IPv6 is now enabled and prefered by default
- Tunneling over IPv6 can provide an easy way out to the internet for an attacker
- Since world IPv6 day, more and more sites are switching on IPv6, meaning most PC prefer to use IPv6 to reach sites such as facebook, google, etc
Mitigation of IPv6 attacks
- Use a static IPv6 host configuration
- Disable IPv6
- Positive enforcement: use policy to shut down tunneling and other known mechanisms that are unneeded and can be used for nefarious purposes
IPv6 PAN-OS notes
Updated support for:
- USER ID
- NAT64 (transition mechanism, NAT IPv6 addresses to IPv4
- OSPFv3 support still lacking
- MP-BGP support still lacking
The article is a more in-depth look at residential IPv6, the final installment of the 2 part series. If you’ve missed it, the 1st article can be found here.
After having established a successful connection to an IPv6 broker server, I fired up wireshark to see what is going on over the wire. We immediately observe IPv6, and in outgoing packets, we can also see the IPv6 in IPv4 encapsulation I mentioned previously:
You can see the inner IPv6 header, encapsulated within a UDP IPv4 datagram on the outside. This transition method is the whole reason why isolated IPv6 “islands” can talk to each other over an as-of-yet predominantly IPv4 internet. As I noted in part 1, observers will note that I did not need any sort of DHCP server to get IPv6 addresses on other nodes in my home network. While DHCPv6 still does play a very important role, another, more automatic method has been introduced in IPv6. This is the router solicitation and router advertisement method. We can see two such packets here:
The first packet, a router solicitation, is sent from a nodes link local address to the “all routers” address (ff02::2). A router will answer with the second packet, a router advertisement, always using the link local address, which looks something like this:
Among the myriad of options, the most important to note is the “prefix information”, which the client uses to build it’s unique global address, using a combination of this prefix and it’s MAC address, without the need of any DHCP server. Similarly, IPv6 has done away with broadcasts, which also includes IPv4′s cornerstone ARP. Instead of ARP, IPv6 uses a similar mechanism to the one presented above, called neighbor solicitation and neighbor advertisement. It serves exactly the same function as ARP… translating a L3 IP address to a L2 MAC address, yet instead of using broadcasts which every node on the link must process, it uses a special form of multicast which only a few nodes will process. For example, we see two such packets here:
In the above screenshot you see the first packet as a “neighbor solicitation” for fe80::5e26:aff:fe15::772f“. Note I drew a relationship between the IP being asked for and the multicast address which the solicitation is being sent on. The multicast’s address last few octets match the MAC address, in fact this multicast address is built from the MAC address. While this is not a one-to-one relation (more than one node may process this multicast), it does significantly reduce the number of nodes that do actually process this packet. The second packet is the “neighbor advertisement” which you can see returns the MAC address.
While sniffing, we also see a bunch of ICMP “packet too big” packets:
These are because of another difference between IPv6 and IPv4: fragmentation. In IPv4, as many admin know, fragmentation can occur at any point along the packet’s path. In fact, in some cases modifying a gateway router/firewalls MTU can solve a number of issues. However, in IPv6, fragmentation can only be done by the end nodes – the PCs themselves. In order for PCs to be able to determine the path MTU, they rely on ICMP “packet too big” messages to figure out what size of packets are acceptable. This points to a valid lesson when building out IPv6 networks… do not block all ICMP traffic like we used to be able to do in IPv4! As you can see above, ICMP in IPv6 is an integral part of the protocol and it would not work without ICMP.
And finally…. a small screenshot of normal HTTP traffic over IPv6:
That is the end of this short IPv6 tutorial / primer, many thanks for reading!
World IPv6 day came and went, but for most of us nothing much changed. In Malta especially, there currently seems no interest for ISPs to start using IPV6, very probably due to the challenges it poses. So I went on a mission to bring IPv6 connectivity to my home network (FYI, there are already some enterprises using IPv6 in Malta – but I do not know of any residential native IPv6 connections in Malta at the time of writing). There are various free “IPv6 broker” services available on the internet. The most well known of these is “Hurricane Electric“. I decided to go with “freenet6” since it was slightly simpler to setup.
These tunnel broker services and others like them use a variety of methods to setup a tunnel, where IPv6 traffic is encapsulated within IPv4 traffic. This traffic is then sent to a server (the “broker” server) which is directly connected to the IPv6 backbone. The server decapsulates the IPv6 packet and sends it along it’s way over the IPv6 internet… and the reverse process for the way back.
This article is the first in a series that explores the pain free method of getting IPv6 connectivity, checking out some more practical and technical aspects of IPv6 along the way
The first order of the day is getting IPv6 connectivity. I used a windows 7 machine to run the freenet6 client, but the process is relatively similar for linux. First the freenet6 client needs to be downloaded, and as it states on the download page, you will need to register with the site. Once the client is downloaded, I also registered with freenet6 to be able to get an entire /64 IPv6 subnet to share with the other PCs in my house. This is because gogo6 provides two methods of connecting to the IPv6 internet:
- Only the PC where the client is installed will connect to the IPv6 internet
- The PC where the client is installed will connect to the IPv6 internet, and in turn will also act as an IPv6 gateway for other PCs in it’s network.
I opted for the second option, it’s more convenient for multiple IPv6 nodes. Once the registration and downloads are done, we are ready to connect to the IPv6 broker server. Freenet6 has made this a breeze. Once the client opens, you are presented with a straightforward page. To make sure I connected to the closest available server, I manually filled in the server address as “amsterdam.freenet6.net”, and entered in my credentials that I obtained when registering with freenet6:
Since I wanted this PC to act as an IPv6 gateway, the last step was to enable the option “Enable Routing Advertisements” under the Advanced tab:
That’s it as far as configuration goes…. In the “basic” tab just select connect and the client should connect. Should you run into issues, going to:
Log tab > Enable Logging to File > Open Log Window…
Will help in troubleshooting. Now, looking at the network configuration of the gateway PC we see:
Ethernet adapter Local Area Connection 3:
Connection-specific DNS Suffix . :
Description . . . . . . . . . . . : gogo6 Virtual Multi-Tunnel Adapter
Physical Address. . . . . . . . . : 02-50-F2-00-00-01
DHCP Enabled. . . . . . . . . . . : Yes
Autoconfiguration Enabled . . . . : Yes
IPv6 Address. . . . . . . . . . . : 2001:5c0:1400:b::d7fd(Preferred)
Link-local IPv6 Address . . . . . : fe80::4c25:3af1:4683:f358%28(Preferred)
Autoconfiguration IPv4 Address. . : 169.254.243.88(Preferred)
Subnet Mask . . . . . . . . . . . : 255.255.0.0
Default Gateway . . . . . . . . . : ::
DNS Servers . . . . . . . . . . . : 2001:5c0:1000:11::2
Ethernet adapter Local Area Connection:
Connection-specific DNS Suffix . :
Description . . . . . . . . . . . : Broadcom NetLink (TM) Gigabit Ethernet
Physical Address. . . . . . . . . : 00-1B-38-6F-F4-9A
DHCP Enabled. . . . . . . . . . . : No
Autoconfiguration Enabled . . . . : Yes
IPv6 Address. . . . . . . . . . . : 2001:5c0:1519:7900::1(Preferred)
IPv6 Address. . . . . . . . . . . : 2001:5c0:1519:7900:55b6:d837:f953:8024(Preferred)
Temporary IPv6 Address. . . . . . : 2001:5c0:1519:7900:307c:cb81:395c:622c(Preferred)
Link-local IPv6 Address . . . . . : fe80::55b6:d837:f953:8024%10(Preferred)
IPv4 Address. . . . . . . . . . . : 192.168.168.171(Preferred)
Subnet Mask . . . . . . . . . . . : 255.255.255.0
Default Gateway . . . . . . . . . : 192.168.168.168
The first interface “Description: gogo6…” is the virtual interface created by the freenet6 client. This basically creates an IPv6 point to point link with the broker server. Any traffic passing over this interface is encapsulated within IPv4 traffic and sent out. Also note how this interface is assigned an IPv6 DNS server.
The second interface “Description: Broadcom…” is my internal LAN address. It has both a valid IPv4 address, and 3 IPv6 addresses. This is the first difference between IPv4 and IPv6. We are used to dealing with a one-to-one relationship between IP and interface in the IPv4 world. However in IPv6 it is perfectly normal and expected to have multiple IPv6 addresse. In my case we have:
- IPv6 Address : this is the global, unique IPv6 address that is assigned to this PC. Imagine it as a kind of public IPv4 address assigned to my PC
- Temporaty IPv6 Address : this is another global, unique IPv6 address that is assigned to this PC. This PC uses the temporary IPv6 address when communicating with the outside world. It uses this address rather than the previous one for privacy concerns. If my PC where to continuously use the first IPv6 address that is unique to my PC, it would be very easy for an outsider to track my browsing an internet activity. To mitigate this, a temporary IPv6 address that is cycled periodically is used so that the IPv6 source address of a client is changed. Not a silver bullet, but it helps
- Link-local IPv6 address : this is the address that the PC uses when communicating with nodes on the same link (when I say link, read: “nodes in the same broadcast domain”). This address is used when determining IP addressing, during neighbor discovery (the IPv6 equivalent of ARP) and other functions. This address should never be sent to the public IPv6 network, it is unroutable.
Now to see if all this works. First we check if an IPv6 ready site is pingable. Via linux it’s a simple “ping6 http://www.google.com”. You can also visit sites such as http://test-ipv6.com/simple_test.html which tests for IPv6 connectivity.
Lastly, we check if other PCs in the network are detecting the newly created IPv6 gateway. In my case I have a linux host. Running ifconfig, we see:
eth0 Link encap:Ethernet HWaddr 5c:26:0a:15:77:2f
inet addr:192.168.1.18 Bcast:192.168.1.255 Mask:255.255.255.0
inet6 addr: 2001:5c0:1519:7900:5e26:aff:fe15:772f/64 Scope:Global
inet6 addr: fe80::5e26:aff:fe15:772f/64 Scope:Link
inet6 addr: 2001:5c0:1519:7900:b12f:7c01:32de:7e21/64 Scope:Global
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:10931 errors:0 dropped:0 overruns:0 frame:0
TX packets:12669 errors:0 dropped:0 overruns:0 carrier:0
RX bytes:5499387 (5.4 MB) TX bytes:2356845 (2.3 MB)
Note the 3 IPv6 addresses that are seen on the interface, similar to the windows machine. There are two global IPv6 addresses and one link local address.
The next post will delve a bit deeper and explore questions such as how clients in the network were provisioned with IPv6 addresses automagically – that is to say, without the need of any IPv6 DHCP servers, and how IPv6 traffic looks like over the network
As I mentioned in a previous post, if you’re troubleshooting an issue using wireshark, especially if you’re using IPv6, it can be a headache to keep track of which IP is which in a complex network. Imagine trying to write down or memorize the following IP addresses in the packet capture:
Wireshark can real the local hosts file (/etc/hosts or C:\windows\system32\drivers\etc\hosts) but using this to give arbitrary mappings between IPs and hostname is not a good idea since it may mess up your day-to-day connectivity
Instead, it’s a better idea to create a hosts file in C:\Program Files\Wireshark. Just create a file named “hosts” (no extension) and using the normal syntax add the IP to host mappings. For example:
Turn on network name resolution in wireshark via the edit > preferences > Name Resolution menu and enable the “enable network name resolution” option. Close and restart wireshark.
You should now have a much easier to read pcap:
As we progress into IPv6 networks, one of the more common transitory scenarios we will see will be similar to the following:
Especially in earlier stages, it is to be expected that isolated “pools” of IPv6 networks will need to communicate with a still predominantly IPv4 internet. One of the many ways of facilitating this is using an explicit proxy deployment which converts IPv6 requests to IPv4 requests. More experienced IPv6 users will argue that this is equivalent to the now depreciated NAT-PT (protocol translation) and there are now better ways such as tunnelling and relays to get an equivalent scenario working… but this is quite an easy and cheap way of achieving relatively good results.
Of course in this article i’m assuming that you already have an IPv6 network up and running. This isn’t such a big deal if you’re running relatively up to date OS such as windows 7 or ubuntu 10.10. In my case it was simply an issue of enabling IPv6 for the OS in question. Usually it’s enabled by default so it’s even less of a worry.
Initially I was testing using link-local addresses (FE80::/10 – see my previous post for more details) however this proved to be a bit of a pain for two main reasons:
1. Link-local addresses are not unique, so you must always specify an outgoing interface. To illustrate this a bit better, consider the output from this linux box when using ping6 or telnet with link-local addresses:
[root@localhost ~]# ping6 fe80::2d0:83ff:fe05:685
connect: Invalid argument
[root@localhost ~]# ping6 -I eth0 fe80::2d0:83ff:fe05:685
PING fe80::2d0:83ff:fe05:685(fe80::2d0:83ff:fe05:685) from fe80::20c:29ff:fe75:25fa eth0: 56 data bytes
64 bytes from fe80::2d0:83ff:fe05:685: icmp_seq=0 ttl=64 time=40.0 ms
64 bytes from fe80::2d0:83ff:fe05:685: icmp_seq=1 ttl=64 time=0.960 ms
64 bytes from fe80::2d0:83ff:fe05:685: icmp_seq=2 ttl=64 time=0.895 ms
— fe80::2d0:83ff:fe05:685 ping statistics —
3 packets transmitted, 3 received, 0% packet loss, time 2117ms
rtt min/avg/max/mdev = 0.895/13.951/40.000/18.419 ms, pipe 2
[root@localhost ~]# telnet fe80::2d0:83ff:fe05:685 8082
telnet: connect to address fe80::2d0:83ff:fe05:685: Invalid argument
telnet: Unable to connect to remote host: Invalid argument
[root@localhost ~]# telnet fe80::2d0:83ff:fe05:685%eth0 8082
Connected to fe80::2d0:83ff:fe05:685%eth0 (fe80::2d0:83ff:fe05:685%eth0).
Note how in either case i needed to either add the –I eth0 switch or append the %eth0 to the IP address for the tool to work. The same goes for firefox by the way. If you explicitly define the proxy link local IP in firefox you will need to include the %interface:
Internet Explorer is more forgiving, no need to use the %interface, but remember to enclose the proxy IP in square brackets [ ] :
It may not seem like a big deal to many, but trust me you will forget to do this at some point.
2. One other major troubleshooting drawback when using link local IPv6 addresses is that wireshark will not resolve link local addresses. If you’ve ever seen an IPv6 capture, you know it’s a nightmare to keep track of connections Wireshark can use it’s own local hosts file where you can define IP to hostname mappings to make it easier to keep track of addresses. But this will only work if you are using non link-local addresses. More about how to configure this in a later post.
For those reasons I decided to use unicast unique local (FC00::/7) IPv6 addresses in my testing. Strictly speaking you can use any IPv6 address within that prefix, but in my testing I simply copied the link-local address and changed the first octet from FE80 to FC00. So for example on my linux box I ran:
[root@localhost ~]# ifconfig eth0 add fc00::20c:29ff:fe75:25fa/64
Obviously configure similar IP addresses on the rest of your nodes.
From the proxy side of things, I got this working using both a bluecoat proxy and using the latest squid 3.1 (note: I found that the squid being served in the standard repositories was an older version, so make sure you get the latest squid 3.1).
So on the bluecoat it was relatively easy to get IPv6 working. Via command line we run:
Enter configuration commands, one per line. End with CTRL-Z.
#(config interface 0:1)ipv6 auto-linklocal enable
There is no need to enable ipv6 forwarding. If you then navigate to the interfaces section, you can then see a link local IPv6 address configured on the interface. Simply add your unique unicast local address there:
Make sure that the proxy listeners is set to intercept all explicit communication. The default gateway was of course set to an IPv4 gateway. There is no IPv6 gateway configured. Add the proxy IPv6 address to the browser. That’s it!. You can then see the traffic entering in IPv6 and leaving in IPv4:
Squid wasn’t any more difficult to setup. Make sure that the appropriate IP addresses are configured on your interface. In this case I’m using a one-armed proxy:
[root@localhost ~]# ifconfig eth0
eth0 Link encap:Ethernet HWaddr 00:0C:29:75:25:FA
inet addr:10.91.25.49 Bcast:10.91.25.255 Mask:255.255.255.0
inet6 addr: fc00::20c:29ff:fe75:25fa/64 Scope:Global
inet6 addr: fe80::20c:29ff:fe75:25fa/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:129282 errors:174 dropped:0 overruns:0 frame:0
TX packets:12553 errors:0 dropped:0 overruns:0 carrier:0
RX bytes:102065746 (97.3 MiB) TX bytes:1682607 (1.6 MiB)
Interrupt:59 Base address:0×2000
The default gateway was of course set to an IPv4 gateway. There is no IPv6 gateway configured.
For testing, I didnt change the squid.conf file much, just simply allowed all traffic, and ran
Make sure squid is listening on the IPv6 address:
[root@localhost ~]# netstat -na | grep 3128
tcp 0 0 :::3128 :::* LISTEN
Point your browser to the IPv6 address and that’s about it: