Ubuntu has a newer Internet protocol called IPv6 turned on by default. However, some hardware — such as NICs and modems — shows broken behavior when exposed to IPv6 related DNS requests[1]. This leaves you wondering why DNS resolution seems slower or doesn't work at all. This guide shows how to disable this new protocol.

[1] « Various forums on the Internet carry reports of people disabling IPv6 because of perceived slowdowns when connecting to hosts on the Internet. This happens because of DNS resolver issues.

This "slow-down" results from DNS resolution failures due to broken NAT 'routers' and other DNS resolvers which don't know how to handle the AAAA DNS query. These DNS resolvers just drop the DNS query request for the AAAA record, instead of returning the appropriate negative DNS response. Because the request is dropped, the host sending the request has to time out, thus causing a perceived slow down when connecting to new hosts.

Note that DNS queries happen over any transport available (IPv4, if only protocol); the transport is independent from the type of query. »

  • Jeroen Massar

Blackhole IPv6 route

Slow responses are often due to the presence of a default route for IPv6 but which is not connected to the Internet. Routers and or other machines on the network may advertise themselves as IPv6 routers, and your own host's Linux kernel can add these as a default IPv6 gateway automatically (probably only when there is no default route yet). To counter this issue, you can block all received Router-Advertisement (RA) packets either by setting a sysctl flag or using ip6tables (tutorials for that elsewhere).

In /etc/sysctl.conf one would add:

net.ipv6.conf.all.accept_ra = 0

or with ip6tables (further actions may be needed to make this permanent across reboots),

ip6tables -I INPUT -p ipv6-icmp --icmpv6-type router-advertisement -j DROP

Hosts having working IPv6 networking do have a default route (as shown below); conversely, if you do not have IPv6 internet, no "default.." line should be present to avoid delays. If RA is blocked from the start, no such route should spring into existence either, thereby solving the problem.

# ip -6 r
2a01:198:200:f::/64 via :: dev sit1  proto kernel  metric 256  mtu 1392 advmss 1332 hoplimit 4294967295
fe80::/64 dev rtl0  proto kernel  metric 256  mtu 1500 advmss 1440 hoplimit 4294967295
fe80::/64 dev sis0  proto kernel  metric 256  mtu 1500 advmss 1440 hoplimit 4294967295
fe80::/64 via :: dev sit1  proto kernel  metric 256  mtu 1392 advmss 1332 hoplimit 4294967295
default via 2a01:198:200:f::1 dev sit1  metric 1024  mtu 1392 advmss 1332 hoplimit 4294967295

The rationale behind this is: If there is no default IPv6 route, attempts to connect with outside IPv6 hosts immediately fails because there is no route to them, and programs can continue to try with IPv4 without delays.

Hence, completely disabling IPv6 by removing addresses on interfaces or unloading the module is often just a bad workaround. Below's claims w.r.t. DNS are therefore to be taken with lots of salt.

Checking whether IPv6 is Enabled

Open up a terminal and type:

test -f /proc/net/if_inet6 && echo "Running kernel is IPv6 ready"

If it says

Running kernel is IPv6 ready

then IPv6 is enabled. If there's no output, then IPv6 is disabled.

Disabling IPv6

Instructions for Ubuntu 8.04 LTS (Hardy Heron)

Ubuntu 8.04 LTS Server Edition (to disable before installation)

This is similar to adding the "noipv6" boot option in Red Hat / Fedora / CentOS during installation. The file "/etc/modprobe.d/blacklist.local" with content shown below will be created:

# Local module settings
# Created by the Debian installer

blacklist ipv6
  1. Boot the Ubuntu 8.04 LTS Server Edition Installation CD (of course!)
  2. Select your language
  3. Highlight "Install Ubuntu Server" (DO NOT press "Enter")
  4. Press the function key "F6"
  5. Add "ipv6.blacklist=yes" to the kernel parameters (The line should read "... -- ipv6.blacklist=yes" afterwards)

  6. Press the "Enter" key to continue with the installation as usual

Ubuntu 8.04 LTS Desktop Edition (to disable before installation)

  1. No method as far as I know. Please follow the instructions below.

Ubuntu 8.04 LTS (to disable after installation, by blacklisting the ipv6 module)

Copied from the manpage of modprobe.conf(5):

blacklist modulename

Modules can contain their own aliases: usually these are aliases describing the devices they support, such as "pci:123...". These "internal" aliases can be overridden by normal "alias" keywords, but there are cases where two or more modules both support the same devices, or a module invalidly claims to support a device: the blacklist keyword indicates that all of that particular module's internal aliases are to be ignored.

On Debian and Ubuntu systems this keyword applies to user-defined aliases as well.

NOTE: Blacklisting a module does NOT prevent a module from being loaded if it is needed by a system service, regardless of the fact that it has been blacklisted. Besides, it does NOT prevent the module from being modprobe'd by root. You may want to disable IPv6 by aliasing net-pf-10 to off. Please refer to the section below for instructions. You may have read tutorials that teach you to append a line to "/etc/modprobe.d/blacklist", but in fact it is NOT RECOMMENDED to do so. It is more appropriate to write manual configurations to a separated file (i.e. local configuration file) whenever possible, so that the configuration files distributed by the system keep their original content. The following instructions create the file "/etc/modprobe.d/blacklist.local" by mimicking what is done by the Ubuntu installer (i.e. Debian installer) when "ipv6.blacklist=yes" is added to the kernel parameters during installation:

  1. Open up a terminal and type:

    echo 'blacklist ipv6' | sudo tee -a '/etc/modprobe.d/blacklist.local' >/dev/null
    The above command appends a line to the local blacklist configuration. The file will be created if it does not exist.
  2. To restart your computer, type:

    sudo reboot

Ubuntu 8.04 LTS (to disable after installation, by aliasing net-pf-10 to off)

Copied from the manpage of modprobe.conf(5):

alias wildcard modulename

This allows you to give alternate names for a module. For example: "alias my-mod really_long_modulename" means you can use "modprobe my-mod" instead of "modprobe really_long_modulename". You can also use shell-style wildcards, so "alias my-mod* really_long_modulename" means that "modprobe my-mod-something" has the same effect. You can't have aliases to other aliases (that way lies madness), but aliases can have options, which will be added to any other options. Note that modules can also contain their own aliases, which you can see using modinfo. These aliases are used as a last resort (ie. if there is no real module, install, remove, or alias command in the configuration).

This is the official way to disable IPv6. The instructions below is equivalent to that documented in Documentation for Ubuntu 8.04 LTS - 3. Wireless Networking - Troubleshooting:

  1. Open up a terminal and type (it is recommended to copy-and-paste it instead):

    sudo sed -i -e 's/alias net-pf-10 ipv6/#&\nalias net-pf-10 off/' /etc/modprobe.d/aliases

    The above command comments the original line (alias net-pf-10 ipv6) and adding the effective line (alias net-pf-10 off). You may use your favorite editor to achieve the same result, if you find that using sed does not meet your taste Smile :) .

  2. To restart your computer, type:

    sudo reboot

Ubuntu 8.04 LTS (to disable after installation, by installing ipv6 as a no-op)

Copied from the manpage of modprobe.conf(5):

install modulename command...

This is the most powerful primitive in modprobe.conf: it tells modprobe to run your command instead of inserting the module in the kernel as normal. The command can be any shell command: this allows you to do any kind of complex processing you might wish. For example, if the module "fred" worked better with the module "barney" already installed (but it didn't depend on it, so modprobe won't automatically load it), you could say "install fred /sbin/modprobe barney; /sbin/modprobe --ignore-install fred", which would do what you wanted. Note the --ignore-install, which stops the second modprobe from re-running the same install command. See also remove below.

You can also use install to make up modules which don't otherwise exist. For example: "install probe-ethernet /sbin/modprobe e100 || /sbin/modprobe eepro100", which will try first the e100 driver, then the eepro100 driver, when you do "modprobe probe-ethernet".

If you use the string "$CMDLINE_OPTS" in the command, it will be replaced by any options specified on the modprobe command line. This can be useful because users expect "modprobe fred opt=1" to pass the "opt=1" arg to the module, even if there's an install command in the configuration file. So our above example becomes "install fred /sbin/modprobe barney; /sbin/modprobe --ignore-install fred $CMD-LINE_OPTS"

  1. Open up a terminal and type:

    echo 'install ipv6 /bin/true' | sudo tee -a '/etc/modprobe.d/blacklist.local' >/dev/null
    The above command appends a line to the local blacklist configuration. The file will be created if it does not exist.
  2. To restart your computer, type:

    sudo reboot

Instructions for Ubuntu 7.10 (Gutsy Gibbon)

On a cleanly installed Gutsy server the above methods didn't work (that is,  ip a | grep inet6  kept generating output showing that IPv6 was not actually disabled).

According to Planète Béranger (Radu-Cristian Fotescu), the best method to prevent a module from loading at boot time is adding the following to some of the files in /etc/modprobe.d (you can do it within /etc/modprobe.d/blacklist):

install ipv6 /bin/true

Another variant method that works for Gutsy, is to add in /etc/modprobe.d/arch/i386:

# no ipv6
alias net-pf-10 off

(In my case having ipv6 enabled breaks Netfilter's SNAT.)

Instructions for Earlier Versions

Ubuntu:

  1. Open a terminal and type:

    gksudo gedit /etc/modprobe.d/blacklist
  2. Add this line:

    blacklist ipv6
  3. Save the file and restart your computer

Kubuntu:

  1. Open a terminal and type:

    kdesu kate /etc/modprobe.d/blacklist
  2. Add this line:

    blacklist ipv6
  3. Save the file and restart your computer

Another method (perhaps simpler) is editing /etc/modprobe.d/aliases and replacing "alias net-pf-10 ipv6" with "alias net-pf-10 off". Done!

Disabling IPv6 temporarily

If you just want to disable IPv6 temporary, you will discover that you can't just unload the ipv6 kernel module as long as an ipv6 address is configured for your device. You can use /sbin/ip to see which addresses are currently configured for your devices and disabling them with the following command:

sudo /sbin/ip addr del <ipv6address>/<prefixlength> dev ethX

Identifying the Broken Device

The real reason for the problem is because IPv6 does DNS queries for "AAAA" records which request the IPv6 address of an internet hostname. You can identify the problem from a terminal, by making a specific DNS query such as:

dig AAAA www.kame.net

The corresponding query for an IPv4 address would be:

dig A www.kame.net

If the first one of these queries times out without returning a valid IPv6 address then your internet router is not working correctly and you may want to see if there is a firmware upgrade available to fix the real problem.

WebBrowsingSlowIPv6IPv4 (last edited 2013-07-14 13:56:58 by jonkers)