IPv4 vs IPv6: differences and dual-stack configuration on Linux

What is the difference between IPv4 and IPv6?

IPv4 and IPv6 are two versions of the Internet Protocol used to identify devices on a network.

Feature IPv4 IPv6
Address length 32 bits 128 bits
Address format Dotted decimal: 203.0.113.10 Hexadecimal colon: 2001:0db8:85a3::8a2e:0370:7334
Total addresses ~4.3 billion ~340 undecillion (3.4 × 10³⁸)
Configuration Manual or DHCP SLAAC (auto), DHCPv6, or manual
NAT Widely used (required due to address scarcity) Not needed (every device gets a public address)
Header size Variable (20–60 bytes) Fixed (40 bytes, simpler)
IPSec Optional Built-in (mandatory in specification)
Broadcast Yes No (uses multicast instead)

IPv6 address types

Type Prefix Description
Global Unicast 2000::/3 Public, routable addresses (equivalent to public IPv4)
Link-Local fe80::/10 Auto-assigned, only valid within the local network segment
Unique Local (ULA) fd00::/8 Private addresses (equivalent to 10.x.x.x, 192.168.x.x in IPv4)
Loopback ::1 Equivalent to 127.0.0.1

Check your current IP configuration

View both IPv4 and IPv6 addresses

ip addr show

View only IPv4

ip -4 addr show

View only IPv6

ip -6 addr show

Check default routes

ip -4 route show    # IPv4 routes
ip -6 route show    # IPv6 routes

Dual-stack configuration

Dual-stack means running IPv4 and IPv6 simultaneously on the same interface. This is the recommended approach for transitioning to IPv6 while maintaining IPv4 compatibility.

Netplan (Ubuntu 18.04+)

network:
  version: 2
  ethernets:
    ens18:
      addresses:
        - 203.0.113.10/24
        - 2001:db8::10/64
      routes:
        - to: default
          via: 203.0.113.1
        - to: default
          via: 2001:db8::1
      nameservers:
        addresses:
          - 8.8.8.8
          - 2001:4860:4860::8888

Apply with:

sudo netplan apply

/etc/network/interfaces (Debian)

auto eth0
iface eth0 inet static
    address 203.0.113.10
    netmask 255.255.255.0
    gateway 203.0.113.1

iface eth0 inet6 static
    address 2001:db8::10
    netmask 64
    gateway 2001:db8::1

Apply with:

sudo systemctl restart networking

NetworkManager (AlmaLinux / RHEL)

sudo nmcli connection modify "System eth0" \
  ipv4.addresses 203.0.113.10/24 \
  ipv4.gateway 203.0.113.1 \
  ipv4.method manual \
  ipv6.addresses 2001:db8::10/64 \
  ipv6.gateway 2001:db8::1 \
  ipv6.method manual
sudo nmcli connection up "System eth0"

Testing IPv6 connectivity

ping -6 ipv6.google.com
ping6 ipv6.google.com     # older syntax
traceroute -6 ipv6.google.com
curl -6 https://ipv6.google.com

Disabling IPv6 (if needed)

In some cases, you may need to disable IPv6 temporarily:

sudo sysctl -w net.ipv6.conf.all.disable_ipv6=1
sudo sysctl -w net.ipv6.conf.default.disable_ipv6=1

To make it persistent, add to /etc/sysctl.conf:

net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1

Then apply: sudo sysctl -p

Firewall considerations

If you use UFW, it handles IPv4 and IPv6 automatically (if IPv6 is enabled in /etc/default/ufw). Your rules apply to both protocols:

sudo ufw allow ssh    # Allows SSH on both IPv4 and IPv6

If you use iptables directly, note that IPv6 rules require ip6tables:

sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT     # IPv4
sudo ip6tables -A INPUT -p tcp --dport 22 -j ACCEPT    # IPv6