Configure IPv6 on Linux VPS — Complete Setup Guide

Updated: September 25, 2026 · Category: Networking

Configure IPv6 on Linux VPS

The global IPv4 address pool is exhausted. Most VPS providers now allocate an IPv6 subnet alongside your server, but Linux doesn't always enable or configure it automatically. This guide walks you through the complete process of setting up IPv6 on a Linux VPS — covering both SLAAC and static assignment, firewall rules, DNS AAAA records, and connectivity testing.

Why Enable IPv6?

IPv4 provides only 4.3 billion addresses — already exhausted. IPv6 provides 3.4 × 10³⁸ addresses. Additional benefits include:

Check Your Provider's IPv6 Allocation

Before configuring, verify your VPS has been assigned an IPv6 address — check your provider's control panel or run:

# Show all network interfaces
ip addr show

# Show only IPv6
ip -6 addr show

# Show IPv6 routing table
ip -6 route show

If you see an address starting with 2xxx: or 3xxx:, your interface already has a global IPv6 address. If you only see fe80:: (link-local), no global IPv6 has been assigned.

Method 1 — SLAAC (Stateless Address Autoconfiguration)

SLAAC is the simplest approach — ideal when your provider sends Router Advertisements. The OS generates an IPv6 address automatically from the advertised prefix.

Ubuntu / Debian — Netplan

# Find your interface name
ip link show

# Edit Netplan config
nano /etc/netplan/00-installer-config.yaml
network:
  version: 2
  ethernets:
    eth0:
      dhcp4: true
      dhcp6: true          # enable SLAAC / DHCPv6
      accept-ra: true      # accept Router Advertisements
# Apply configuration
netplan apply

# Verify
ip -6 addr show eth0

CentOS / Rocky / AlmaLinux — NetworkManager

nmcli con show
nmcli con mod eth0 ipv6.method auto
nmcli con up eth0

# Verify
nmcli -p con show eth0 | grep IPv6

Method 2 — Static IPv6 Address

Use static assignment for servers that need a stable IP — mail servers, DNS servers, or any host you add AAAA records for.

Ubuntu / Debian — Netplan (static)

nano /etc/netplan/00-installer-config.yaml
network:
  version: 2
  ethernets:
    eth0:
      dhcp4: true
      addresses:
        - 2a01:4f8:c2c:1234::1/64   # replace with your provider's IPv6
      routes:
        - to: ::/0
          via: 2a01:4f8:c2c:1234::1  # your IPv6 gateway
      nameservers:
        addresses:
          - 2606:4700:4700::1111     # Cloudflare IPv6 DNS
          - 2001:4860:4860::8888     # Google IPv6 DNS
netplan apply

CentOS / Rocky — nmcli (static)

nmcli con mod eth0 \
  ipv6.method manual \
  ipv6.addresses "2a01:4f8:c2c:1234::1/64" \
  ipv6.gateway "fe80::1" \
  ipv6.dns "2606:4700:4700::1111,2001:4860:4860::8888"

nmcli con up eth0

Kernel Configuration — Enable IPv6 if Disabled

Some providers disable IPv6 at the kernel level. Check and enable it:

# Check if IPv6 is disabled
sysctl net.ipv6.conf.all.disable_ipv6
# 1 = disabled

# Enable IPv6 for all interfaces
sysctl -w net.ipv6.conf.all.disable_ipv6=0
sysctl -w net.ipv6.conf.default.disable_ipv6=0

# Make persistent across reboots
echo "net.ipv6.conf.all.disable_ipv6 = 0" >> /etc/sysctl.d/99-ipv6.conf
echo "net.ipv6.conf.default.disable_ipv6 = 0" >> /etc/sysctl.d/99-ipv6.conf
sysctl --system
Tip: Set net.ipv6.conf.all.forwarding = 1 only if your VPS acts as an IPv6 router or gateway for containers.

Firewall Rules for IPv6

iptables only handles IPv4. IPv6 traffic is controlled by ip6tables — they must be configured separately.

UFW (recommended for Ubuntu/Debian)

# Ensure UFW has IPv6 enabled
grep "IPV6" /etc/default/ufw
# Should show: IPV6=yes

# Allow common ports (applies to both IPv4 and IPv6)
ufw allow 22/tcp
ufw allow 80/tcp
ufw allow 443/tcp
ufw enable

# View IPv6 rules
ufw status verbose

ip6tables (manual)

# Flush existing rules
ip6tables -F
ip6tables -X

# Allow loopback and established connections
ip6tables -A INPUT -i lo -j ACCEPT
ip6tables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

# Allow ICMPv6 (required for neighbor discovery)
ip6tables -A INPUT -p ipv6-icmp -j ACCEPT

# Allow SSH, HTTP, HTTPS
ip6tables -A INPUT -p tcp --dport 22 -j ACCEPT
ip6tables -A INPUT -p tcp --dport 80 -j ACCEPT
ip6tables -A INPUT -p tcp --dport 443 -j ACCEPT

# Drop everything else
ip6tables -A INPUT -j DROP

# Save rules
apt install iptables-persistent -y
netfilter-persistent save
Tip: Never block all ICMPv6! ICMPv6 is essential for the Neighbor Discovery Protocol (NDP) — the IPv6 equivalent of ARP. Blocking it entirely will break connectivity.

Configure DNS AAAA Records

Once your VPS has IPv6, add AAAA records in your domain's DNS:

Record TypeNameValue
AAAA@2a01:4f8:c2c:1234::1
AAAAwww2a01:4f8:c2c:1234::1
AAAAmail2a01:4f8:c2c:1234::1

For reverse DNS (PTR records), configure rDNS through your provider's control panel — point your IPv6 address to your server's hostname.

Configure Nginx to Listen on IPv6

server {
    # Accept both IPv4 and IPv6
    listen 80;
    listen [::]:80;

    listen 443 ssl;
    listen [::]:443 ssl;

    server_name example.com www.example.com;
    # ...
}

With the default Linux setting net.ipv6.bindv6only = 0, a dual-stack [::]:80 socket also accepts IPv4 connections — no need for a separate listen 80 directive.

Verify IPv6 is Working Correctly

# Ping Google's IPv6 DNS
ping6 2001:4860:4860::8888 -c 4

# Test HTTP request over IPv6
curl -6 -I https://ipv6.google.com

# Show active global IPv6 addresses
ip -6 addr show scope global

# Check routing table
ip -6 route show
tracepath6 2001:4860:4860::8888

# Test DNS resolution over IPv6
dig AAAA google.com @2606:4700:4700::1111
Tip: Use test-ipv6.com to test dual-stack connectivity from the outside — a 10/10 score confirms full IPv6 support.

Troubleshooting Common Issues

Error: "Network is unreachable" when running ping6

This means the interface has no global IPv6 address or the default IPv6 route is missing.

# Check for a default route
ip -6 route show | grep default

# Add a temporary default route (replace with your actual gateway)
ip -6 route add default via 2a01:4f8:c2c:1234::1 dev eth0

# If your provider uses a link-local gateway
ip -6 route add default via fe80::1 dev eth0

Error: "connect: Cannot assign requested address" with curl -6

IPv6 is disabled at the kernel level. Check and enable it:

cat /proc/sys/net/ipv6/conf/all/disable_ipv6
# If 1, run:
sysctl -w net.ipv6.conf.all.disable_ipv6=0

Error: "Address already in use" when Nginx won't start after adding [::]:443

Occurs when net.ipv6.bindv6only=1 and the port is already held by an IPv4 socket.

# Check current value
sysctl net.ipv6.bindv6only

# Set to 0 to allow dual-stack sockets
sysctl -w net.ipv6.bindv6only=0
echo "net.ipv6.bindv6only = 0" >> /etc/sysctl.d/99-ipv6.conf

Error: ICMPv6 "Destination Unreachable" — neighbor solicitation not answered

Firewall is blocking all ICMPv6. Open the Neighbor Discovery message types:

ip6tables -A INPUT -p ipv6-icmp --icmpv6-type 133 -j ACCEPT
ip6tables -A INPUT -p ipv6-icmp --icmpv6-type 134 -j ACCEPT
ip6tables -A INPUT -p ipv6-icmp --icmpv6-type 135 -j ACCEPT
ip6tables -A INPUT -p ipv6-icmp --icmpv6-type 136 -j ACCEPT
ip6tables -A INPUT -p ipv6-icmp --icmpv6-type 137 -j ACCEPT

IPv6 address disappears after reboot

The address was set temporarily, not persisted in a config file.

# Ubuntu/Debian — verify Netplan config
cat /etc/netplan/00-installer-config.yaml

# CentOS/Rocky — verify NetworkManager connection
cat /etc/NetworkManager/system-connections/eth0.nmconnection | grep ipv6

Frequently Asked Questions

Does my VPS have IPv6?

Check your provider's control panel — most providers show the allocated IPv6 subnet there. Alternatively, run ip -6 addr show and look for an address starting with 2 or 3 (global unicast). If you only see fe80:: (link-local), IPv6 hasn't been provisioned on your server yet.

Do I need IPv6 if my website only uses IPv4?

It's recommended even for IPv4-only sites. Googlebot supports IPv6 and may crawl your site over it. Some ISPs provide IPv6-only connectivity to end users. Cloudflare also favors dual-stack origins when routing traffic. Enabling IPv6 has no downside and improves reach and future-proofing.

What's the difference between SLAAC and DHCPv6?

SLAAC (Stateless Address Autoconfiguration) lets the host generate its own address from a router-advertised prefix — no DHCP server needed. DHCPv6 works like IPv4 DHCP — a server explicitly assigns an address. Most VPS providers use SLAAC or static assignment; check your provider's documentation to see which applies to your plan.