PF + route-to + gif weird behavior (bug ?)

Schmurfy schmurfy at gmail.com
Mon Jun 27 11:13:59 UTC 2011


Hi,
I just came across a problem with route-to and gif interfaces.
First, here is my rc.conf:

# Router
ifconfig_em0="inet 10.11.12.212/24"
defaultrouter="10.11.12.253"
gateway_enable="YES"

static_routes="gif_endpoint"
route_visp="10.11.20.1/32 10.11.12.213"

pf_enable="YES"
pf_rules="/etc/pf.conf"
pflog_enable="YES"

# IPIP tunnels
gif_interfaces="gif1001"

ifconfig_em0_alias0="inet 10.11.20.2/32"
ifconfig_em0_alias1="inet 192.168.254.1/32"
gifconfig_gif1001="10.11.20.2 10.11.20.1"
ifconfig_gif1001="inet 1.2.3.1 1.2.3.2 netmask 255.255.255.252"





What I wanted to do is to redirect incoming connections on the external
interface (em0) on a specific address to a gif tunnel, my problem is that
the packet is redirected so that part works but the packet exiting the em0
interfaces (the gif tunnel is also using em0) has a wrong ipip header: the
source address is the first address assigned to em0 instead of the alias
added for the gif tunnel.
Without pf the tunnel itself works fine, both side can ping each other and
the packets are correct.

Here is my pf.conf (The rules I am speaking of are the port forwarding ones,
1 rdr and 2 pass):

phys_if = "em0"

env1c1_tunnel = "gif1001"
env1c1_tunnel_dst = "10.11.20.1"
env1c1_tunnel_src = "10.11.20.2"
env1c1_escape = "10.11.12.212"

set skip on lo0
set block-policy drop

scrub in on $phys_if

####
## NAT / RDR
####

nat on $phys_if tagged e1c1 -> $env1c1_escape
nat on $phys_if tagged e1c2 -> $env1c2_escape

# forwarded port (http)
rdr on $phys_if proto tcp from any to $env1c1_escape port 80 tag e1c1 ->
192.168.0.23 port 80


####
## FILTERS
####

# block any packet with no match
block log all

# allow our own services to work
pass in on $phys_if proto tcp from any to $phys_if port ssh synproxy state
pass in on $phys_if proto icmp from any to $phys_if
pass out on $phys_if proto udp from any to any port { ntp, domain }


# allow ipip traffic (tunnels)
pass in on $phys_if from $env1c1_tunnel_dst to $env1c1_tunnel_src
pass out on $phys_if from $env1c1_tunnel_src to $env1c1_tunnel_dst

pass in on $phys_if from $env1c2_tunnel_dst to $env1c2_tunnel_src
pass out on $phys_if from $env1c2_tunnel_src to $env1c2_tunnel_dst

# Port forwarding
pass in log on $phys_if route-to ( $env1c1_tunnel  1.2.3.2 ) proto tcp from
any to 192.168.0.23 port 80 tagged e1c1
pass out log on $env1c1_tunnel tagged e1c1

# NAT (the server's gateway will be used, traffic is returned to the tunnel)
pass in log on $env1c1_tunnel tag e1c1
pass out log on $phys_if reply-to $env1c1_tunnel tagged e1c1

pass in log on $env1c2_tunnel tag e1c2
pass out log on $phys_if reply-to $env1c2_tunnel tagged e1c2

# sites => sites
pass in on $env1c1_tunnel route-to $env1c1_tunnel to $env1c1_sites tag e1c1
pass in on $env1c2_tunnel route-to $env1c2_tunnel to $env1c2_sites tag e1c2





Did I hit a bug ? or did I do something wrong ?
I did a quick test on openbsd with a similar config and everything works
fine there but I would really prefer sticking with FreeBSD :/

Thanks for any pointers.



PS: I first posted this on the freebsd forum, full post is available here:
http://forums.freebsd.org/showthread.php?t=24600


More information about the freebsd-pf mailing list