From owner-freebsd-questions@FreeBSD.ORG Fri Oct 31 17:04:12 2008 Return-Path: Delivered-To: freebsd-questions@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id DB79A106567A for ; Fri, 31 Oct 2008 17:04:12 +0000 (UTC) (envelope-from jdc@koitsu.dyndns.org) Received: from QMTA04.emeryville.ca.mail.comcast.net (qmta04.emeryville.ca.mail.comcast.net [76.96.30.40]) by mx1.freebsd.org (Postfix) with ESMTP id BA2C98FC08 for ; Fri, 31 Oct 2008 17:04:12 +0000 (UTC) (envelope-from jdc@koitsu.dyndns.org) Received: from OMTA03.emeryville.ca.mail.comcast.net ([76.96.30.27]) by QMTA04.emeryville.ca.mail.comcast.net with comcast id ZV3g1a0030b6N64A4V4B3S; Fri, 31 Oct 2008 17:04:11 +0000 Received: from koitsu.dyndns.org ([69.181.141.110]) by OMTA03.emeryville.ca.mail.comcast.net with comcast id ZV3l1a01z2P6wsM8PV3oUG; Fri, 31 Oct 2008 17:03:52 +0000 X-Authority-Analysis: v=1.0 c=1 a=6I5d2MoRAAAA:8 a=QycZ5dHgAAAA:8 a=8iwDuBYC723A0YfXIOIA:9 a=7ej-7wswwcpKf2MdIwuwbEuGu3sA:4 a=EoioJ0NPDVgA:10 a=SV7veod9ZcQA:10 a=LY0hPdMaydYA:10 Received: by icarus.home.lan (Postfix, from userid 1000) id D9890C9419; Fri, 31 Oct 2008 10:03:45 -0700 (PDT) Date: Fri, 31 Oct 2008 10:03:45 -0700 From: Jeremy Chadwick To: Lowell Gilbert Message-ID: <20081031170345.GA36712@icarus.home.lan> References: <367168.61424.qm@web56806.mail.re3.yahoo.com> <490A4487.8020101@gmail.com> <20081030233933.GB16747@icarus.home.lan> <448ws4da2f.fsf@be-well.ilk.org> <20081031160949.GA36045@icarus.home.lan> <444p2sd8od.fsf@be-well.ilk.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <444p2sd8od.fsf@be-well.ilk.org> User-Agent: Mutt/1.5.18 (2008-05-17) Cc: Jack Barnett , Freebsd questions , mdh_lists@yahoo.com Subject: Re: Firewalls in FreeBSD? X-BeenThere: freebsd-questions@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: User questions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 31 Oct 2008 17:04:12 -0000 On Fri, Oct 31, 2008 at 12:35:30PM -0400, Lowell Gilbert wrote: > Jeremy Chadwick writes: > > > On Fri, Oct 31, 2008 at 12:05:28PM -0400, Lowell Gilbert wrote: > >> Jeremy Chadwick writes: > >> > >> > On Thu, Oct 30, 2008 at 06:34:31PM -0500, Jack Barnett wrote: > >> >> > >> >> Ok, I had some progress with this last night. Basically what I do is: > >> >> > >> >> in natd - redirect_port 1000 to 10000 to the internal windows box. > >> >> set ipfw to "open" file wall. > >> >> > >> >> Obviously this isn't prefect - but gives some idea of what's going on. > >> >> > >> >> What I'd like to do, is a) keep the nat redirects since that works > >> >> pretty well. > >> >> b) in ipfw, ONLY allow data back on these ports IF the windows box has > >> >> established the connection out first then deny everything else. > >> > > >> > This is called "port triggering" in the residential router world. I > >> > don't know how to do this on FreeBSD. > >> > >> Stateful rules are the only way to do it. > >> In fact, this is the main purpose of stateful rules. > > > > Read this part of the thread, where I outline protocol flow (based on > > what the OP has stated about the protocol, which so far appears to be > > accurate): > > > > http://lists.freebsd.org/pipermail/freebsd-questions/2008-October/thread.html > > > > Stateful rules will not solve this problem. > > > > The OP wants a feature that tells ipfw or pf "after the TCP handshake > > has completed, dynamically add a port forward for port X on interface Y > > to machine A on port Z; when the TCP session is FIN'd cleanly, or > > extinguishes, dynamically remove that port forward". > > Okay, I guess I'm a little confused by the line about "ONLY allow data > back on these ports IF the windows box has established the connection > out first then deny everything else." I read that as saying that the > Windows box had sent a packet on the same connection (4-tuple, at > least) that should be later accepted heading *to* the Windows box. > That's just a stateful rule, and it seems to be at odds with what you > wrote in your first message in the thread. The apparent disagreement > was why I said anything in the first place; it sounds like there's > more than one model of how the game works. I understand the confusion. Here's the actual protocol that the game appears to be using (since the OP has stated forwarding a port range to his LAN PC solves the problem -- meaning, his original description of how the game protocol worked is accurate): windows = 192.168.x.x machine on the LAN natgwlan = private LAN-facing IP of FreeBSD box (e.g. gateway IP) natgwwan = public Internet-facing IP of FreeBSD box gameserver = game server (public Internet IP) * = randomly-allocated port number gameport = some static port # for the game (OP hasn't disclosed this) range = some specific range of port numbers (OP says 1000-10000) This is what would happen if the windows machine was on the Internet directly (no NAT, no firewall): Step 1) windows:* --> gameserver:gameport Step 2) gameserver:* --> windows:range Note that the randomly-allocated port number is *not* identical between all of the above steps; literally each is a new port and unrelated to the previous -- hence why state tracking won't work. Now with NAT in the way, this is what happens for Step 1: windows:* <--> natgwlan natgwwan:* <--> gameserver:gameport Once the TCP handshake is completed for Step 1, the following happens as a result of Step 2 -- again, note this is a *brand new connection* being initiated from the gameserver: gameserver:* <--> natgwwan:range The problem is that these are all brand new connections being initiated, and there's no way to cross-reference them, which is why state tracking won't work to solve the OPs problem. The "port triggering" method I described above, commonly available on residential routers, is configured so that once the TCP handshake is completed in Step 1, the router/natgw *immediately* adds a port forward and firewall allow/pass rule (you have to configure it to say what port range to forward, and what LAN IP to forward the packets to). Thus, the following would happen immediately after the TCP handshake was completed in Step 1: - natgw adds a firewall pass rule for natgwwan:range - natgw adds a forwarding rule for natgwwan:1000 --> windows, where the port number matches (e.g. natgwwan:1000 --> windows:1000) This pass/allow rule and the forward remains intact until the "port triggered" connection is severed (FIN or expired). It does not expire/close based upon the connection made in Step 1. This would allow Step to work, and would look like this with NAT in the way: gameserver:* <--> natgwwan:range natgwlan --> windows:range This is as verbose as I can get, and based upon the forwarding and the firewall rules the OP added, this does appear to be the protocol the game uses. And yes, this is a *horrible* protocol, completely NAT- unfriendly. The only part that confuses me is how the gameserver knows what port number (e.g. "range") to connect to on natgwwan; I assume this port number is somehow negotiated during Step 1, so that gameserver knows to connect to windows:1000, windows:1578, windows:9739, etc.... you get the point. -- | Jeremy Chadwick jdc at parodius.com | | Parodius Networking http://www.parodius.com/ | | UNIX Systems Administrator Mountain View, CA, USA | | Making life hard for others since 1977. PGP: 4BD6C0CB |