Complete IPv6 Configuration for VPS: Enable, Secure, and Deploy Dual-Stack Networking

Complete IPv6 Configuration for VPS: Enable, Secure, and Deploy Dual-Stack Networking

IPv6 adoption has crossed 45% globally and most VPS providers assign IPv6 addresses alongside IPv4. Properly enabling IPv6 on your VPS serves users on IPv6-only networks (increasingly common with mobile carriers), future-proofs your infrastructure, and can improve performance for users where IPv6 paths are less congested. This guide enables IPv6 in Nginx, UFW, and applications with full security hardening.

Check IPv6 Assignment

<code"># Check if your VPS has an IPv6 address
ip addr show | grep inet6
# Look for: inet6 2001:db8::/128 (your actual IPv6 address)

# Check IPv6 routing
ip -6 route show
# Should show: default via 2001:db8::1 (gateway)

# Test IPv6 connectivity
ping6 ipv6.google.com
curl -6 https://ipv6.icanhazip.com

Step 1: Enable IPv6 in UFW

<code">sudo nano /etc/default/ufw
<code"># Change:
IPV6=yes
<code"># IPv6 UFW rules follow the same syntax:
# Allow SSH over IPv6 (usually auto-applied when allowing by service name)
sudo ufw allow ssh
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp

# Verify both IPv4 and IPv6 rules exist:
sudo ufw status verbose | grep -E "v6|IPv6"

# Check iptables-based IPv6 rules (ip6tables):
sudo ip6tables -L INPUT -n | head -20

# Reload UFW to apply IPv6=yes change:
sudo ufw disable && sudo ufw enable

Step 2: Configure Nginx for Dual-Stack

<code">sudo nano /etc/nginx/sites-available/yoursite
<code">server {
    # IPv4 (existing)
    listen 80;
    listen 443 ssl http2;

    # IPv6 — add these lines
    listen [::]:80;           # IPv6 HTTP
    listen [::]:443 ssl http2; # IPv6 HTTPS

    server_name yourdomain.com www.yourdomain.com;

    ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;

    # ... rest of config unchanged
}
<code"># In nginx.conf, ensure IPv6 is enabled:
sudo nano /etc/nginx/nginx.conf
<code">http {
    # Default server that catches undefined hosts (important for both v4 and v6)
    server {
        listen 80 default_server;
        listen [::]:80 default_server;
        listen 443 ssl default_server;
        listen [::]:443 ssl default_server;
        server_name _;
        return 444;   # Close connection silently
    }
}
<code">sudo nginx -t && sudo systemctl reload nginx

Step 3: Set AAAA DNS Records

<code"># Find your VPS IPv6 address:
ip addr show | grep "inet6" | grep -v "fe80\|::1"
# Example: inet6 2001:db8:1234:5678::1/128

# Add DNS records (in your DNS provider):
# Type: AAAA
# Name: yourdomain.com
# Value: 2001:db8:1234:5678::1

# Type: AAAA
# Name: www.yourdomain.com
# Value: 2001:db8:1234:5678::1

# Verify DNS propagation:
dig AAAA yourdomain.com +short
# Should return your IPv6 address

Step 4: Update Certbot for IPv6

<code"># Certbot works over IPv4 or IPv6 — verify certificate covers your domain:
sudo certbot certificates

# If needed, renew to test IPv6 validation:
sudo certbot renew --dry-run

# For new certificates with IPv6:
sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com
# Certbot will use whatever protocol (v4/v6) is available

Step 5: Configure Applications for IPv6

Node.js/Express

<code">// Listen on both IPv4 and IPv6
app.listen(3000, '::', () => {
    console.log('Listening on IPv4 and IPv6 on port 3000');
});

// Or bind to specific interface:
app.listen(3000, '0.0.0.0');  // IPv4 only
app.listen(3000, '::');        // Both (dual-stack)

Python/FastAPI

<code">import uvicorn

# Dual-stack (listen on :: binds to both IPv4 and IPv6 on most Linux systems)
uvicorn.run(app, host="::", port=8000)

# Or in command:
# uvicorn main:app --host "::" --port 8000

PostgreSQL

<code"># /etc/postgresql/16/main/postgresql.conf:
listen_addresses = 'localhost,::1'   # Include IPv6 loopback

# /etc/postgresql/16/main/pg_hba.conf:
host    mydb    myuser    ::1/128    scram-sha-256   # IPv6 loopback

Step 6: IPv6-Specific Security Hardening

<code">sudo nano /etc/sysctl.d/99-ipv6-security.conf
<code"># Disable IPv6 router advertisements (prevent SLAAC hijacking)
net.ipv6.conf.all.accept_ra = 0
net.ipv6.conf.default.accept_ra = 0

# Disable IPv6 redirects
net.ipv6.conf.all.accept_redirects = 0
net.ipv6.conf.default.accept_redirects = 0

# Disable IPv6 source routing
net.ipv6.conf.all.accept_source_route = 0

# Enable IPv6 privacy extensions (randomize temporary addresses)
net.ipv6.conf.all.use_tempaddr = 2
net.ipv6.conf.default.use_tempaddr = 2

# Log IPv6 martian packets
net.ipv6.conf.all.log_martians = 1
<code">sudo sysctl -p /etc/sysctl.d/99-ipv6-security.conf

Step 7: Test IPv6 Connectivity

<code"># Test from the VPS:
ping6 -c 4 ipv6.google.com
curl -6 https://yourdomain.com

# Test from external:
# Online: https://ipv6-test.com or https://test-ipv6.com
# Enter your domain — checks AAAA record and IPv6 connectivity

# Test Nginx is listening on IPv6:
ss -tlnp | grep nginx
# Should show: :::80 and :::443

# Check Nginx logs for IPv6 access (should see IPv6 source IPs):
tail -f /var/log/nginx/access.log
# 2001:db8:1:2::100 - - [01/Jun] "GET / HTTP/2.0" 200 ...

# Verify UFW allows IPv6 traffic:
sudo ufw status verbose | grep -E "443.*v6|80.*v6"

# Full IPv6 connectivity test:
curl -v --ipv6 https://yourdomain.com 2>&1 | grep -E "Connected|SSL|HTTP"

Fail2ban for IPv6

<code"># Fail2ban supports IPv6 — ensure it's configured:
sudo nano /etc/fail2ban/jail.local
<code">[DEFAULT]
# Use ip6tables for IPv6 banning
banaction = iptables-multiport
banaction_allports = iptables-allports

# Or use ufw (handles both IPv4 and IPv6):
banaction = ufw

Getting Started

IPv6 is assigned by default on VPS.DO Ubuntu plans — check your VPS control panel for your assigned IPv6 address. The Nginx configuration change (adding listen [::]:443) is the most impactful step — it enables IPv6 HTTPS in under 2 minutes. Set the AAAA DNS record, and IPv6 users will automatically connect over IPv6 when their network supports it (Happy Eyeballs protocol in browsers selects the fastest path).

Conclusion

Enabling IPv6 on a VPS is a 15-minute configuration task that future-proofs your infrastructure, serves users on IPv6-only mobile networks, and ensures compliance with IPv6 requirements in some jurisdictions. The key steps are: enable UFW IPv6 support, add listen [::]:80 and listen [::]:443 to Nginx server blocks, add AAAA DNS records, and apply IPv6-specific sysctl security hardening. Fail2ban with the UFW banaction handles both IPv4 and IPv6 banning automatically.

Fast • Reliable • Affordable VPS - DO It Now!

Get top VPS hosting with VPS.DO’s fast, low-cost plans. Try risk-free with our 7-day no-questions-asked refund and start today!