Netskope Publisher

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 errors

Replace <container> with your publisher container name or ID.

Detailed Validation Steps

Host-Level Checks

NAT46 Configuration

cat ~/resources/.nat46_config.json

Verify enabled is true, pool6 is a /96 ULA prefix, and ipv4_range is set.

Jool SIIT Instance

sudo jool_siit instance display

Should show a default instance.

Pool6 Route

ip -6 route show table local | grep fd

Should 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 display

Should show a source mapping entry:

191.1.0.1/32 <-> <host_ipv6>/128

This 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/32

The 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.forwarding

Must be 1.

Container-Level Checks

Enter the container:

docker exec -it <container> bash

CoreDNS Plugin

coredns -plugins 2>/dev/null | grep nat46

Corefile

cat /etc/coredns/Corefile

Should contain a nat46 { ... } block with ipv4_range, default_ttl, and grace_period.

TUN Interface

ip addr show tun0

Should show tun0 with an IPv4 address.

Config File Mounted

cat /home/resources/.nat46_config.json

Should match the host file.

DNS Checks

A Query for IPv6-Only Host

dig @127.0.0.1 v6.speedtest.nexioapp.org A +short

Should 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 AAAA

Expected response:

;; ->>HEADER<<- opcode: QUERY, status: NOERROR
;; flags: qr rd; QUERY: 1, ANSWER: 0, AUTHORITY: 0
  • status: NOERROR with ANSWER: 0 = correct NODATA
  • ANSWER: 1 with an A record = old buggy plugin still deployed

Normal DNS Passthrough

dig @127.0.0.1 google.com A +short

Should 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 display

Should 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 -10

On this page