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)

Reply via email to