Managing IPv6 - Part 1
By Ryan Giobbi on August 19, 2009 10:07 AM | Permalink
This entry is the first in a series about securely configuring the IPv6 protocol on selected operating systems. Although this entry focuses on how to disable IPv6, we are not recommending that everyone immediately disable IPv6. However, if critical parts of your infrastructure (firewall, IDS, etc.) do not yet fully support the IPv6 protocol, consider disabling IPv6 until those components can be upgraded.
The following are some of the reasons why an administrator would want to disable IPv6:
* Many networks have IPv6 connectivity running on their LAN but do not have IPv6 WAN connectivity. Programs may see the connectivity on the LAN and unsuccessfully attempt to use IPv6 to connect to remote IPv6-enabled servers.
* Local IPv6 traffic might be able to bypass IDS systems or other low-layer network defenses.
* Operating systems may obtain global (publicly reachable) IPv6 addresses by creating tunnels.
* Running an additional protocol increases a system's attack surface.
* Global addressing restores end-to-end connectivity.
There are also more than a couple of reasons why an administrator wouldn't want to disable IPv6 connectivity:
* The network has full IPv6 connectivity, and software on the network actively uses some of the features (usually the large pool of global addresses) found only in IPv6.
* Network services running on the LAN are actively using IPv6.
* The network is designed to be a "dump pipe," and the administrator is expected to not interfere with passing traffic.
* Global addressing restores end-to-end connectivity.
Below are instructions for disabling IPv6 on some popular operating systems. At the bottom of the entry are links to scripts that you can run from the command line.
Disabling IPv6 via firewalls or access control lists
To disable IPv6 at a router or firewall, block protocols 41, 43, 44, 58, 59, and 60 as well as UDP ports 3544 and 3545. This firewall policy will likely miss some tunneled and non-routed IPv6 traffic (such as Teredo-compatible tunnels on non-standard ports) running on the local network.
There is too much variation in firewall syntax for us to list rules for every vendor; instead, we've written a few rules in Cisco's ACL syntax and included an ip6tables script linked at the bottom of this page.
access-list ipv6 deny 41 any any
access-list ipv6 deny 43 any any
access-list ipv6 deny 44 any any
access-list ipv6 deny 58 any any
access-list ipv6 deny 59 any any
access-list ipv6 deny 60 any any
access-list ipv6 deny udp any any eq 3544
access-list ipv6 deny udp any any eq 3545
Disabling IPv6 on Windows XP and Server 2003
The easiest way to disable IPv6 on Windows XP and Server 2003 is to run this command from a prompt with administrator privileges and reboot:
netsh.exe interface ipv6 uninstall
Disabling IPv6 on Windows Vista and Server 2008
The IPv6 protocol cannot be uninstalled from Windows Vista. The most effective way of disabling it is to edit the registry:
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip6\Parameters\DisabledComponents]
"Compatibility Flags"=dword:0xFFFFFFFF
If you don't want to edit the registry, the following netsh commands will effectively block IPv6. Note to administrators: using the "domain profile" feature of the Windows firewall will allow you to create rules that block IPv6 connectivity based on whether the user is authenticated to your domain.
netsh advfirewall firewall add rule name "IPv6" protocol=icmpv6 dir=out action=block
netsh advfirewall firewall add rule name "IPv6" protocol=icmpv6 dir=in action=block
netsh advfirewall firewall add rule name "IPv6" action=block protocol=41 dir=out
netsh advfirewall firewall add rule name="IPv6 protocol 43" protocol=43 action=block dir=out
netsh advfirewall firewall add rule name="IPv6 protocol 44" protocol=44 action=block dir=out
netsh advfirewall firewall add rule name="IPv6 protocol 58" protocol=58 action=block dir=out
netsh advfirewall firewall add rule name="IPv6 protocol 59" protocol=59 action=block dir=out
netsh advfirewall firewall add rule name="IPv6 protocol 60" protocol=60 action=block dir=out
Disabling IPv6 on Red Hat Enterprise Linux 5
1. Edit /etc/sysctl.conf
2. Append "net.ipv6.conf.all.disables_ipv6 = 1"
3. Execute "sysctl -p" as root
You can modify "net.ipv6.conf.all.disables_ipv6 = 1" for a specific interface (e.g., "net.ipv6.conf.eth1.disables_ipv6 = 1") to selectively disable IPv6 on that interface.
The following steps will disable IPv6 connectivity on all interfaces:
1. Edit /etc/modprobe.conf
2. Append "alias net-pf-10 off"
3. Execute the command "modprobe -a" as root
For those of you who really want to disable IPv6, add these lines to your iptables scripts:
ip6tables -P INPUT DROP
ip6tables -P OUTPUT DROP
ip6tables -P FORWARD DROP
ip6tables -I INPUT -p all -j DROP
ip6tables -I OUTPUT -p all -j DROP
Disabling IPv6 on Ubuntu Linux (version 9.04)
1. Edit /etc/sysctl.conf
2. Append "net.ipv6.conf.all.disable_ipv6 = 1"
3. Execute "sysctl -p" as root
You can modify "net.ipv6.conf.all.disable_ipv6 = 1" for a specific interface (e.g., "net.ipv6.conf.eth1.disable_ipv6 = 1") to selectively disable IPv6 on that interface.
The following steps will disable IPv6 connectivity on all interfaces:
1. Edit /etc/modprobe.d/blacklist
2. Append "blacklist ipv6"
3. Execute the command "modprobe -a" as root
Ubuntu users who run UFW can check /etc/default/ufw. If IPV6=no, you can block IPv6 connectivity with this command:
sudo ufw disable && sudo ufw enable
Scripts
Here are files you can use to disable IPv6. As with all scripts, make sure you understand the implications before running these on your system.
* ip6tables router/firewall shell script
* batch file to disable on Windows XP and Server 2003
* reg file to disable IPv6 on Windows Vista and Server 2008 (Microsoft has published instructions on how to import. Also see the instructions in the solution section of TA09-020A.)
Reference: http://www.cert.org/blogs/vuls/2009/08/managing_ipv6_part_i.html
Managing IPv6 - Part 2
Past entries have addressed both securing and disabling IPv6. This entry describes ways that administrators can secure their networks and generate test cases to test those settings.
Administrators and developers who work with IPv4 will notice that IPv6 has made some changes beyond offering many more addresses than IPv4. The following are some of the changes that have security impacts:
* Many hosts that currently have private IPv4 addresses will have global, publicly reachable addresses.
* ICMPv6 contains much of the functionality of DHCP in IPv4 and cannot easily be entirely filtered.
* IPv6 addresses can be predictable or partially random. Modern operating systems allow both, and there is a tradeoff between system management ease of use and user privacy.
These changes can cause problems. For example, a host that accepts any ICMPv6 type can be fingerprinted easily from remote systems. That might not be a problem for some networks, but it could be critical for others.
There are ways for administrators to handle these challenges. The examples below aren't universally applicable, so use them as a general guide.
Managing networks using global IPv6 addresses
Globally reachable addresses are not "hidden" in the same way as NAT addresses. To filter traffic destined to these clients, administrators can use application-layer proxy servers, stateful network filtering, or host-based firewalls.
Below is an example of filtering traffic to a globally reachable IPv6 address. For the purpose of these rules, 2001:1::/64 is the local network, eth0 is the LAN interface on a firewall, eth1 is the WAN interface on the firewall, and 2001:3::1 is an IPv6 address on the internet.
ip6tables -A FORWARD -p tcp -i eth0 -s 2001:1::/64 -p tcp -j ACCEPT
ip6tables -A FORWARD -p tcp -m state --state ESTABLISHED,RELATED -j ACCEPT
ip6tables -A FORWARD -p tcp -i eth1 --dport 3389 -s 2001:3::1 -j ACCEPT
ip6tables -A FORWARD -p tcp -i eth1 -m state --state NEW,INVALID -j DROP
The following is an explanation of what's happening in these rules, based on the behavior of a typical router doing NAT.
ip6tables -A FORWARD -p tcp -i eth0 -s 2001:1::/64 -p tcp -j ACCEPT
Pass any traffic that has entered on our LAN's ethernet interface (-i eth0) and that has a source address in the range our LAN is using (2001:1::/64).
ip6tables -A FORWARD -p tcp -m state --state ESTABLISHED,RELATED -j ACCEPT
Pass any traffic that is part of an existing connection.
ip6tables -A FORWARD -p tcp -i eth1 --dport 3389 -s 2001:3::1 -j ACCEPT
Allow any traffic coming into our WAN interface (-i eth1) to pass through to our LAN if it matches the TCP port used for RDP (--dport 3389).
ip6tables -A FORWARD -p tcp -i eth1 -m state --state NEW,INVALID -j DROP
Drop all other traffic.
After configuring the firewall, administrators should test the ruleset to confirm it is working as expected. Two commonly used tools that can test IPv6 TCP and UDP policies are nmap and netcat6.
Building on the example above, let's imagine that a user logs into a host with IP address 2001:1::2/64 and starts a netcat listener on port 3389:
$ netcat6 -l -p 3389
A scan of that IP from any host on the internet other than 2001:3::1 should fail. This result can be verified with an nmap comand:
$ nmap -PN -sT 2001:1::2/64 -p 3389
Starting Nmap 4.76 ( http://nmap.org ) at 2009-09-02 14:32 EDT
Interesting ports on 2001:1::2:
PORT STATE SERVICE
Filtering selected ICMPv6 types
The ICMPv6 protocol includes some great functionality. IANA maintains a list of ICMPv6 types and codes.
It is hard to make general statements about which ICMPv6 types should be allowed or denied. The following chart provides some guidance about reasonable firewall policies applied to ICMPv6 types. The types are listed based on whether or not the ICMPv6 type can typically be allowed or denied.
ICMPv6 types typically safe to allow
Purpose/Comments
1, Destination Unreachable general connectivity testing
2, Packet Too Big
sent by routers to notify a node that it should fragment the packets
3, Time Exceeded protects against routing loops
4, Parameter Problem error messages and handling
128, Echo Request ping
129, Echo Reply ping reply
133, Router Solicitation sent by clients to the all-nodes multicast address to request an IP address assignment
134, Router Advertisement
sent by routers to the all-nodes multicast address; clients can use the information in this message to generate an address
135, Neighbor Solicitation queries nodes for IP and connectivity information
136, Neigbor Advertisement
sends IP and connectivity information to other nodes
ICMPv6 types that can typically be denied
Purpose/Comments
137, Redirect
alerts clients to send traffic to another router, presumably one with a more direct route to the destination; like other ICMPv6 types listed, these messages are unauthenticated and could be malicious
138, Router Renumbering automatic reconfiguration of routers
139, Node Information Query allows a host to be fingerprinted
140, Node Information Response allows a host to be fingerprinted
151-154 deny by default
others not yet used, deny by default
We've talked about filtering ICMPv6 types before, so there's no reason to discuss it again. Instead, let's focus on some test case generation options.
There don't seem to be many tools that can generate arbitrary ICMPv6 packets. One of the more commonly used tools is ping6 or ping -6. The ping command sends an echo request message to an individual IPv6 address. Creating arbitrary ICMPv6 types requires a different tool.
Newer versions of the scapy packet crafting tool can be used to generate most ICMPv6 types. Here's an example of typical scapy usage:
# scapy
Welcome to Scapy (2.0.1-dev)
>>> a=IPv6(dst="2001:1::2")/ICMPv6ND_Redirect()
>>> send(a)
To list the available ICMPv6 types (layers), use the ls() command:
>>> ls()
ARP : ARP
ASN1_Packet : None
BOOTP : BOOTP
CookedLinux : cooked linux
...
ICMPerror : ICMP in ICMP
ICMPv6DestUnreach : ICMPv6 Destination Unreachable
ICMPv6EchoReply : ICMPv6 Echo Reply
ICMPv6EchoRequest : ICMPv6 Echo Request
ICMPv6HAADReply : ICMPv6 Home Agent Address Discovery Reply
ICMPv6HAADRequest : ICMPv6 Home Agent Address Discovery Request
ICMPv6MLDone : MLD - Multicast Listener Done
ICMPv6MLQuery : MLD - Multicast Listener Query
ICMPv6MLReport : MLD - Multicast Listener Report
...
To view what parameters a layer will take, use the ls() command again:
>>> ls(ICMPv6ND_Redirect())
type : ByteEnumField = 137 (137)
code : ByteField = 0 (0)
cksum : XShortField = None (None)
res : XIntField = 0 (0)
tgt : IP6Field = '::' ('::')
dst : IP6Field = '::' ('::')
This information can be used when creating packets to allow greater control over specific packets:
a=IPv6(dst="2001:1::2")/ICMPv6ND_Redirect(tgt="2001:1::3")
Disabling/enabling privacy extensions
Currently, IPv6 addresses are typically assigned via stateless autoconfiguration, DHCPv6 or static assignment.
With stateless autoconfiguration, an operating system is expected to generate part (usually the lower 64-bits) of its address. If privacy extensions are enabled, the generated address will be pseudo-random. This is good for privacy but makes remote management difficult.
On Windows Server 2008, privacy extensions can be controlled with a netsh command:
C:\> netsh interface ipv6 privacy enabled|disabled
Linux users should check /proc/sys/net/ip6/conf (the exact location varies between distributions and kernel versions).
Testing the address status of other systems on the same Ethernet segment is possible, assuming that echo requests and replies are accepted on those machines. If the following commands run on a Linux system produce predictable addresses, privacy extensions are disabled:
$ ping6 -B -I eth0 -I [global IPv6 address attached to eth0] ff02::1
$ ip neighbor
Windows users can use these commands:
C:\> ping -S [global IPv6 address] -6 ff02::2
C:\> netsh interface ipv6 show neighbors
Reference: http://www.cert.org/blogs/vuls/2009/10/managing_ipv6_-_part_2.html