Good day, I’m wondering if someone familiar with IPv6 and NAT64 can help me understand what I’m missing here as I’m struggling to get NAT64 working with RFC 1918 IPv4-only hosts (including VPN hosts and hairpining to internal hosts) . I appreciate any insight you may be able to provide.
I’ve configured two af-to rules in my pf.conf to provide IPv6 NAT64 Provider-side transLATor (PLAT) to 64:ff9b::/96 from the egress interface em0, and to 64:ff9b::a00:0/104 (translates to 10/8 IPv4 prefix) from an internal interface (to reach remote VPN networks and hairpin NAT). I’ve also configured the IPv6-Only Preferred DHCP option 108 (RFC 8925) on my home network lab. Most day to day things work, but I’m struggling to connect to IPv4 addresses on the other side of an IPSec tunnel from IPv6-only hosts using NAT64, and also to hairpin and reach hosts that don’t support IPv6 only (eg. IoT devices) on the vport99 network (10.1.0.0/24 prefix) from IPv6 only hosts. I ran the following tests: 1. Ping an IPv4-only host on the Internet from an IPv6-only host - *SUCCESS* 2. Ping an IPv6-only (Inernet and locally) host from an IPv6-only host - *SUCCESS* 3. Ping a IPv6 NAT64 prefix (64:ff9b::a02:1) which translates to a IPv4 address (10.2.0.1) on the other side of the IPSec tunnel and confirmed the traffic on sec(4) interface using tcpdump - *SUCCESS* 4. Ping the IPv4 address 10.2.0.1 (from test 3) on the other side of the IPSec tunnel (I’m not seeing this hit a rule and I’m not seeing any traffic on the sec(4) interface) - *FAILED* 5. Ping the IPv4 address (10.2.0.1 from test 3) from the IPv4 address internal interface vport99 - *SUCCESS* Below is the relevant portions of my router/firewall configuration. Please let me know if I have missed some details or you would like to see something else. */etc/hostname.em0* descr "Internet" inet autoconf inet6 autoconf */etc/hostname.em1* descr "Internal VLAN Trunk" up */etc/hostname.vlan99* parent em1 vnetid 99 up */etc/hostname.vport99* group internal descr "Home Network" inet 10.1.0.1/24 inet6 autoconf inet6 alias fd34:1107:d22e::1/64 up */etc/hostname.veb99* add vlan99 add vport99 up */etc/hostname.sec0* inet 10.250.0.1 255.255.255.252 10.250.0.2 up !route add -net 10.2.0/24 10.250.0.2 */etc/dhcp6leased.conf* ## Global request rapid commit ## PD request prefix delegation on em0 for { vport99/64 #vport100/64 #vport105/64 } */etc/rad.conf* interface vport99 dns { nameserver fd34:1107:d22e::1 } #interface vport100 #interface vport105 # Advertise the NAT64 prefix available on this network nat64 prefix 64:ff9b::/96 */etc/dhcpd.conf* subnet 10.1.0.0 netmask 255.255.255.0 { option domain-name-servers 10.1.0.1; option ntp-servers 10.1.0.1; option routers 10.1.0.1; # Send DHCP Option 108 (RFC 8925) to tell clients option ipv6-only-preferred 900; range 10.1.0.100 10.1.0.199; } */etc/pf.conf* home_if = “vport99" nat64_prefix = "64:ff9b::/96” table <martians> { 0.0.0.0/8 10.0.0.0/8 127.0.0.0/8 169.254.0.0/16 \ 172.16.0.0/12 192.0.0.0/24 192.0.2.0/24 224.0.0.0/3 192.168.0.0/16 \ 198.18.0.0/15 198.51.100.0/24 203.0.113.0/24 \ ::/128 ::/96 ::1/128 ::ffff:0:0/96 100::/64 2001:10::/28 2001:2::/48 \ 2001:db8::/32 3ffe::/16 fec0::/10 fc00::/7 } icmp_types = "echoreq" icmp6_types = "{ unreach toobig timex paramprob echoreq routersol routeradv \ neighbrsol neighbradv redir routrrenum }" set block-policy drop set loginterface egress set skip on lo0 match in all scrub (no-df random-id max-mss 1440) match out on egress inet from !(egress:network) to any nat-to (egress:0) antispoof quick for { egress $home_if $guest $kids } block in quick on egress from <martians> to any block return out quick on egress from any to <martians> pass in quick on egress inet proto { tcp udp } from any to (egress:0) port bootpc pass out quick on egress inet proto { tcp udp } from (egress:0) to any port bootps block all pass out quick inet pass out quick inet6 pass out log (all) quick on enc0 keep state (if-bound) pass in on egress proto udp from any to (egress) port {isakmp ipsec-nat-t} tag IKED pass in on egress proto esp from any to (egress) tag IKED pass in on enc0 proto ipencap from any to (egress) keep state (if-bound) pass in log on sec0 from 10.250.0.2/32 to 10.250.0.1/32 pass in on $home_if inet from $home_if:network pass in on $home_if inet6 pass in quick on egress inet6 proto icmp6 all icmp6-type $icmp6_types pass in quick on egress proto udp from fe80::/10 port dhcpv6-server to fe80::/10 port dhcpv6-client # NAT64 for IPSec tunnel traffic pass in log on $home_if inet6 from any to 64:ff9b::a00:0/104 af-to inet from 10.1.0.1 # NAT64 Provider-side transLATor (PLAT) pass in log on $home_if inet6 from any to $nat64_prefix af-to inet from (egress:0)