Subject: kern/18517: ipf 3.4.27 does not do nat properly on return-rst packets
To: None <gnats-bugs@gnats.netbsd.org>
From: None <kivinen@ssh.fi>
List: netbsd-bugs
Date: 10/03/2002 02:37:20
>Number:         18517
>Category:       kern
>Synopsis:       ipf 3.4.27 does not do nat properly on return-rst packets
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Wed Oct 02 16:38:00 PDT 2002
>Closed-Date:
>Last-Modified:
>Originator:     Tero Kivinen
>Release:        NetBSD 1.6
>Organization:
SSH Communications Security
>Environment:
System: NetBSD fireball.acr.fi 1.6 NetBSD 1.6 (FIREBALL) #0: Wed Oct 2 15:13:02 EEST 2002 tk@fireball.acr.fi:/usr/src/sys/arch/i386/compile/FIREBALL i386
Architecture: i386
Machine: i386
>Description:

	I have a combined NAT and firewall box that will have static
	NAT for some addresses behind the box. Those boxes only allow
	very limited amount of connections, i.e only ssh. The ipf is
	configured to block and send tcp reset to other connections.
	This tcp reset is sent, but it is sent with the NAT'ed source
	address, and because of that it does not reach the other, end
	causing the other end to see only black hole instead of
	connections being tcp reseted. 

>How-To-Repeat:

ipnat.conf:
----------------------------------------------------------------------
...
bimap fxp0 192.168.2.2/32 -> 212.226.138.157/32
...
----------------------------------------------------------------------

ipf.conf:
----------------------------------------------------------------------
block in log on fxp0 all head 100
...
block in log proto tcp from any to 192.168.2.2/32 flags S/SA head 120 group 100
...
pass in log first quick proto tcp from any to any port = 22 keep state group 120
...
block return-rst in log proto tcp from any to any flags S/SA group 100
...
----------------------------------------------------------------------

	Then I try to connect from 212.16.100.3 to 212.226.138.157
	port 25:
----------------------------------------------------------------------
edelleen (1:59) ~#tcpdump -n -i fxp0 -e -vv -x -X host haste.acr.fi and port not 22
tcpdump: listening on fxp0
01:59:43.698473 0:d0:b7:21:b8:9f 0:30:b6:6a:c8:0 0800 74: 212.16.100.3.54244 > 212.226.138.157.25: S [tcp sum ok] 2282219024:2282219024(0) win 16384 <mss 1460,nop,wscale 0,nop,nop,timestamp 0 0> (ttl 64, id 32647, len 60)
0x0000   4500 003c 7f87 0000 4006 63a1 d410 6403        E..<....@.c...d.
0x0010   d4e2 8a9d d3e4 0019 8807 e610 0000 0000        ................
0x0020   a002 4000 315e 0000 0204 05b4 0103 0300        ..@.1^..........
0x0030   0101 080a 0000 0000 0000 0000                  ............
^C
126 packets received by filter
0 packets dropped by kernel
edelleen (2:01) ~#
----------------------------------------------------------------------
edelleen (1:59) ~>telnet haste.acr.fi smtp
Trying 212.226.138.157...
^C
----------------------------------------------------------------------

	The packet is received by the firewall and the tcp reset is
	sent back:
----------------------------------------------------------------------
fireball (1:58) ~#tcpdump -i fxp0 -n -e -vv -x -X host 212.16.100.3 and port not 22
tcpdump: listening on fxp0
01:58:58.369302 0:4:9a:86:f3:d6 0:90:27:2d:8e:58 0800 74: 212.16.100.3.54244 > 212.226.138.157.25: S [tcp sum ok] 2282219024:2282219024(0) win 16384 <mss 1460,nop,wscale 0,nop,nop,timestamp 0 0> (ttl 57, id 32647, len 60)
0x0000   4500 003c 7f87 0000 3906 6aa1 d410 6403        E..<....9.j...d.
0x0010   d4e2 8a9d d3e4 0019 8807 e610 0000 0000        ................
0x0020   a002 4000 315e 0000 0204 05b4 0103 0300        ..@.1^..........
0x0030   0101 080a 0000 0000 0000 0000                  ............
01:58:58.369399 0:90:27:2d:8e:58 0:4:9a:86:f3:d6 0800 54: 192.168.2.2.25 > 212.16.100.3.54244: R [tcp sum ok] 0:0(0) ack 2282219025 win 0 (ttl 64, id 34687, len 40)
0x0000   4500 0028 877f 0000 4006 f892 c0a8 0202        E..(....@.......
0x0010   d410 6403 0019 d3e4 0000 0000 8807 e611        ..d.............
0x0020   5014 0000 72fb 0000                            P...r...
^C
1009 packets received by filter
0 packets dropped by kernel
fireball (2:01) ~# 
----------------------------------------------------------------------

	As you can see from the log the return rst has the source
	address of the tcp reset packet is 192.168.2.2 instead of
	212.226.138.157 as it should be.

	From the syslog we can se that this is really rejected by the
	proper rule:
----------------------------------------------------------------------
Oct  3 01:58:58 fireball ipmon[116]: 01:58:58.369368 fxp0 @100:14 b 212.16.100.3,54244 -> 192.168.2.2,25 PR tcp len 20 60 -S IN 
----------------------------------------------------------------------
fireball (2:20) ~#ipfstat -i -n | grep 'group 100' | grep 14
@14 block return-rst in log proto tcp from any to any flags S/SA group 100
fireball (2:20) ~#
----------------------------------------------------------------------

	It would be actually very usefull to have the ipfstat -n to
	print out the numbers in the same format ipmon prints them,
	i.e @100:14. 

>Fix:

	Perhaps the ip_fil.c:send_reset should set the fin->fin_out to
	0 to force the nat processing again in ipfr_fastroute. As the
	code is little bit complex, not sure that is the proper fix...
>Release-Note:
>Audit-Trail:
>Unformatted: