Validation
Verify your NAT46 deployment is working correctly
Installation Validation
After enabling NAT46 through the wizard, run through these checks to verify everything is working.
Quick Validation Checklist
Run these commands for a rapid pass/fail check:
# 1. Config exists and enabled
jq '.enabled' ~/resources/.nat46_config.json
# Expected: true
# 2. Jool SIIT module loaded
lsmod | grep jool_siit
# Expected: jool_siit line present
# 3. IPv6 forwarding enabled
sysctl -n net.ipv6.conf.all.forwarding
# Expected: 1
# 4. CoreDNS has nat46 plugin
docker exec <container> coredns -plugins 2>/dev/null | grep nat46
# Expected: nat46
# 5. A query synthesizes translated address
dig @127.0.0.1 v6.speedtest.nexioapp.org A +short
# Expected: address in configured ipv4_range (e.g., 240.0.0.1)
# 6. AAAA query returns NODATA (empty answer)
dig @127.0.0.1 v6.speedtest.nexioapp.org AAAA | grep "ANSWER: 0"
# Expected: matches (ANSWER: 0)
# 7. Normal DNS passthrough works
dig @127.0.0.1 google.com A +short
# Expected: real IP addresses
# 8. No CoreDNS errors
docker exec <container> grep -i "error" /var/log/coredns.log | tail -5
# Expected: no DNS resolution errorsReplace <container> with your publisher container name or ID.
Detailed Validation Steps
Host-Level Checks
NAT46 Configuration
cat ~/resources/.nat46_config.jsonVerify enabled is true, pool6 is a /96 ULA prefix, and ipv4_range is set.
Jool SIIT Instance
sudo jool_siit instance displayShould show a default instance.
Pool6 Route
ip -6 route show table local | grep fdShould show a local route for your pool6 prefix on dev lo.
The pool6 route is in the local routing table, not the main table. You must use table local to see it. A plain ip -6 route show will not display it.
Source EAMT Entry
sudo jool_siit eamt displayShould show a source mapping entry:
191.1.0.1/32 <-> <host_ipv6>/128This entry maps the publisher's fixed SNAT address to the host's real IPv6. If it's missing:
HOST_IPV6=$(jq -r '.host_ipv6' ~/resources/.nat46_config.json)
sudo jool_siit eamt add "$HOST_IPV6"/128 191.1.0.1/32The CoreDNS nat46 plugin flushes the EAMT on startup and restores this entry automatically from the config file. If the entry is missing after a container restart, check that host_ipv6 is set in ~/resources/.nat46_config.json.
IPv6 Forwarding
sysctl net.ipv6.conf.all.forwardingMust be 1.
Container-Level Checks
Enter the container:
docker exec -it <container> bashCoreDNS Plugin
coredns -plugins 2>/dev/null | grep nat46Corefile
cat /etc/coredns/CorefileShould contain a nat46 { ... } block with ipv4_range, default_ttl, and grace_period.
TUN Interface
ip addr show tun0Should show tun0 with an IPv4 address.
Config File Mounted
cat /home/resources/.nat46_config.jsonShould match the host file.
DNS Checks
A Query for IPv6-Only Host
dig @127.0.0.1 v6.speedtest.nexioapp.org A +shortShould return an address in your configured ipv4_range (e.g., 240.0.0.1 or 10.0.0.1).
AAAA Query Returns NODATA
dig @127.0.0.1 v6.speedtest.nexioapp.org AAAAExpected response:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR
;; flags: qr rd; QUERY: 1, ANSWER: 0, AUTHORITY: 0status: NOERRORwithANSWER: 0= correct NODATAANSWER: 1with an A record = old buggy plugin still deployed
Normal DNS Passthrough
dig @127.0.0.1 google.com A +shortShould return real IP addresses. NAT46 should not interfere with hosts that have native A records.
EAMT Mappings
After a successful synthesized A query:
sudo jool_siit eamt displayShould show a mapping from the synthesized IPv4 to the real IPv6 address.
Publisher Process Checks
DNS Resolution in Logs
docker exec <container> grep -i "error\|nat46" /var/log/coredns.log | tail -10nat46synthesis entries = working- DNS errors = see Troubleshooting