Prerequisites: your broadband is already IPv4 + IPv6 dual-stack (if you are not sure, run a test at the IPv6 test tool first)
Goal: reach your home NAS directly over IPv6 from the internet — no port forwarding, no frp, no paid relay
Time needed: about 30 minutes, half of which goes into "working out whether the address actually changes"
Clearing up one misunderstanding first: IPv6 needs no port forwarding, but it does need a firewall rule
Many people configuring IPv6 direct access for the first time stall at the same spot: they hunt through the router for "IPv6 port forwarding", find no such menu, and conclude their router does not support it.
The truth is that the concepts do not line up.
Port forwarding (NAT translation) was needed in the IPv4 era because every device in your home shares one public IPv4, so the router has to know "which machine should that inbound port 5000 go to":
Internet → Public IPv4:5000 → Router looks up NAT table → 192.168.1.100:5000 (NAS)
↑ this step is port forwarding
Under IPv6, every device has its own public address, so the router does not translate anything — it only decides "do I let this packet in":
Internet → [2408:xxxx:xxxx:xxxx::100]:5000 → Router IPv6 firewall → NAS
↑ only "allow/block", no translation
So:
A router's IPv6 firewall defaults to "deny all inbound", which is by design and is exactly how it should be. What you need to do is open a hole for that NAS address and those few ports. When you go looking for the menu, do not look for "port forwarding" — look for "IPv6 firewall".
Where direct connection beats relaying
No inflated multiplier here (lines differ far too much, and any single number would be made up) — just the structural difference:
- Via a relay or tunnel: your data
NAS → relay server → youtakes a longer way round, andthe ceiling is pinned by the relay node's bandwidth and its paid plan - Via direct IPv6:
NAS → youtravels the carrier backbone, and the ceiling is your home connection's upstream bandwidth
Home upstream bandwidth is typically 30–50 Mbps (on a gigabit plan), and that number is the real ceiling for streaming or pulling files over a direct connection. Relay setups often cannot even saturate that, and this is the true source of "direct is faster".
Step 1: Confirm you really are dual-stack
Open the 17NAS IPv6 test and see which category your result falls into:
Watch out for one trap: this test measures the outbound path of "the device you are on right now". Your phone showing IPv6 over Wi-Fi does not mean the NAS has it — the NAS may sit behind a switch or software router that does not forward IPv6, or may have IPv6 disabled itself. So the next step is to confirm the NAS separately.
While you are at it, note the address prefix the test reports (2408:/240e:/2409: and so on); you will need it later to cross-check the NAS address.
Step 2: Confirm the NAS has a "public IPv6" address
It is not enough for an IPv6 address to exist — it has to be the publicly routable kind. There are three address classes you must keep straight:
fe80::fd00:: ~ fdff::2000::/3 (that is, 2xxx: 240e: 2408: 2409: 240c: and so on)How to check on each platform
Synology DSM: Control Panel → Network → Network Interface → select the LAN → Edit → IPv6, set the mode to "Auto", and the acquired address appears below.
QNAP QTS: Control Panel → Network & Virtual Switch → Interfaces → the relevant NIC → IPv6.
fnOS / Linux / Synology SSH:
ip -6 addr show scope global
Windows (if the NAS is Windows or a software-router VM):
ipconfig /all
If the NAS only has an address starting with fe80::, the router is not handing an IPv6 prefix to the LAN. Back to the router:
- WAN IPv6 connection type: choose DHCPv6 or SLAAC (domestic carriers almost all use DHCPv6-PD)
- Prefix acquisition: DHCPv6-PD (prefix delegation); the prefix length is usually
/60or/56 - LAN assignment: SLAAC or SLAAC + stateless DHCPv6
Wait 1–2 minutes after the change, then check again on the NAS. If it is still missing, disable and re-enable the NAS network adapter.
Step 3 (the step most often skipped): make the NAS address stable
If it suddenly stops connecting a couple of days after setup, this is almost certainly why. An IPv6 address is assembled from two parts:
2408:8210:1234:5678 : a1b2:c3d4:e5f6:0789
└── prefix (assigned by the carrier) ──┘ └── interface ID (chosen by the device) ──┘
both parts can change, but the causes and the fixes are completely different.
Change one: the interface ID shifts (IPv6 privacy extensions)
To prevent tracking via a fixed address, many systems enable "temporary addresses / privacy extensions" by default, and the interface ID changes daily or even every few hours. On a desktop that is a good thing; on a NAS it is a disaster — your DDNS can never keep up.
How to tell whether you are affected:
ip -6 addr show scope global
If the output contains temporary or secondary, it is a temporary address. Another rough-and-ready check:an address containing ff:fe in the middle is an EUI-64 address (derived from the NIC's MAC and stable by nature); a string with no discernible pattern that changes daily is a temporary address.
Turning it off:
Linux / fnOS / Synology SSH:
# Apply temporarily first, to verify
sudo sysctl -w net.ipv6.conf.all.use_tempaddr=0
sudo sysctl -w net.ipv6.conf.default.use_tempaddr=0
# Once confirmed, write it into /etc/sysctl.conf to make it permanent
echo "net.ipv6.conf.all.use_tempaddr=0" | sudo tee -a /etc/sysctl.conf
echo "net.ipv6.conf.default.use_tempaddr=0" | sudo tee -a /etc/sysctl.conf
Windows (admin PowerShell / CMD):
netsh interface ipv6 set global randomizeidentifiers=disabled
netsh interface ipv6 set privacy state=disabled
Synology DSM and QNAP use EUI-64 by default, so the interface ID is generally stable, but it is still worth confirming with the method above, since behaviour differs between versions.
Change two: the prefix shifts (the carrier changes your IP)
This one is out of your hands. Home connections from China Telecom, China Unicom, and China Mobile can all pick up a new prefix after the ONT redials, after line work, or after long uptime. The symptom: the back half of the address is unchanged while the first four groups differ.
There is only one answer: DDNS (covered in Step 7). Do not try to configure a static IPv6 by hand — the moment the prefix changes, the static address is void.
If your router supports "manual IPv6 interface ID" (OpenWrt, iKuai, and some Asus models do), you can pin the NAS interface ID to something memorable such as ::100, so that a prefix change only alters the first half of the address and troubleshooting gets much easier.
Step 4: Open the router's IPv6 firewall
The core action: allow remote access to the NAS's full IPv6 address on the specified port.
First work out which ports to open. The common ones:
If you can get away with opening only 443 for a reverse proxy, do not open a pile of ports. Every extra port is one more doorway to be scanned.
Where the settings live by brand
Asus
Firewall → IPv6 Firewall → Enable IPv6 Firewall = Yes → Add rule:
::100)5001TP-LINK
IPv6 settings → Firewall / "IPv6 forwarding rules" (the naming varies by firmware); enter the NAS IPv6 address and port. Some older firmware only offers a master "IPv6 firewall on/off" switch.
Xiaomi / Redmi
Advanced routing → Advanced settings → IPv6 settings; most models only have a firewall master switch. If all you can do is turn the master switch off, make sure the protection lives on the NAS side instead (Step 8).
Huawei
More features → Security settings → IPv6 firewall; choose "Custom" and then add an allow rule. Choosing "Off" means allow everything, which is not recommended.
OpenWrt / iStoreOS (most precise, recommended)
SSH in and run:
uci add firewall rule
uci set firewall.@rule[-1].name='Allow-NAS-DSM'
uci set firewall.@rule[-1].src='wan'
uci set firewall.@rule[-1].dest='lan'
uci set firewall.@rule[-1].proto='tcp'
uci set firewall.@rule[-1].dest_ip='2408:xxxx:xxxx:xxxx::100'
uci set firewall.@rule[-1].dest_port='5001'
uci set firewall.@rule[-1].family='ipv6'
uci set firewall.@rule[-1].target='ACCEPT'
uci commit firewall
/etc/init.d/firewall restart
Replace dest_ip with your NAS's actual address. This rule breaks when the prefix changes — the more robust approach is to match the interface ID only, and OpenWrt supports the ::100/::ffff:ffff:ffff:ffff mask form for that. Versions differ quite a bit here, so always verify with the method in Step 6 once configured.
The ONT can block you too
If your ONT is in router mode (dialling up itself), traffic has to pass the ONT before the router, and the ONT's IPv6 firewall will block it just the same. This double-layer setup is very hard to troubleshoot.
It is strongly recommended that you switch the ONT to bridge mode and let the router dial, leaving only one layer. See: Bridge your ONT in 10 minutes.
⚠️ Do not take the lazy route and simply turn the IPv6 firewall off entirely. That exposes every listening port on the NAS (including SMB, SSH, databases, and all those containers in Docker) to the public internet. Better to click a couple more times and add a rule.
Step 5: Do not forget the NAS's own firewall
Once the router allows the traffic, the NAS still has its own gate. This is a very common reason why "the router rule is clearly there but it still does not work".
Synology DSM: Control Panel → Security → Firewall. Check the "Source IP" in your rules; if you previously entered only an IPv4 subnet (such as 192.168.1.0/24), IPv6 traffic gets blocked by the default rule. You need to add a rule that allows the relevant port from "All".
QNAP: Control Panel → System → Security → Allow/Deny list.
Linux (ufw):
sudo ufw allow proto tcp to any port 5001
sudo ufw status verbose
Note that /etc/default/ufw in IPV6=yes must be enabled (on by default in recent versions), otherwise the rules apply to IPv4 only.
Services deployed in Docker must be verified separately. How container networking handles IPv6 depends on the Docker version and daemon configuration, and -p 5001:5001 in some environments IPv6 works while in others it does not, so do not assume from experience — test it with the method in the next step. If the test fails, there are two common fixes:
- Switch the container to
network_mode: host(the least effort) - Enable IPv6 support in
/etc/docker/daemon.json("ipv6": truetogether with"ip6tables": true), then restart dockerd
Step 6: Verify — connect back from the public internet for real
Do not fudge this step with "I will just try connecting from home".Working on the LAN does not mean working from the internet: when you reach the NAS's IPv6 address from home, the packets never leave the router, so there is no way to tell whether the firewall rule took effect.
You must verify from outside. The two commands below run directly on the NAS (over SSH or in Synology's terminal) and are the fastest route:
1. First confirm the NAS has IPv6 egress of its own, and get its public address
curl -6 https://v6.17nas.com
Normally it simply returns an address, such as 2408:8210:1234:5678:a1b2:c3d4:e5f6:789.
- Error / timeout → the NAS has no IPv6 egress at all; go back to Step 2
- The returned address does not match what you see in DSM → a temporary address is almost certainly at work; go back to Step 3
To see the location and carrier as well:
curl -6 "https://v6.17nas.com?format=json"
2. Have a public server connect back to your port
curl -6 "https://17nas.com/api/tools/port-check.php?port=5001"
This endpoint will have the 17NAS server actively open a TCP connection to the port you specify on the address from before, then report the result. It returns something like:
{"success":true,"status":"open","ip":"2408:8210:...","port":5001,"ip_version":6,"latency_ms":24}
The three status outcomes map to three completely different problems:
openrefusedfilteredBeing able to tell refused from filtered saves half the guesswork — in the first case stop fiddling with the router, in the second stop fiddling with the NAS.
Note: this endpoint only connects back tothe address that made the request and will not target an arbitrary IP. So the command must run on the NAS; running it on your computer tests your computer. Limited to 30 calls per hour.
3. Browser verification (remember the square brackets)
An IPv6 address is full of colons, and the browser treats them as a port separator, so you must wrap the address in square brackets:
❌ https://2408:8210:1234:5678::100:5001
✅ https://[2408:8210:1234:5678::100]:5001
Turn off Wi-Fi on your phone and use 4G/5G to open this address — that is the verification closest to real-world use. If your mobile carrier network has no IPv6, it will not open — that is not a mistake on your side, it is a limitation on the phone's side.
Step 7: The address changes, so set up DDNS (AAAA records)
It connects now, but the address is a string of hexadecimal nobody can memorise, and the prefix can change at any time. The solution is to point your domain's AAAA record (IPv6 uses AAAA; A is for IPv4) automatically at the current address.
Option A: ddns-go (recommended, graphical interface)
It supports Cloudflare, Alibaba Cloud, Tencent Cloud, DNSPod, and more; one Docker command starts it:
docker run -d --name ddns-go --restart=always \
--network=host \
-v /opt/ddns-go:/root \
jeessy/ddns-go
Visit http://NAS-LAN-IP:9876 to configure it.Key settings:
- Enable "IPv6" and set the domain type to AAAA
- Acquisition method: prefer "get via network interface", then filter out temporary addresses with a regex
- Set the TTL to 60–120 seconds; the default 600 seconds means waiting 10 minutes after a prefix change
Option B: write your own script (simplest and most reliable)
Paired with the endpoint above, a single cron job is enough. Taking Cloudflare as the example:
#!/bin/bash
# /opt/ddns6.sh — sync the AAAA record every 5 minutes
TOKEN="your_Cloudflare_API_Token"
ZONE_ID="your_Zone_ID"
RECORD_ID="Record_ID_of_the_AAAA_record"
NAME="nas.example.com"
IP6=$(curl -6 -sS --max-time 10 https://v6.17nas.com)
[ -z "$IP6" ] && exit 0 # if we cannot get it, do nothing - never blank the record
LAST=$(cat /tmp/.ddns6_last 2>/dev/null)
[ "$IP6" = "$LAST" ] && exit 0 # unchanged, so do not send a request
curl -sS -X PUT \
"https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records/$RECORD_ID" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
--data "{\"type\":\"AAAA\",\"name\":\"$NAME\",\"content\":\"$IP6\",\"ttl\":120,\"proxied\":false}" \
&& echo "$IP6" > /tmp/.ddns6_last
Make it executable and add it to crontab:
chmod +x /opt/ddns6.sh
crontab -e
# add this line
*/5 * * * * /opt/ddns6.sh >> /var/log/ddns6.log 2>&1
ZONE_ID is at the bottom right of the Cloudflare domain overview page; RECORD_ID requires creating an AAAA record manually first, then listing records via the API to obtain it.
Three easy traps:
- The script must run on the NAS, because
curl -6 v6.17nas.comreturns "the address of the machine that made the request". Running it on the router gives you the router's address, which is not the same thing. proxiedmust befalse. With Cloudflare's orange cloud on, traffic is routed back through a relay and direct connection loses its point (and the orange cloud does not proxy ports like 5000/5001 anyway).- Do not update the record when no address is obtained. The line
[ -z "$IP6" ] && exit 0in the script above does exactly that — I have seen too many people have one network hiccup blank out their AAAA record and then spend two hours investigating "why has my domain suddenly stopped resolving".
Step 8: Security — this step matters more than the previous seven combined
You must be clear-eyed about this: direct IPv6 means your NAS genuinely stands on the public internet, with no NAT to block anything for you.
A widely repeated but false comfort is "the IPv6 address space is so large, nobody will scan me". That may have held in 2018; it does not hold now. Attackers no longer brute-force the address space — they obtain live addresses directly from places like these:
- Certificate Transparency logs (CT logs): once you issue a certificate for
nas.example.comwith Let's Encrypt, that domain appears in the public CT logs the same day, visible to anyone - DNS record brute-forcing: subdomains such as
nas.home.syno.ds.are among the first entries in any wordlist - Passive DNS databases, plus screenshots you yourself posted on a forum
The conclusion: if you have configured a domain, assume the address is already public. Security has to come from the configuration itself, not from "nobody knows about me".
Must-do checklist
At the port level
- Allow only the ports you need; if a reverse proxy can collapse everything onto 443, open only 443
- Never expose:
445/139(SMB, the number one entry point for ransomware),111/2049(NFS),3389(RDP),3306/5432(databases), Docker's2375 - Move management ports (DSM 5000/5001, QTS 8080) to uncommon ports above 10000
- Keep SSH closed unless needed; if you must, change the port and disable password login, using keys only
At the account level
- Disable or rename the default administrator account (Synology's
admin, QNAP'sadmin) — this is the scanner's first shot - Turn on two-factor authentication (2FA) for administrator accounts; it has the best cost-benefit ratio of any measure here
- Use passwords of 16 characters or more, not reused on other sites
At the protection level
- Synology: Control Panel → Security → Account → enable Auto Block (blocking an IP after 5 failures within 5 minutes is suggested)
- Turn on notifications to push successful and failed logins to your phone
- Keep the system and packages updated — both Synology and QNAP have had remotely exploitable vulnerabilities used at scale, and patching beats everything else
At the encryption level
- Always use HTTPS; never send passwords over plain HTTP
- When requesting certificates, prefer DNS-01 validation (a TXT record in DNS); it needs no port 80 open and is unaffected by carriers blocking port 80
- Synology DSM's built-in Let's Encrypt uses HTTP-01, which requires port 80 to be reachable; if 80 is blocked, switch to acme.sh with DNS-01
Going further
- If only you and your family use it, the safest approach is to not expose the web panel directly, and instead open only a WireGuard/Tailscale entry point, then reach the internal network over the encrypted mesh. Direct IPv6 still has value here — it lets WireGuard establish a peer-to-peer connection without a relay
- Review the login log periodically (Synology: Control Panel → Log Center)
Quick troubleshooting reference
curl -6 v6.17nas.com times outfe80:: addressfilteredrefusedhttp://[address]:portnetwork_mode: host or enable IPv6 for dockerdWhen direct IPv6 is not enough
Honestly, direct IPv6 has one hard prerequisite: the client side must have IPv6 too. These scenarios will fail:
- Office and campus networks (many corporate networks are still IPv4-only to this day)
- Some hotels and public Wi-Fi
- A minority of broadband plans that have not enabled IPv6 yet
- When you need to share access with someone else and cannot control their network environment
In those cases you need an "IPv4 landing point" as a supplement. The common approach is to use a CDN or edge node to translate IPv4 to IPv6 on the origin side — visitors reach the CDN over IPv4, and the CDN reaches your home NAS over IPv6. For details, see: No public IPv4? Use Tencent Cloud EdgeOne + IPv6 to reach your home network.
Best practice is to walk on two legs: direct IPv6 as the primary path (fast, free, unlimited traffic), with a CDN or Tailscale as the fallback.
Related tools and further reading
Testing tools you will use during configuration:
- IPv6 connectivity test — confirm dual-stack status and see your egress address and carrier
- Port forwarding test — connect back from the internet to verify whether the port is truly open
- NAT type test — if you also want to work on P2P, online gaming, or WireGuard hole punching
Further reading:
- IPv6 vs IPv4 in depth: a step-by-step guide to enabling IPv6 on every platform — detailed steps for each operating system
- No public IPv4 needed, no more NAT traversal! Enabling IPv6 on a home connection and configuring the router firewall
- Bridge your ONT in 10 minutes — double NAT is a common root cause of IPv6 configuration failures
One last emphasis: the verification in Step 6 is mandatory, and the security in Step 8 is mandatory. The former saves time; the latter may save all the data on your NAS.
Data reference: to see how widely IPv6 is adopted in your province and on your carrier, check the IPv6 reachability statistics by Chinese province (real test samples from the last 30 days, updated hourly).
