VPS IPv6 Outbound for a Self-Hosted Proxy: Setup and Checks

VPS IPv6 Outbound for a Self-Hosted Proxy: Setup and Checks

James Carter
October 14, 2026· 11 min read

VPS IPv6 outbound works for a self-hosted proxy when the server has a working global IPv6 address and default route, and the proxy is told which address family to prefer when it resolves a destination. Confirm the allocation first, then configure the system, the firewall and sing-box in that order, and keep IPv4 as a tested fallback. This procedure is based on the official sources listed below; a complete end-to-end test has not been performed.

Key Takeaways

  • The provider's allocation decides what you can configure, so read it before editing anything.
  • ICMPv6 carries Neighbor Discovery; blocking all of it can break the IPv6 path.
  • In sing-box 1.12 and later, the IPv6 preference lives in domain_resolver, not the deprecated domain_strategy.
  • This guide uses one stable IPv6 address; it does not cover rotating addresses to avoid bans or rate limits.

What does VPS IPv6 outbound change for a proxy?

A proxy server opens a new connection to each destination on the client's behalf. When the client sends a domain name, the proxy resolves it and picks an IPv4 or IPv6 address; when the client sends a literal IP, the family is already decided. In sing-box, dial fields control that choice and can also bind outgoing connections to a specific local IPv6 address.[1]

So the server needs two things: an IPv6 path that works from the operating system, and a proxy setting that uses it. The overview of running your own network services covers the wider maintenance duties. If the address families themselves are new to you, start with how IPv4 and IPv6 addressing differ, because the checks below assume you can read an IPv6 prefix.

This is a server-side change. A client device sending IPv6 outside its tunnel is a different problem, covered in the explanation of IPv6 leaks.

Which IPv6 allocation did your provider give you?

Providers usually hand out one of a few common shapes, and each one changes what "add an address" means. With an on-link prefix, the upstream router finds your address through Neighbor Discovery: it sends a Neighbor Solicitation, and only an address actually configured on your interface answers.[2] With a routed prefix, the provider forwards the whole prefix to one address you already hold.

AllocationWhat the router expectsWhat to configureMain risk
Single /128One address answering NDThat address and the stated gatewayTypo in address or gateway
On-link /64Addresses answering ND on the linkOne chosen address from the prefixUsing an address you never configured
Routed /64Prefix forwarded to a link addressLink address plus prefix useMissing the separate link address
SLAAC via RARouter Advertisements on the linkAccept RA; avoid static duplicatesRA ignored when forwarding is on

Read the provider's control panel or documentation for the exact address, prefix length and gateway; some providers use a link-local gateway such as fe80::1. The rest of this guide uses one stable address. Cycling many addresses per connection to get around platform blocks or limits is out of scope here, and it can break the provider's or the destination's terms.

Step 1: Inventory addresses, routes and kernel settings

Log in over IPv4 first, so an IPv6 mistake cannot lock you out. Record the current state:

ip -6 addr show scope global
ip -6 route show default
sysctl net.ipv6.conf.all.forwarding
sysctl net.ipv6.conf.eth0.accept_ra
curl -6 -sS -o /dev/null -w '%{http_code}\n' https://example.com

Replace eth0 with your interface. A global address plus a default route and a successful curl -6 mean the system path already works, so you can skip to Step 3. A global address without a default route, or no global address, means Step 2 applies.

The accept_ra value matters on proxy servers that also forward traffic, such as a VPN endpoint. With accept_ra set to 1, the kernel accepts Router Advertisements only while forwarding is disabled; 2 accepts them even when forwarding is enabled.[3] If your provider relies on RA and you enable forwarding, the default route can disappear silently.

Step 2: Set the address and default route in Netplan

On Ubuntu servers that use Netplan, add a separate file instead of editing the provider's generated one, and keep a copy of every existing file under /etc/netplan/. The example sets one address and a Netplan IPv6 default route, using the documentation prefix 2001:db8::/32; replace the address, prefix length, gateway and interface with your provider's values.

network:
  version: 2
  ethernets:
    eth0:
      addresses:
        - "2001:db8:1234:5678::10/64"
      routes:
        - to: "::/0"
          via: "fe80::1"
          on-link: true

Netplan's addresses adds static addresses alongside any from DHCP or RA, routes needs at least to, and a default route can be defined only once per IP family and routing table.[4] on-link: true tells the system the gateway is directly connected, which matters when the gateway sits outside your prefix. If the provider uses RA instead, set accept-ra: true and leave the static route out, so you do not end up with two competing defaults.[4]

Apply with a safety timer:

sudo netplan try

netplan try applies the configuration and rolls it back unless you confirm within 120 seconds by default; after a timeout or cancel, check that the old state actually returned.[5] Run the Step 1 commands again before confirming.

Step 3: Keep ICMPv6 open and match inbound limits

Neighbor Discovery runs over ICMPv6, so a firewall that drops all ICMPv6 can make the address unreachable even when the configuration is correct.[2] Allow the ICMPv6 types your firewall tool marks as required for IPv6, rather than writing a blanket drop.

Then check exposure. A proxy listening on [::] accepts IPv6 connections, so the inbound rules you wrote for IPv4 need IPv6 equivalents. Compare ss -lntup with the firewall's IPv6 rule list, and confirm that management ports and any local-only listener stay closed to the internet on both families.

Step 4: Set the sing-box IPv6 outbound preference

From sing-box 1.12.0, the domain_strategy dial field is deprecated and scheduled for removal in 1.14.0; the replacement is a domain_resolver object that names a DNS server and a strategy.[1][6] The strategy values are prefer_ipv4, prefer_ipv6, ipv4_only and ipv6_only.[7]

The following fragment shows only the parts that matter: a local DNS server, which resolves through the host system, a direct outbound that prefers IPv6, and a test inbound bound to the loopback address.[8] Merge it into your existing configuration rather than replacing your real inbound.

{
  "dns": {
    "servers": [{ "type": "local", "tag": "local" }]
  },
  "inbounds": [
    { "type": "mixed", "tag": "test-in", "listen": "127.0.0.1", "listen_port": 2080 }
  ],
  "outbounds": [
    {
      "type": "direct",
      "tag": "direct-out",
      "inet6_bind_address": "2001:db8:1234:5678::10",
      "domain_resolver": { "server": "local", "strategy": "prefer_ipv6" }
    }
  ],
  "route": { "final": "direct-out" }
}

inet6_bind_address pins IPv6 connections to the address you configured in Step 2; leave it out if you have only one global address.[1] Run sing-box check -c /etc/sing-box/config.json and restart the service only when the check passes.

StrategyDestination has A and AAAAIPv4-only destinationUse it when
prefer_ipv4IPv4 usedIPv4 usedIPv6 is new and untested
prefer_ipv6IPv6 usedFalls back to IPv4You want IPv6 where available
ipv6_onlyIPv6 usedFailsTesting the IPv6 path alone
ipv4_onlyIPv4 usedIPv4 usedRolling back quickly

Step 5: Verify IPv6 targets, IPv4 fallback and the exit address

Test through the loopback inbound on the server itself. --socks5-hostname sends the domain name to the proxy, so sing-box performs the resolution and applies the strategy.

curl -sS --socks5-hostname 127.0.0.1:2080 -o /dev/null -w '%{remote_ip}\n' https://example.com

Use these as expected observations and record your own results.

Check methodExpected observationIf it fails
Dual-stack site through the test inboundConnection succeeds over IPv6Recheck Step 1 and the bind address
IPv4-only site with prefer_ipv6Connection falls back to IPv4Make sure you did not set ipv6_only
Client device through your real inboundIP check shows the server's IPv6 for an IPv6 pathCompare client DNS and proxy rules
Firewall scan of public ports on IPv6Only intended ports answerAdd the missing IPv6 rules

From a client connected to your proxy, check which address the outside world sees. An IPv6 result confirms that web requests take the new path; an IPv4 result can still be correct when the site or the client's own resolution chose IPv4. Remove the test inbound when you finish.

Step 6: Roll back without losing access

Keep the IPv4 session open while reverting. Delete or move the Netplan file you added, run sudo netplan apply, and confirm ip -6 route show default matches your Step 1 record. In sing-box, switch the strategy to prefer_ipv4 or ipv4_only, remove inet6_bind_address, run the configuration check and restart.

If the server becomes unreachable, use the provider's web console to remove the added file. Do not disable IPv6 kernel-wide as a first response; the ip-sysctl documentation notes that writing the all value of disable_ipv6 changes every interface at once.[3]

When is single-address IPv6 outbound the wrong tool?

IPv6 egress changes the route your server takes, not who you are. Destinations still see one stable address tied to your VPS. If the goal is avoiding the operator's own responsibilities, a hosted service may fit better than a server you maintain.

It is also the wrong tool when the destination has no IPv6, when the provider's IPv6 path is unstable, or when you need per-user addresses. In those cases keep prefer_ipv4, and revisit after the provider fixes the path. Home routers that receive a delegated prefix need a different procedure, described in the OpenWrt prefix delegation guide.

Summary

  • Identify whether you have a /128, an on-link /64, a routed /64 or SLAAC before editing anything.
  • Add one address and one default route with netplan try, keeping IPv4 access open.
  • Allow required ICMPv6 and mirror your IPv4 inbound limits for IPv6.
  • Use domain_resolver with prefer_ipv6 in sing-box 1.12 or later, then test both IPv6 and IPv4 fallback.

FAQ

Do I need a whole /64 for IPv6 outbound?

No. One working global address and a default route are enough for a proxy to reach IPv6 destinations. A /64 only gives you more addresses to choose from.

Why can my server ping its gateway but not reach websites?

Usually the default route is missing or points to the wrong gateway. Compare ip -6 route show default with the provider's stated gateway, and check that the firewall is not dropping ICMPv6.

Should I still use domain_strategy in sing-box?

Not on 1.12 or later. It is deprecated there and scheduled for removal in 1.14.0, so move the preference into a domain_resolver object with a strategy value.

Will prefer_ipv6 break sites that only have IPv4?

It should not. With prefer_ipv6, a destination without an AAAA record is still reached over IPv4; only ipv6_only makes those connections fail.

Why did my IPv6 route disappear after enabling forwarding?

With accept_ra at 1, the kernel ignores Router Advertisements once forwarding is on. Set accept_ra to 2 on that interface or configure a static default route instead.

Can I rotate IPv6 addresses to avoid rate limits?

This guide does not cover that. Rotating addresses to get around blocks or limits can violate provider and site terms, and the procedure here keeps one stable address.

Does IPv6 outbound make my proxy more private?

No. It changes which address family carries traffic. Destinations still see an address registered to your VPS, so your privacy depends on the same operator and logging choices as before.

Disclaimer: This article is for general informational purposes only and does not constitute legal, technical, or other professional advice. We make no guarantees regarding the accuracy, completeness, or timeliness of the content. Follow your hosting provider's acceptable use policy and the terms of the services you connect to.

Sources:

  1. sing-box — Dial Fields — https://sing-box.sagernet.org/configuration/shared/dial/
  2. IETF — RFC 4861, Neighbor Discovery for IP version 6 (IPv6) — https://www.rfc-editor.org/rfc/rfc4861
  3. Linux kernel — IP sysctl — https://docs.kernel.org/networking/ip-sysctl.html
  4. Netplan — YAML configuration reference — https://netplan.readthedocs.io/en/stable/netplan-yaml/
  5. Netplan — netplan try — https://netplan.readthedocs.io/en/stable/netplan-try/
  6. sing-box — Migration — https://sing-box.sagernet.org/migration/
  7. sing-box — Rule Action — https://sing-box.sagernet.org/configuration/route/rule_action/
  8. sing-box — Local DNS server — https://sing-box.sagernet.org/configuration/dns/server/local/

Sources checked 14 October 2026.


Related articles:

Start your 3-day free trial

Sign up to experience all premium features at no cost.

*Available only to new users. Each user is limited to one trial.

VPS IPv6 Outbound for a Self-Hosted Proxy: Setup and Checks | AethoVPN