From owner-freebsd-pf@FreeBSD.ORG Thu Oct 13 12:45:54 2005 Return-Path: X-Original-To: freebsd-pf@freebsd.org Delivered-To: freebsd-pf@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 84D6B16A422 for ; Thu, 13 Oct 2005 12:45:54 +0000 (GMT) (envelope-from dhartmei@insomnia.benzedrine.cx) Received: from insomnia.benzedrine.cx (insomnia.benzedrine.cx [62.65.145.30]) by mx1.FreeBSD.org (Postfix) with ESMTP id 45D3743D46 for ; Thu, 13 Oct 2005 12:45:52 +0000 (GMT) (envelope-from dhartmei@insomnia.benzedrine.cx) Received: from insomnia.benzedrine.cx (dhartmei@localhost [127.0.0.1]) by insomnia.benzedrine.cx (8.13.4/8.12.11) with ESMTP id j9DCj6U7018838 (version=TLSv1/SSLv3 cipher=DHE-DSS-AES256-SHA bits=256 verify=NO); Thu, 13 Oct 2005 14:45:06 +0200 (MEST) Received: (from dhartmei@localhost) by insomnia.benzedrine.cx (8.13.4/8.12.10/Submit) id j9DCj4pi028175; Thu, 13 Oct 2005 14:45:04 +0200 (MEST) Date: Thu, 13 Oct 2005 14:45:04 +0200 From: Daniel Hartmeier To: Artemiev Igor Message-ID: <20051013124504.GE2605@insomnia.benzedrine.cx> References: <20051011121205.4dfa7cf2.ai@bmc.brk.ru> <20051011155421.4e3b69cb.ai@bmc.brk.ru> <20051012175937.GA2605@insomnia.benzedrine.cx> <20051013083343.0c8dbb2d.ai@bmc.brk.ru> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20051013083343.0c8dbb2d.ai@bmc.brk.ru> User-Agent: Mutt/1.5.10i Cc: freebsd-pf@freebsd.org Subject: Re: NAT states X-BeenThere: freebsd-pf@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "Technical discussion and general questions about packet filter \(pf\)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 13 Oct 2005 12:45:54 -0000 On Thu, Oct 13, 2005 at 08:33:43AM +0400, Artemiev Igor wrote: > By default, if an interface is not specified, state operates on any > interface. State was created on "self" aka any local interface, > but didn`t match passing packets. > I tried to set "set state-policy floating" explicitly, but to no effect. That does not apply when the state involves address/port translation. In your case, the incoming replies from the external peer match the state entry on the external interface. Right then, the translation is reversed. Then (afterwards), the packet passes back through the stack and then gets filtered again on the internal interface. There, it does NOT match the same state, because the (re-translated) address does not match. Example: nat pass from to any -> ($extif:0) block in log all pass on $lanif from $lanif:network to $lanif:network allow-opts pass out on $extif from $extif to any keep state allow-opts LAN host 10.1.2.3 (source port 65000) connects to external host 62.65.145.30 (destination port 80). The TCP SYN looks like this: src dst 10.1.2.3:65000 -> 62.65.145.30:80 It passes in on $lanif statelessly (not creating state), last matching your first pass rule. It then passes out on $extif, last matching your second pass rule, creating a translating state: lan gwy ext 10.1.2.3:65000 24.25.26.27:20000 62.65.145.30:80 where 24.25.26.27 is your $extif address and 20000 is a random proxy port. Then, the peer's reply SYN-ACK arrives in on $extif, it looks like this: src dst 62.65.145.30:80 -> 24.25.26.27:20000 Incoming packets cause a state lookup with src = ext AND dst = gwy (replacing dst with lan, if different) which matches your state entry above. So the packet is passed according to this state entry. Since lan != gwy, the destination address is replaced, i.e. dst := lan. The packet now looks like this: src dst 62.65.145.30:80 -> 10.1.2.3:65000 It is now filtered outgoing on $lanif. Outgoing packets cause a state lookup with src = lan AND dst = ext (replacing src with gwy, if different) This does not match your state entry, both conditions are false. The ruleset is evaluated. The last matching rule is 'block in log all'. Packet dropped. Handshake fails. So, even a floating state does not allow packets related to a connection to pass through all interfaces in arbitrary directions. And translation is applied whenever a packet does match a state. It's unlikely that the same packet, after translation, will match the same state on another interface again. Daniel