Configure and Verify IPv6 Addresses in Linux

CompTIABeginner
Practice Now

Introduction

In this lab, you will learn the fundamental skills for configuring and verifying IPv6 addresses on a Linux system. Using modern command-line tools, you will gain hands-on experience with the essential tasks involved in IPv6 network management, from inspection to static configuration and connectivity testing. This lab focuses on using the ip command from the iproute2 suite and the ping6 utility, which are standard in modern Linux distributions like Ubuntu 22.04.

You will begin by using the ip a command to discover the automatically configured IPv6 loopback and link-local addresses on your network interfaces. Next, you will manually assign a static global unicast address to an interface. Finally, you will use the ping6 command to verify network connectivity to the loopback, link-local, and newly configured global unicast addresses, confirming that your IPv6 setup is functioning correctly.

In this step, you will learn how to discover the IPv6 addresses that are automatically configured on your system. Modern Linux distributions, including Ubuntu 22.04, have IPv6 enabled by default. We will use the ip command, which is the modern and recommended tool for network configuration and inspection in Linux.

First, let's inspect the network interfaces and their assigned addresses. The command ip a is a shorthand for ip address.

  1. Open a terminal. Your default path is ~/project.
  2. Execute the ip a command to list all network interfaces and their addresses.
ip a

You will see output similar to the following. The exact interface names (like eth0) and addresses may vary, but the structure will be the same.

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 00:16:3e:00:54:72 brd ff:ff:ff:ff:ff:ff
    altname enp0s5
    altname ens5
    inet 172.16.50.202/24 metric 100 brd 172.16.50.255 scope global dynamic eth0
       valid_lft 1892159972sec preferred_lft 1892159972sec
    inet6 fe80::216:3eff:fe00:5472/64 scope link
       valid_lft forever preferred_lft forever
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
    link/ether 02:42:89:01:6f:fc brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
       valid_lft forever preferred_lft forever

Now, let's analyze the output to identify the key IPv6 addresses:

  • Loopback Address: Look at the interface named lo. This is the virtual loopback interface, used for testing the network stack on the local machine. You will see the IPv6 address ::1/128. This is the IPv6 loopback address, equivalent to 127.0.0.1 in IPv4. The scope host indicates it's only valid within the host itself.

  • Link-Local Address: Look at your primary network interface (e.g., eth0, enp0s3). You will find an inet6 address that starts with fe80::. This is your link-local address. It is automatically assigned to every IPv6-enabled interface and is used for communication only on the local network segment (e.g., your local Ethernet LAN). The scope link confirms that this address is only valid on the local link and is not routable on the internet.

You have now successfully identified the two fundamental types of automatically configured IPv6 addresses on your system.

Add a Static Global Unicast Address with ip addr add

In this step, you will manually configure a Global Unicast Address (GUA) on your network interface. While link-local addresses are used for communication on the local network segment, GUAs are the IPv6 equivalent of public IPv4 addresses. They are globally unique and routable on the internet.

For this lab, we will use an address from the 2001:db8::/32 block, which is specifically reserved for documentation and examples. This ensures we don't accidentally use a real, in-use internet address.

  1. We will add the static GUA 2001:db8:acad::1/64 to the eth0 interface. The /64 indicates the prefix length, which is standard for most LANs. We need sudo because modifying network interfaces requires administrative privileges.

    sudo ip -6 addr add 2001:db8:acad::1/64 dev eth0
    
    • Note: This change is temporary and will be removed if you reboot the system. For permanent configuration on Ubuntu, you would typically edit files in /etc/netplan/, but that is outside the scope of this lab.
  2. Now, verify that the new GUA has been successfully assigned. Run the ip a command again to inspect your network interfaces.

    ip a
    

    You should now see the new address listed under the eth0 interface. Notice the scope global, which indicates this is a routable address.

    1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
        ...
    2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
        link/ether 00:16:3e:00:54:72 brd ff:ff:ff:ff:ff:ff
        altname enp0s5
        altname ens5
        inet 172.16.50.202/24 metric 100 brd 172.16.50.255 scope global dynamic eth0
           valid_lft 1892159959sec preferred_lft 1892159959sec
        inet6 2001:db8:acad::1/64 scope global
           valid_lft forever preferred_lft forever
        inet6 fe80::216:3eff:fe00:5472/64 scope link
           valid_lft forever preferred_lft forever
    

You have successfully assigned a static IPv6 GUA to your network interface. In the next step, we will test connectivity to this new address.

Test Connectivity to Loopback and GUA with ping6

In this step, you will use the ping6 utility to test IPv6 connectivity. This command is the IPv6 equivalent of the familiar ping command and is essential for network diagnostics. We will verify that your local IPv6 stack is working correctly and that the Global Unicast Address (GUA) you configured in the previous step is responsive.

First, let's test the local IPv6 stack by pinging the loopback address.

  1. Ping the IPv6 loopback address ::1. We will use the -c 3 option to send only 3 packets instead of pinging indefinitely.

    ping6 -c 3 ::1
    

    A successful test will show that packets are being sent and received with 0% packet loss, confirming your local IPv6 stack is operational.

    PING ::1(::1) 56 data bytes
    64 bytes from ::1: icmp_seq=1 ttl=64 time=0.026 ms
    64 bytes from ::1: icmp_seq=2 ttl=64 time=0.021 ms
    64 bytes from ::1: icmp_seq=3 ttl=64 time=0.035 ms
    
    --- ::1 ping statistics ---
    3 packets transmitted, 3 received, 0% packet loss, time 2030ms
    rtt min/avg/max/mdev = 0.021/0.027/0.035/0.005 ms
    

Next, let's test the GUA you manually assigned to the eth0 interface. This confirms that the interface is correctly configured and listening on that address.

  1. Ping the GUA 2001:db8:acad::1 that you added in the previous step.

    ping6 -c 3 2001:db8:acad::1
    

    Similar to the loopback test, a successful result will show replies from the address, confirming it is correctly assigned and reachable on the host.

    PING 2001:db8:acad::1(2001:db8:acad::1) 56 data bytes
    64 bytes from 2001:db8:acad::1: icmp_seq=1 ttl=64 time=0.028 ms
    64 bytes from 2001:db8:acad::1: icmp_seq=2 ttl=64 time=0.037 ms
    64 bytes from 2001:db8:acad::1: icmp_seq=3 ttl=64 time=0.038 ms
    
    --- 2001:db8:acad::1 ping statistics ---
    3 packets transmitted, 3 received, 0% packet loss, time 2034ms
    rtt min/avg/max/mdev = 0.028/0.034/0.038/0.004 ms
    

You have now successfully verified connectivity to both the loopback and your manually configured Global Unicast Address.

In this step, you will learn how to test connectivity to a link-local address. As you discovered earlier, these addresses start with fe80:: and are only valid on a single network segment (the "link"). Because they are not globally unique, you must provide extra information to the ping6 command to specify which network interface should be used to send the ping. This is known as the "zone index" or "scope ID".

First, you need to find the link-local address of your eth0 interface again.

  1. Run the ip a command and identify the inet6 address starting with fe80:: for the eth0 interface.

    ip a show eth0
    

    The output will look similar to this. You need to copy the address (e.g., fe80::xxxx:xxff:fexx:xxxx).

    2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
        link/ether 00:16:3e:00:54:72 brd ff:ff:ff:ff:ff:ff
        altname enp0s5
        altname ens5
        inet 172.16.50.202/24 metric 100 brd 172.16.50.255 scope global dynamic eth0
           valid_lft 1892159869sec preferred_lft 1892159869sec
        inet6 2001:db8:acad::1/64 scope global
           valid_lft forever preferred_lft forever
        inet6 fe80::216:3eff:fe00:5472/64 scope link
           valid_lft forever preferred_lft forever
    
  2. Now, ping this link-local address. To specify the zone index, you append % followed by the interface name (eth0) to the address. Replace YOUR_LINK_LOCAL_ADDRESS with the actual address you just found.

    ping6 -c 3 YOUR_LINK_LOCAL_ADDRESS%eth0
    

    For example, if your address was fe80::216:3eff:fe00:5472, the command would be: ping6 -c 3 fe80::216:3eff:fe00:5472%eth0

    A successful ping confirms that the interface is responding to its link-local address.

    PING fe80::216:3eff:fe00:5472%eth0(fe80::216:3eff:fe00:5472%eth0) 56 data bytes
    64 bytes from fe80::216:3eff:fe00:5472%eth0: icmp_seq=1 ttl=64 time=0.031 ms
    64 bytes from fe80::216:3eff:fe00:5472%eth0: icmp_seq=2 ttl=64 time=0.030 ms
    64 bytes from fe80::216:3eff:fe00:5472%eth0: icmp_seq=3 ttl=64 time=0.030 ms
    
    --- fe80::216:3eff:fe00:5472%eth0 ping statistics ---
    3 packets transmitted, 3 received, 0% packet loss, time 2028ms
    rtt min/avg/max/mdev = 0.030/0.030/0.031/0.000 ms
    

    If you forget the %eth0 part, the command will fail because the system won't know which interface to use for the link-local destination. This special syntax is a key concept in handling link-local IPv6 addresses.

Summary

In this lab, you learned to perform fundamental IPv6 configuration and verification tasks on a Linux system using the ip command suite. You began by using ip a to inspect the network interfaces, successfully identifying the automatically assigned IPv6 loopback address (::1) on the lo interface and the link-local address (prefixed with fe80::) on the primary network interface. You then proceeded to manually configure a static Global Unicast Address (GUA) on the primary interface using the ip addr add command.

To validate the configuration, you utilized the ping6 utility. You confirmed the local network stack was operational by pinging the loopback address and verified the static GUA was correctly assigned and reachable. Finally, you learned the specific requirement for testing link-local addresses, which involves using the %interface syntax with ping6 to explicitly specify the zone index (outgoing interface), a necessary step due to the link scope of these addresses.