PF IPv6 NAT and The Curse of The Invalid Checksum

CyberLeo Kitsana cyberleo at cyberleo.net
Sun Dec 16 06:54:17 UTC 2012


Has anyone successfully attempted to NAT IPv6 addresses using PF?

I'm running 9.1-RELEASE at 2012-12-01, and am trying to cope with my colo
provider's provision of a single IPv6 address to feed a few Jails. My
fallback approach, via HE Tunnelbroker, is thwarted by the provider's
having blocked ICMP echo requests, required by Tunnelbroker to maintain
a tunnel. Thus, I decided to leverage PF to NAT a site-scope subnet. For
v4, this works fine; v6, not so much.

I managed to track down the issue to pf generating improper checksums
(or not updating the checksums at all) whenever a translation of the v6
address or port is performed, causing the egress packet to be ignored by
the intended global-scope target.

A cursory perusal of the pf code in 9.1 suggests that it should be doing
the right thing, so I am at a loss as to why it is not.

Any suggestions on where I might look? Is this send-pr(1)-worthy? Or is
v6 NAT as unwanted as Google suggests it is?

Thanks!

----

With the following configuration, all jails (with the exception of the
firewalled jump jail) can connect to global IPv4 addresses, but attempts
to connect to global IPv6 addresses time out. Conversely, incoming IPv4
connections to port 2222 are properly redirected to ssh in the jump
jail, but incoming IPv6 connections time out.

base.pf:
----8<----
host_ipv4="216.226.128.201"
host_ipv6="2605:3e00::d8e2:80c9"
jail_net4="10.4.4.0/24"
jail_net6="fec0::4444:0:0:a04:400/120"
jump_ipv4="10.4.4.2"
jump_ipv6="fec0::4444:0:0:a04:402"

set block-policy return

# Prevent jump jail from connecting out; blocked below
no nat on em1 from $jump_ipv4 to !$jail_net4
no nat on em1 from $jump_ipv6 to !$jail_net6

# Nat all other jails
nat on em1 from $jail_net4 to !$jail_net4 -> $host_ipv4
nat on em1 from $jail_net6 to !$jail_net6 -> $host_ipv6

# Invite ssh into jump jail
rdr pass on em1 proto tcp from any to $host_ipv4 port 2222 -> $jump_ipv4
port 22
rdr pass on em1 proto tcp from any to $host_ipv6 port 2222 -> $jump_ipv6
port 22

# Prevent leaking privates
block out log quick on em1 from any to $jail_net4
block out log quick on em1 from any to $jail_net6
block out log quick on em1 from $jail_net4 to any
block out log quick on em1 from $jail_net6 to any

# Isolate jump jail from connecting to other jails except via ssh
pass in quick on lo0 proto tcp from $jump_ipv4 to $jail_net4 port 22
pass in quick on lo0 proto tcp from $jump_ipv6 to $jail_net6 port 22
block in log quick on lo0 from $jump_ipv4 to any
block in log quick on lo0 from $jump_ipv6 to any

pass in all
pass out all
----8<----

/etc/jail.conf:
----8<----
# Defaults
$base="/srv/jail/${name}";

path="${base}/root";

mount.devfs;
mount.fstab = "${base}/fstab";

exec.clean;
exec.start = "/bin/sh /etc/rc";
exec.stop = "/bin/sh /etc/rc.shutdown";

jump {
  host.hostname = "jump.mtumishi.cyberleo.net";
  interface = "lo1";
  ip4.addr = 10.4.4.2;
  ip6.addr = fec0::4444:0:0:a04:402;
  enforce_statfs = 1;
}

build {
  host.hostname = "build.mtumishi.cyberleo.net";
  interface = "lo1";
  ip4.addr = 10.4.4.3;
  ip6.addr = fec0::4444:0:0:a04:403;
  enforce_statfs = 1;
}

main {
  host.hostname = "main.mtumishi.cyberleo.net";
  interface = "lo1";
  ip4.addr = 10.4.4.4;
  ip6.addr = fec0::4444:0:0:a04:404;
  enforce_statfs = 1;
}
----8<----

-- 
Fuzzy love,
-CyberLeo
Technical Administrator
CyberLeo.Net Webhosting
http://www.CyberLeo.Net
<CyberLeo at CyberLeo.Net>

Furry Peace! - http://wwww.fur.com/peace/


More information about the freebsd-pf mailing list