[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Passing RDR outside of RDR rule



Rule question:

http://www.openbsd.org/faq/pf/rdr.html

"NOTE: Translated packets must still pass through the filter engine and
will be blocked or passed based on the filter rules that have been defined.


"The only exception to this rule is when the pass keyword is used within the
rdr rule. In this case, the redirected packets will pass statefully right
through the filtering engine: the filter rules won't be evaluated against
these packets.


To this point, this is what I've been doing: using "pass" on my rdr rules.

	lan  = "le0"
	wlan = "le2"
	INT = "192.168.1.0/24"
	ext  = "le1"
	fwd_lan_port = 999
	fwd_lan_dest_ip = 192.168.1.9
	fwd_lan_dest_port = 8888

	nat on $ext from $INT to any -> $ext
	rdr pass on $ext inet proto tcp \
		to port $fwd_lan_port -> $fwd_lan_dest_ip port $fwd_lan_dest_port


"...However, if you want to enable more specific filtering options such
as synproxy, modulate state, etc. you'll still have to use a dedicate pass
rule as these options don't fit into redirection rules.


Which is what I now want to do...

"Also be aware that since translation occurs before filtering, the filter
engine will see the translated packet as it looks after it's had its
destination IP address and/or destination port changed to match the
redirection address/port specified in the rdr rule.


But I'm having trouble writing such a rule.

With my "pass" rdr rule, all traffic being redirected matches the following rule:

pass out log-all quick on $lan from any to any keep state

as it passes in to the internal network. Everything works just fine. I can see the traffic on the internal interface, and I actually connect to the internal machine. But I want more options on the rule that allows traffic to pass, so I remove the "pass" on the rdr rule:

	rdr on $ext inet proto tcp \
		to port $fwd_lan_port -> $fwd_lan_dest_ip port $fwd_lan_dest_port

And attempt to write a simple rule that will do exactly the same thing. Understanding that the traffic will be translated BEFORE any rules are applied, I figure this inbound traffic will change from:

	dest IP = IP-of-OBSD box
	dest-port = $fwd_lan_port

to:

	dest IP = $fwd_lan_dest_ip
	dest-port = $fwd_lan_dest_port

So I write the rule:

	pass in log-all quick on $ext inet proto tcp from any to \
		$fwd_lan_dest_ip port $fwd_lan_dest_port

Which shows up in pfctl -gs rules as:

@26 pass in log-all quick on le1 inet proto tcp from any to 192.168.1.9 port = 8888

And I attempt the connection. Unfortunately, the inbound traffic misses rule @26 above,
and makes it all the way to:


@54 block drop in log-all quick on le1 all

Which blocks it in on le1, showing the external interface's IP, and

rule 54/0(match): block in on le1: [remote].63309 > [ext_if_ip].999: S ..

Okay, so the packet is actually NOT being modified before it hits the PF rules.

Scrap the rule I wrote, and change it to:

	pass in log-all quick on $ext inet proto tcp from any \
		to port $fwd_lan_port keep state

which resolves to:

@26 pass in log-all quick on le1 inet proto tcp from any to any port = 999 keep state

Watching pflog0:

rule 26/0(match): pass in on le1: [remote].63312 > [ext_if_ip].999: S 2386147166:
2386147166(0) win 65535 <mss 1452,nop,wscale 0,[|tcp]> (ttl 50, id 39864,
bad cksum 3217! differs by 4000)
rule 26/0(match): pass out on le1: [ext_if_ip].999 > [remote].63312: R
[tcp sum ok] 0:0(0) ack 2386147167 win 0 (ttl 64, id 32973)


I get a "connection refused" on the machine on the outside when I attempt to connect, and no traffic ever shows up on the internal interface. No block rules are hit. The connection is simply dropped.

Any thoughts as to what I'm doing wrong?


Thanks, JMF