Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 03 Oct 2002 18:14:23 -0400 (EDT)
From:      Andriy Gapon <avg@icyb.net.ua>
To:        Georg Graf <georg-ipfw@graf.priv.at>
Cc:        freebsd-ipfw@freebsd.org
Subject:   Re: Natd plus statefull connections impossible?
Message-ID:  <20021003161757.I32181-100000@edge.foundation.invalid>

next in thread | raw e-mail | index | archive | help

Georg,

I've been trying to do the same thing (or almost the same) recently and I
have found this one trick on some mailing list archive (don't remember
where and who is the author, try searching on google for "nat ipfw stateful").
After playing around for some time I have some observations/rules of thumb
that helped me to build a quite simple and much stateless set of rules
than I originally had in my mind.

1simpe/ no stateful rules before divert rules
1expanded/ if you have stateful rules that may match the same packet that
you want to go throgh natd, you must not put any keep-state, check-state
rules before divert

2/ most of the rules will be after divert(s), so always keep in mind that
all incoming traffic has addresses internal_ip<-real_world_ip and all
outgoing traffic has addresses external_interface_ip->real_world_ip.

3/ dynamic rules that were created by match of a stateful rule on a
particular interface do apply to all interfaces

4/ the only way to have a dynamic rule that matches
internal_ip<-real_world_ip packet is to put a keep-state rule on interal
interface that would match internal_ip->real_world_ip packet when it
enters a gateway host

5/ for access to a server on the internal network you can have either of:
	a. rule that allows packets from XXX to internal adderss:port
	b. (trust natd) rule that allows all packets after divert that
	   originated in real world and go to internal network
plus either of:
	a'. rule that allows packets from external_if:forwarded_port to XXX
	b'. general rule that allows all outgoing traffic from external_if


Ok, here is my simplest firewall ruleset:
(rl1 - internal_if, rl0 - external_if)

#loopback stuff
add 00100 allow ip from any to any via lo0
add 00110 deny ip from any to 127.0.0.0/8
add 00120 deny ip from 127.0.0.0/8 to any
#trust internal network
add 00125 allow all from any to any via rl1
#make sure we don't leak internal traffic out there
add 00150 deny all from any to 192.168.0.0/16 via rl0
add 00200 divert natd all from 192.168.0.0/16 to any out via rl0
#probably just paranoia
add 00250 deny all from 192.168.0.0/16 to any via rl0
#allow me to connect to gateway from outside via ssh (can not be stateful)
add 00400 allow tcp from any to me ssh in via rl0
add 00410 allow tcp from me ssh to any out via rl0
#translate incoming
add 00500 divert natd all from any to me in via rl0
#trust natd, it shouldn't translate destination address to my internal
#network unless session was initiated from there, or this a port, address
#etc forwarding
add 00510 allow ip from any to 192.168.0.0/16 in via rl0
#check dynamic rules
add 00600 check-state
#allow all outgoing traffic (this will match packets both originated in
#in internal network and here on gateway
add 01000 allow ip from me to any out via rl0 keep-state
add 01200 allow icmp from any to any
#all legitimate traffic should have matched above
add 01300 deny log logamount 30 tcp from any to any established
#don't put this garbage in logs
add 64900 deny udp from any to any 137,138,139 in recv rl0
add 64901 deny tcp from any to any 137,138,139,443,1443,27374 in recv rl0
add 65000 deny log logamount 30 ip from any to any

as you have figured out this allows all traffic established from inside as
well as traffic established from the outside and forwarded ny natd.

Here's also much more elaborate, prohibitive and paranoid ruleset. It also
illustrates the idea of keep-state rules on internal interface that
produce dynamic rules for the external interface:

(sorry, much less comments)
add 00100 allow ip from any to any via lo0
add 00110 deny ip from any to 127.0.0.0/8
add 00120 deny ip from 127.0.0.0/8 to any
add 00130 allow udp from any bootps to any bootpc
add 00131 allow udp from me bootpc to any bootps
add 00150 deny all from any to 10.0.0.0/8 via rl0
add 00151 deny all from any to 172.16.0.0/12 via rl0
add 00152 deny all from any to 192.168.0.0/16 via rl0
add 00153 deny all from any to 0.0.0.0/8 via rl0
add 00154 deny all from any to 169.254.0.0/16 via rl0
add 00155 deny all from any to 192.0.2.0/24 via rl0
add 00156 deny all from any to 224.0.0.0/4 via rl0
add 00157 deny all from any to 240.0.0.0/4 via rl0
add 00200 divert natd all from 192.168.0.0/16 to any out via rl0
add 00250 deny all from 10.0.0.0/8 to any via rl0
add 00251 deny all from 172.16.0.0/12 to any via rl0
add 00252 deny all from 192.168.0.0/16 to any via rl0
add 00253 deny all from 0.0.0.0/8 to any via rl0
add 00254 deny all from 169.254.0.0/16 to any via rl0
add 00255 deny all from 192.0.2.0/24 to any via rl0
add 00256 deny all from 224.0.0.0/4 to any via rl0
add 00257 deny all from 240.0.0.0/4 to any via rl0
add 00301 deny ip from not 192.168.1.0/24 to any in via rl1
add 00303 deny ip from any to not 192.168.1.0/24 out via rl1
add 00400 allow tcp from any to me ssh in via rl0
add 00410 allow tcp from me ssh to any out via rl0
add 00500 divert natd all from any to me in via rl0
#keep-state rules on the internal if
add 00550 allow tcp from any to not 192.168.0.0/16 in via rl1 setup
keep-state
add 00552 allow ip from any to not 192.168.0.0/16 in via rl1 keep-state
add 00553 allow all from any to any via rl1
add 00600 deny log logamount 10 ip from any to any frag
add 00900 reset log logamount 10 tcp from any to me auth in via rl0
#allow only ssh on 2222, and 49333 port connection
#to a particular internal host
add 00950 allow tcp from any to 192.168.1.12 22 in via rl0 setup
add 00951 allow tcp from me 2222 to any out via rl0 established
add 00970 allow tcp from any to 192.168.1.12 49333 in via rl0 setup
add 00971 allow tcp from me 49333 to any out via rl0 established
add 01000 deny log logamount 30 tcp from any to any established
add 01002 allow tcp from me to any out via rl0 setup keep-state
add 01103 allow udp from me to any domain via rl0 keep-state
add 01104 allow tcp from me to any domain via rl0 setup keep-state
add 01105 allow udp from me to any ntp via rl0 keep-state
add 01106 allow udp from me to any out via rl0
add 01200 allow icmp from any to any
add 64000 allow tcp from me to any out tcpflags rst
add 64900 deny udp from any to any 137,138,139 in recv rl0
add 64901 deny tcp from any to any 137,138,139,443,1443,27374 in recv rl0
add 65000 deny log logamount 30 ip from any to any

comments are welcome.
Hope this is useful for you, because both configs are actually working
for me.

-- 
Andriy Gapon
*
Hang on tightly, let go lightly.


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-ipfw" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20021003161757.I32181-100000>