Introduction
In this lab, you will learn how to configure an IPv4-to-IPv6 6to4 tunnel in a Linux environment. This hands-on exercise guides you through the process of enabling IPv6 connectivity over an existing IPv4 network, a key transition mechanism for network administrators. You will use standard Linux command-line tools to build and verify a functional tunnel from scratch.
Following a step-by-step process, you will first prepare a conceptual public IPv4 address to simulate a real-world scenario. You will then create a SIT (Simple Internet Transition) tunnel interface, assign it a 6to4-formatted IPv6 address, and add a default IPv6 route through a public 6to4 relay. To conclude the lab, you will test the end-to-end IPv6 connectivity through the newly configured tunnel using the ping6 command.
Prepare for Tunneling with a Conceptual Public IPv4 Address
In this step, you will learn about the fundamental requirement for 6to4 tunneling: a public IPv4 address. We will explore how to identify your system's IP address and why we will use a special, conceptual address for this lab exercise.
6to4 tunneling is a transition mechanism that encapsulates IPv6 packets within IPv4 packets, allowing them to travel across the IPv4 internet. For this to work in a real-world scenario, your system (the tunnel endpoint) must have a public IPv4 address so that other devices on the internet can send traffic back to it. In a typical lab or home environment, your computer is often behind a router using Network Address Translation (NAT) and has a private IPv4 address, which is not reachable from the public internet.
First, let's check the actual IPv4 address assigned to your network interface in this lab environment. You can do this using the ip a command combined with grep to filter for IPv4 addresses.
Execute the following command in your terminal:
ip a | grep inet
You will see an output similar to the following, listing the IPv4 and IPv6 addresses on your system. Note that the IPv4 addresses are private, not public.
inet 127.0.0.1/8 scope host lo
inet6 ::1/128 scope host
inet 172.16.50.33/24 metric 100 brd 172.16.50.255 scope global dynamic eth0
inet6 fe80::216:3eff:fe01:236f/64 scope link
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
As you can see, the addresses listed are private (like 172.16.50.33) or loopback (127.0.0.1). They cannot be used as a public endpoint for a 6to4 tunnel. To simulate a real-world setup, we will use a conceptual public IPv4 address. For this lab, we will use 192.0.2.1. This address is part of a block specifically reserved for documentation and examples (RFC 5737), ensuring it doesn't conflict with any real public IP addresses. All subsequent steps will use this placeholder address to build our tunnel configuration.
Create a SIT Tunnel Interface with the ip tunnel Command
In this step, you will create the virtual tunnel interface that will serve as the foundation for our 6to4 tunnel. We will use the ip command, a powerful utility in Linux for network configuration.
The command ip tunnel is used to create, manage, and delete tunnel interfaces. For 6to4, we need a specific type of tunnel called sit, which stands for "Simple Internet Transition." This mode encapsulates IPv6 packets directly within IPv4 packets, which is the core mechanism of 6to4.
Now, let's create a tunnel interface named tun6to4. We will configure it using the conceptual public IPv4 address 192.0.2.1 that we identified in the previous step.
Execute the following command in your terminal. You need sudo because creating network interfaces is a privileged operation.
sudo ip tunnel add tun6to4 mode sit local 192.0.2.1 remote any
Let's break down this command:
sudo ip tunnel add tun6to4: This part instructs the system to add a new tunnel interface namedtun6to4.mode sit: This specifies the encapsulation mode.sitis the correct mode for 6to4 tunneling.local 192.0.2.1: This sets the source IPv4 address of the tunnel packets. It's the "local" endpoint of our tunnel, which we are simulating with our conceptual public IP.remote any: This is a crucial part of the 6to4 mechanism. It tells the system that the tunnel can connect to any remote endpoint. In practice, this means it will send traffic to a well-known "anycast" address for a 6to4 relay router, which then forwards the traffic to the IPv6 internet.
After running the command, you can verify that the tunnel interface has been created. Use the ip tunnel show command:
ip tunnel show
The output should confirm the creation and configuration of your new tun6to4 interface. You may also see a default sit0 interface, which can be ignored for this lab.
sit0: ipv6/ip remote any local any ttl 64 nopmtudisc 6rd-prefix 2002::/16
tun6to4: ipv6/ip remote any local 192.0.2.1 ttl inherit 6rd-prefix 2002::/16
You can also see the new interface by running ip a again, but it won't have any IP addresses assigned to it yet. We will handle that in the next step.
Assign a 6to4-Formatted IPv6 Address to the Tunnel Interface
In this step, you will configure the tun6to4 interface you just created by assigning it a special 6to4-formatted IPv6 address. This address is not arbitrary; it is derived directly from the public IPv4 address of the tunnel endpoint.
The 6to4 addressing scheme is designed to be automatic. It uses a designated IPv6 prefix, 2002::/16. The 32 bits that follow this prefix are filled with the public IPv4 address, converted to hexadecimal format. This creates a unique /48 IPv6 prefix for any organization with at least one public IPv4 address.
Let's calculate the hexadecimal representation for our conceptual IPv4 address, 192.0.2.1:
192in decimal isc0in hexadecimal.0in decimal is00in hexadecimal.2in decimal is02in hexadecimal.1in decimal is01in hexadecimal.
Combining these, the hexadecimal representation of 192.0.2.1 is c000:0201. Therefore, our unique 6to4 prefix is 2002:c000:0201::/48.
Now, we will assign a specific IPv6 address from this prefix to our tun6to4 interface. We'll use the first address in the first subnet, 2002:c000:0201::1/64. Execute the following command to assign the address:
sudo ip -6 addr add 2002:c000:0201::1/64 dev tun6to4
After creating the interface and assigning an address, the interface is still in a "DOWN" state by default. You need to bring it "UP" to make it operational. Use the ip link set command for this:
sudo ip link set tun6to4 up
Finally, let's verify that the interface is up and has the correct IPv6 address. Use the ip a command and look for the tun6to4 interface:
ip a
You should see an output that includes the tun6to4 interface, now active and configured with the IPv6 address. Note that the interface number (e.g., 5:) may vary, and you may see other interfaces like docker0 or sit0.
5: tun6to4@NONE: <NOARP,UP,LOWER_UP> mtu 1480 qdisc noqueue state UNKNOWN group default qlen 1000
link/sit 192.0.2.1 brd 0.0.0.0
inet6 ::192.0.2.1/96 scope global
valid_lft forever preferred_lft forever
inet6 2002:c000:201::1/64 scope global
valid_lft forever preferred_lft forever
Notice that in addition to the 2002:... address you configured, the system automatically added an IPv4-compatible IPv6 address (::192.0.2.1/96). This is expected behavior.
Add a Default IPv6 Route via the 6to4 Relay Address
In this step, you will configure the final piece of the puzzle for outbound connectivity: a default route. Just having an IP address on the tun6to4 interface isn't enough; your system needs to know where to send IPv6 traffic that is destined for the global internet. We will point it to a special 6to4 relay router.
6to4 relies on public relay routers that connect the 6to4 world to the native IPv6 internet. These routers listen for encapsulated traffic on a specific, well-known anycast IPv4 address: 192.88.99.1. When our system sends an IPv6 packet to an external destination, it will encapsulate it in an IPv4 packet and send it to this relay address. The relay then unwraps the packet and forwards it onto the IPv6 network.
To set this up, we will add a default IPv6 route using the ip -6 route add command. Execute the following in your terminal:
sudo ip -6 route add default via ::192.88.99.1 dev tun6to4
Let's analyze the command:
default: This specifies that the route is the "default gateway" for all IPv6 traffic that doesn't match a more specific route in the routing table.via ::192.88.99.1: This sets the next-hop gateway. The::192.88.99.1syntax is a special way to represent an IPv4 address within an IPv6 context, telling the system to send the traffic to the IPv4 address192.88.99.1.dev tun6to4: This explicitly tells the system to use ourtun6to4interface for this route.
Now, you can verify that the IPv6 routing table has been updated correctly. Run the following command:
ip -6 route show
The output should now include a default route pointing to the 6to4 relay via your tunnel interface. The exact output may vary slightly, but the key is the default line.
::1 dev lo proto kernel metric 256 pref medium
::/96 dev tun6to4 proto kernel metric 256 pref medium
2002:c000:201::/64 dev tun6to4 proto kernel metric 256 pref medium
fe80::/64 dev eth0 proto kernel metric 256 pref medium
default via ::192.88.99.1 dev tun6to4 metric 1024 pref medium
With this route in place, your system is now fully configured to send IPv6 traffic through the simulated 6to4 tunnel.
Test IPv6 Connectivity Through the Tunnel with ping6
In this step, you will attempt to test your newly configured 6to4 tunnel by sending IPv6 traffic to a public destination. We will use the ping6 command, which is the IPv6 equivalent of the familiar ping utility.
The goal is to see if our system can send an IPv6 packet, have it encapsulated into an IPv4 packet, sent to the 6to4 relay, and then forwarded to its final destination. We will use the -I flag with ping6 to specify that the traffic must originate from our tun6to4 interface.
Let's try to ping a well-known IPv6-enabled host, such as ipv6.google.com. The -c 4 flag will limit the command to sending only 4 packets.
Execute the following command in your terminal:
ping6 -c 4 -I tun6to4 ipv6.google.com
Expected Outcome and Explanation
You will see the command fail, with an output indicating the destination is unreachable. This is the expected outcome, and this part of the lab is for demonstration purposes only.
PING ipv6.google.com(sfo03s32-in-x0e.1e100.net (2607:f8b0:4005:814::200e)) from 2002:c000:201::1 tun6to4: 56 data bytes
From iZrj9hhbt3mi4boxowaqhxZ (2002:c000:201::1) icmp_seq=1 Destination unreachable: Address unreachable
From iZrj9hhbt3mi4boxowaqhxZ (2002:c000:201::1) icmp_seq=2 Destination unreachable: Address unreachable
From iZrj9hhbt3mi4boxowaqhxZ (2002:c000:201::1) icmp_seq=3 Destination unreachable: Address unreachable
From iZrj9hhbt3mi4boxowaqhxZ (2002:c000:201::1) icmp_seq=4 Destination unreachable: Address unreachable
--- ipv6.google.com ping statistics ---
4 packets transmitted, 0 received, +4 errors, 100% packet loss, time 3253ms
This failure does not mean you configured anything incorrectly. You have successfully set up the client side of a 6to4 tunnel. The failure is expected in this lab environment for two key reasons:
- Lab Environment: The LabEx virtual machine does not have a real, public IPv4 address. We used a conceptual address (
192.0.2.1) for configuration. The 6to4 relay cannot send a reply back to this non-routable address. - Obsolete Infrastructure: The public 6to4 relay infrastructure (at the anycast address
192.88.99.1) is largely deprecated and no longer maintained on the modern internet. Network operators have moved to more robust and secure IPv6 transition mechanisms like native IPv6, 6rd, and DS-Lite.
This lab's primary purpose is to teach you the concept and configuration syntax of a historically significant IPv4-to-IPv6 tunneling mechanism, which is a topic covered in networking certifications like the CompTIA Network+.
Summary
In this lab, you learned how to configure an IPv4-to-IPv6 6to4 tunnel in Linux. You started by understanding the core requirement for 6to4 tunneling: a public IPv4 address. After identifying the private IP address in the lab environment, you adopted a conceptual public IPv4 address (192.0.2.1) to simulate a real-world scenario. You then used the ip tunnel command to create a SIT (Simple Internet Transition) tunnel interface, which serves as the endpoint for encapsulating IPv6 packets within IPv4.
With the tunnel interface established, you constructed and assigned a 6to4-formatted IPv6 address, which is programmatically derived from the conceptual public IPv4 address. To direct IPv6 traffic through the tunnel, you added a default IPv6 route pointing to the anycast 6to4 relay address. Finally, you tested the configuration using the ping6 command. The test failed as expected, which confirmed that while your local setup was correct, the public 6to4 relay infrastructure is no longer widely available, demonstrating a key reason why this technology is now considered historic.



