VPS Tutorials
IPv6 VPS Configuration Guide: Enable Dual Stack, DNS, Nginx and Common Pitfalls (2026)
Many VPS come with IPv6, but it isn't configured properly by default: either there's no AAAA record, the firewall blocks v6, or Nginx only listens on IPv4. This article gives you a copyable dual-stack configuration workflow: from confirming whether you have a /64, checking routes, configuring netplan/ifupdown/NetworkManager, to DNS AAAA, Nginx/SSH listening, UFW/ip6tables rules, and then stepping through the most common pitfalls in one go.

Many people see a line saying "IPv6 /64 Included" when buying a VPS and think: great, a bunch of free addresses.
But when it comes to actually using them:
ping6doesn't work- Your domain only has an A record, and AAAA stays empty
- Nginx only listens on IPv4, so IPv6 access times out directly
This article does one thing: turn IPv6 from "decoration" into "usable", while trying not to blow up your existing IPv4 configuration.
Take a look on the VPS first:
ip -6 addr
ip -6 route
What you usually want to see:
- A public IPv6 on the network interface (usually starting with
2a01:,2400:) - A default route
default via ... dev eth0
If you only see a link-local address like fe80::, that basically means "not configured".
Simplest connectivity self-test:
ping -6 -c 3 2606:4700:4700::1111
curl -6 -s https://api64.ipify.org && echo
ping -6works: at least routing isn't deadcurl -6returns an IPv6: your outbound IPv6 is working
If this step already fails, don't rush to change Nginx; 99% of the time it's: the provider didn't enable it for you, you didn't add the gateway, or the firewall killed v6 outbound/inbound.
The main difference between distributions is "where the network configuration file lives". I'll put the three most common types together; just pick the one that matches yours.
First confirm the interface name:
ip link
Then look at the existing netplan configuration:
ls -l /etc/netplan/
cat /etc/netplan/*.yaml
Example (you need to change addresses/gateway6/nameservers to what the provider gave you):
network:
version: 2
ethernets:
eth0:
dhcp4: true
dhcp6: false
addresses:
- 2001:db8:1234:5678::2/64
gateway6: 2001:db8:1234:5678::1
nameservers:
addresses:
- 1.1.1.1
- 2606:4700:4700::1111
Apply the configuration:
sudo netplan apply
Take a look at /etc/network/interfaces:
cat /etc/network/interfaces
Example:
auto eth0
iface eth0 inet dhcp
iface eth0 inet6 static
address 2001:db8:1234:5678::2
netmask 64
gateway 2001:db8:1234:5678::1
Restart networking (commands may differ slightly between systems):
sudo systemctl restart networking
nmcli con show
nmcli con mod "System eth0" ipv6.method manual \
ipv6.addresses "2001:db8:1234:5678::2/64" \
ipv6.gateway "2001:db8:1234:5678::1" \
ipv6.dns "2606:4700:4700::1111 2001:4860:4860::8888"
nmcli con up "System eth0"
Note: the
2001:db8::above is a documentation example prefix; you must replace it with your real IPv6.
Many people "think IPv6 doesn't work", when in fact DNS just isn't configured.
- IPv4: A record
- IPv6: AAAA record
You can check with these two commands:
# 本机或 VPS 都行
nslookup -type=A yourdomain.com
nslookup -type=AAAA yourdomain.com
If AAAA is empty, then when you use curl https://yourdomain.com, of course the browser can only go over IPv4.
Pitfall: after you enable the Cloudflare proxy, even if the origin has no IPv6, Cloudflare may give you "frontend IPv6".
- This doesn't mean your VPS IPv6 is configured
- It just means Cloudflare edge nodes are "putting up a front" for you
To verify whether the origin really supports IPv6, test by "connecting directly to the origin" (for example, access the VPS's IPv6 directly or temporarily turn off the DNS proxy).
The most common case: Nginx only has listen 80;, without listen [::]:80;.
Add it in your site configuration (example):
server {
listen 80;
listen [::]:80;
server_name example.com;
location / {
return 200 "ok\n";
}
}
Then:
sudo nginx -t
sudo systemctl reload nginx
You can test directly with IPv6:
# 用你的域名
curl -6 -I http://example.com
# 或者直接用 IPv6(注意要用中括号)
curl -I "http://[2001:db8:1234:5678::2]/"
First confirm whether UFW has IPv6 enabled:
sudo grep -n '^IPV6=' /etc/default/ufw
What you want to see:
IPV6=yes
Allow ports (example: SSH/HTTP/HTTPS):
sudo ufw allow 22/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw reload
sudo ufw status verbose
Many people only configure iptables, and as a result IPv6 is either fully exposed or fully blocked.
sudo ip6tables -S
sudo ip6tables -L -n -v
The basic rules you need (example, just demonstrating the idea):
sudo ip6tables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
sudo ip6tables -A INPUT -p tcp --dport 22 -j ACCEPT
sudo ip6tables -A INPUT -p tcp --dport 80 -j ACCEPT
sudo ip6tables -A INPUT -p tcp --dport 443 -j ACCEPT
sudo ip6tables -A INPUT -j DROP
Typical cause: firewall/security group not opened (especially if you only opened IPv4 rules).
You can temporarily start a listening test on the VPS:
sudo python3 -m http.server 8000 --bind ::
Then from your local machine:
curl -6 "http://[你的VPS_IPV6]:8000/"
This kind of problem is usually "routing quality": some networks' IPv6 egress takes detours, or carriers don't care much about IPv6 quality.
The approach is simple:
- First compare with
curl -6andcurl -4 - If v6 is clearly unstable, consider not adding AAAA for now (or letting Cloudflare manage it)
If you need more detailed network diagnosis, read this article:
Check first:
- Whether Nginx has
listen [::]:80/listen [::]:443 ssl - Whether the backend service (e.g. Node/Go) listens on
0.0.0.0but not::
If your problem is essentially "the site won't open", you can follow this troubleshooting route first: