• We’re currently investigating an issue related to the forum theme and styling that is impacting page layout and visual formatting. The problem has been identified, and we are actively working on a resolution. There is no impact to user data or functionality, this is strictly a front-end display issue. We’ll post an update once the fix has been deployed. Thanks for your patience while we get this sorted.

OpenBSD PF's... pass rules and redirection

xyyz

Diamond Member
i'm working on my config and i came across the redirect which has me confused.

i thought that pass rules were all that were needed.

for example, i'm allowing telnet access to an access server with the following:


### cisco pod network access
pass in log on $int_if from $hosts proto tcp to $access_server port telnet keep state flags S/SA keep state
pass in log on $ext_if from any proto tcp to $access_server port telnet keep state flags S/SA keep state

while this might seem redundant, i just want to make teh rules as granular as possible.

anyways, do i also have to have a redirect statement to tell the external interface to move the packets that are destined to the telnet port of the access server... or are teh pass rules good enough?

which means do i have to have the following instead:

### cisco pod network access
rdr on $ext_if proto tcp from $router to $ext_ip port 23 -> $access_server
pass in log on $int_if from $hosts proto tcp to $access_server port telnet keep state flags S/SA keep state
pass in log on $ext_if from any proto tcp to $access_server port telnet keep state flags S/SA keep state
 
hmmm... i have a NAT... :/

i guess i'll remove the hashes and see what happens... as it stands nothing is working.
 
Originally posted by: xyyz
hmmm... i have a NAT... :/

i guess i'll remove the hashes and see what happens... as it stands nothing is working.

With NAT, the rdr rules basically tell the system that anyone coming in on $EXT_IF to $EXT_IF port 23, push the packet to the internal machine. Without the rdr, the packets will stop at $EXT_IF and either connect to a telnet daemon there, or be rejected. This explanation probably sucks, but it's the best I can do at the moment 😛
 
damn this thing is still not working... and i'm really hesitant to post on the openbsd newsgroup.
 
Here are the rules I use to pass BitTorrent traffic through the NAT to my desktop...

rdr on $ext proto tcp from any to $natip port 6881:6889 -> $desktop
pass in on $ext proto tcp from any to $desktop port 6880><6890 flags S/SAFR keep state


$natip is the IP my NAT'ed machines masquerade as. In my case, that's not the same as the external interface's IP, but it generally would be. The notable bit is that you write your pass rules to apply after the redirect has taken place.

I'm assuming you've turned on ip forwarding in /etc/sysctl.conf.
 
here... let's post the latest installment of what i've been working with:

###################################
# $OpenBSD: pf.conf 11/9/2003
###################################

#####################################
### macros
#####################################

### IP addresses
ext_ip = "10.10.190.2" # external interface ip address
int_ip = "192.168.175.253" # internal interface ip address
pub_ip = "172.16.210.1" # public servers interface ip address
pvt_ip = "192.168.50.1" # private servers interface ip address
pod_ip = "172.16.150.1" # cisco router pod interface ip address

### physical interfaces
int_if = "hme0" # internal interface
pvt_srv_if = "hme1" # private server interface
pub_svr_if = "hme2" # public server interface
cisco_pod_if = "hme3" # router lab interface
ext_if = "hme4" # external interface
all_if = "{ hme0, hme1, hme2, hme3, hme4}" # all interfaces

### servers
web_server = "172.16.210.2" # webserver
PDC = "192.168.50.2" # primary domain server
router = "10.10.190.1" # router
access_server = "172.16.150.2" # cisco pod access server
print_server = "192.168.175.251" # print server
proxy_server = " 192.168.175.248" # proxy server

### internal network hosts
venus = "192.168.175.242" #
saturn = "192.168.175.243" #
mercury = "192.168.175.249" # laptop
uranus = "192.168.175.248" # backup server
neptune = "192.168.175.253" # OpenBSD
hosts = "{" $venus $saturn $mercury $uranus "}"

### Services
www = "{ 80, 443}" # http/https

### Private addresses
spoof_ips= "{ 127.0.0.0/8, 192.168.0.0/16, 172.16.0.0/12, 10.0.0.0/8 }" # private addresses

##################################################################
### Options: tune the behavior of pf
##################################################################

### Sets the interface for which PF should gather statistics such as bytes in/out and packets passed/blocked
### Optimize PF for one of the following network environments
### packet is silently dropped

set loginterface hme4

##########################
#Packet Filtering Table
##########################

### Clean up fragmented packets and abnormal packets
scrub in all fragment reassemble

### nat rule
nat on $ext_if from $hosts to any -> $ext_ip
rdr on $ext_if proto tcp from $router to $ext_ip port 23 -> $access_server
rdr on $ext_if proto tcp from $router to $ext_ip port $www -> $web_server

###
# traffic rules #
###

# default deny policy
block in all
block out all

### pass traffic on the loopback interface in either direction
pass in on lo0 from $all_if to any modulate state

### activate spoofing protection for the internal interface
# block in log quick on $ext_if from $spoof_ips to any
# block out log quick on $ext_if from any to $spoof_ips
antispoof for $ext_if inet

### allow ssh connections in on the external interface as long as they're NOT destined for the firewall (ie, they're
### destined for a machine on the local network). log the initial packet so that we can later tell who is trying to connect.
pass in log on $ext_if proto tcp from any to { $uranus, !$ext_ip, !$int_if } port ssh flags S/SA synproxy state

###
### core ruleset
###

### pass tcp, udp, and icmp out on the external (Internet) interface. keep state on udp and icmp and modulate state on tcp.
pass in on $int_if from $hosts proto tcp to $ext_ip modulate state
pass in on $int_if from $hosts proto { udp, icmp } to $ext_ip keep state

### cisco pod network access
pass in log on $int_if from $hosts proto tcp to $access_server port telnet keep state flags S/SA
pass in log on $ext_if from any proto tcp to $access_server port telnet keep state flags S/SA

### private server network access
pass in on $int_if from $hosts proto tcp to $PDC keep state flags S/SA
pass in on $int_if from $hosts proto { udp, icmp } to $PDC keep state
pass in on $pvt_srv_if from $PDC proto tcp to $ext_ip keep state flags S/SA keep state
pass in on $pvt_srv_if from $PDC proto { udp, icmp } to $ext_ip keep state

### public server network access
pass in on $int_if from $hosts proto tcp to $web_server port $www keep state flags S/SA keep state
pass in on $ext_if from any proto tcp to $web_server port $www keep state flags S/SA keep state

btw... this doesn't work.

the output from tcpdump is totally unremarkable... it just loops the same stuff over and over.
 
This is what I have, although I can't tell you if it works or not at the moment (if I don't edit this, you can PM me and we can test it):
rdr on $EXT_IF proto tcp from any to ($EXT_IF) port 80 -> 192.168.130.15 port 8
0
rdr on $EXT_IF proto tcp from any to ($EXT_IF) port 22 -> 192.168.130.15 port 22

rdr on $EXT_IF proto tcp from any to ($EXT_IF) port 443 -> 192.168.130.15 port 4
43


Maybe if you tried something along the lines of:
rdr on $ext_if proto tcp from $router to $ext_if port 23 -> $access_server port 23
rdr on $ext_if proto tcp from $router to $ext_if port $www ->$web_server port $www

EDIT: I made a few adjustments and got it to work on my ruleset. The rdrs were fine, but my pass rule was not. I had to do something like:

pass in on $EXT_IF inet proto tcp from any to any port 80

Then it worked fine.
 
Did you say you were using a VPN or something, xyyz? That would be the only reason to use "from $router" in those lines - the source address of a packet is the original source, not the address of the routers that carry it to you.
 
i will be using a VPN later...

but as it stands the openbsd firewall is behind a router.

(internet)------router------firewall------(lan)

from looking at the example, i replaced "from any" with from router, because only the router (at the moment at least, before the VPN is brought in) will connect to the external interface of the firewall.
 
oh this might help... here's the output from tcpdump. it didn't make any sense to me... but you guys might be able to figure it out

Dec 21 07:48:51.789877 802.1d config root=8000.0:e0:29:72:14:50 rootcost=0x0 bridge=8000.0:e0:29:72:14:50 port=0x8003 age=0/0 max=20/0 hello=2/0 fwdelay=15/0
Dec 21 07:48:53.788044 802.1d config root=8000.0:e0:29:72:14:50 rootcost=0x0 bridge=8000.0:e0:29:72:14:50 port=0x8003 age=0/0 max=20/0 hello=2/0 fwdelay=15/0
Dec 21 07:48:55.786211 802.1d config root=8000.0:e0:29:72:14:50 rootcost=0x0 bridge=8000.0:e0:29:72:14:50 port=0x8003 age=0/0 max=20/0 hello=2/0 fwdelay=15/0
Dec 21 07:48:57.784373 802.1d config root=8000.0:e0:29:72:14:50 rootcost=0x0 bridge=8000.0:e0:29:72:14:50 port=0x8003 age=0/0 max=20/0 hello=2/0 fwdelay=15/0
Dec 21 07:48:59.782541 802.1d config root=8000.0:e0:29:72:14:50 rootcost=0x0 bridge=8000.0:e0:29:72:14:50 port=0x8003 age=0/0 max=20/0 hello=2/0 fwdelay=15/0
Dec 21 07:49:01.780709 802.1d config root=8000.0:e0:29:72:14:50 rootcost=0x0 bridge=8000.0:e0:29:72:14:50 port=0x8003 age=0/0 max=20/0 hello=2/0 fwdelay=15/0
Dec 21 07:49:03.778872 802.1d config root=8000.0:e0:29:72:14:50 rootcost=0x0 bridge=8000.0:e0:29:72:14:50 port=0x8003 age=0/0 max=20/0 hello=2/0 fwdelay=15/0
Dec 21 07:49:05.777040 802.1d config root=8000.0:e0:29:72:14:50 rootcost=0x0 bridge=8000.0:e0:29:72:14:50 port=0x8003 age=0/0 max=20/0 hello=2/0 fwdelay=15/0
Dec 21 07:49:07.775203 802.1d config root=8000.0:e0:29:72:14:50 rootcost=0x0 bridge=8000.0:e0:29:72:14:50 port=0x8003 age=0/0 max=20/0 hello=2/0 fwdelay=15/0
Dec 21 07:49:09.773374 802.1d config root=8000.0:e0:29:72:14:50 rootcost=0x0 bridge=8000.0:e0:29:72:14:50 port=0x8003 age=0/0 max=20/0 hello=2/0 fwdelay=15/0
Dec 21 07:49:11.771536 802.1d config root=8000.0:e0:29:72:14:50 rootcost=0x0 bridge=8000.0:e0:29:72:14:50 port=0x8003 age=0/0 max=20/0 hello=2/0 fwdelay=15/0
Dec 21 07:49:13.769697 802.1d config root=8000.0:e0:29:72:14:50 rootcost=0x0 bridge=8000.0:e0:29:72:14:50 port=0x8003 age=0/0 max=20/0 hello=2/0 fwdelay=15/0
Dec 21 07:49:15.767868 802.1d config root=8000.0:e0:29:72:14:50 rootcost=0x0 bridge=8000.0:e0:29:72:14:50 port=0x8003 age=0/0 max=20/0 hello=2/0 fwdelay=15/0
Dec 21 07:49:17.766032 802.1d config root=8000.0:e0:29:72:14:50 rootcost=0x0 bridge=8000.0:e0:29:72:14:50 port=0x8003 age=0/0 max=20/0 hello=2/0 fwdelay=15/0
Dec 21 07:49:19.764199 802.1d config root=8000.0:e0:29:72:14:50 rootcost=0x0 bridge=8000.0:e0:29:72:14:50 port=0x8003 age=0/0 max=20/0 hello=2/0 fwdelay=15/0
 
this is probably worth mentioning too... here's the diagram

(internet)
||
||
||
router
||
||
||
firewall
||
||
||
--------(lan)
--------(network 2)
--------(network 3)
--------(network 4)
--------(network 5)

the networks are vlan'd, with the openbsd firewall doing the vlan routing.
 
Try a "from any" and see if that works. Eliminate possibilities... It's kind of like nuking them from orbit, it's the only way to be sure.
 
hmmm you know what... i figured that the problem might be at the internal interface and not the router pod interface.

so i did a tcpdump on hme0, and this is what i found:

Dec 23 04:06:29.145496 192.168.175.243.3210 > 172.16.100.2.telnet: S [tcp sum ok] 108911307:108911307(0) win 65520 <mss 1260,nop,nop,sackOK> (DF) (ttl 127, id 52212)
Dec 23 04:06:29.247837 802.1d config root=8000.0:e0:29:72:14:50 rootcost=0x0 bridge=8000.0:e0:29:72:14:50 port=0x800d age=0/0 max=20/0 hello=2/0 fwdelay=15/0

unfortunately, it makes no sense to me... any one know what it means?


 
Originally posted by: n0cmonkey
Try a "from any" and see if that works. Eliminate possibilities... It's kind of like nuking them from orbit, it's the only way to be sure.

grrrr.... this was the last thing i wanted to do... but relucatantly i'll do it.

so right now my rule's are "pass in all" and "pass out all"

well... the good news is that now i can telnet to my server from the opbsd box... but the badnews is that the friggin workstation cannot telnet to it.

here's the tcpdump output:

07:24:36.128654 192.168.175.243.3727 > 172.16.150.2.telnet: S [tcp sum ok] 3103999837:3103999837(0) win 65520 <mss 1260,nop,nop,sackOK> (DF) (ttl 127, id 30400)
07:24:36.131808 arp who-has 192.168.175.243 tell 172.16.150.2
07:24:38.144949 arp who-has 192.168.175.243 tell 172.16.150.2
07:24:39.106145 192.168.175.243.3727 > 172.16.150.2.telnet: S [tcp sum ok] 3103999837:3103999837(0) win 65520 <mss 1260,nop,nop,sackOK> (DF) (ttl 127, id 30403)
07:24:39.108198 arp who-has 192.168.175.243 tell 172.16.150.2
07:24:42.173214 arp who-has 192.168.175.243 tell 172.16.150.2
07:24:45.113908 192.168.175.243.3727 > 172.16.150.2.telnet: S [tcp sum ok] 3103999837:3103999837(0) win 65520 <mss 1260,nop,nop,sackOK> (DF) (ttl 127, id 30406)
07:24:45.115971 arp who-has 192.168.175.243 tell 172.16.150.2
07:24:50.229061 arp who-has 192.168.175.243 tell 172.16.150.2
07:25:06.341215 arp who-has 192.168.175.243 tell 172.16.150.2
07:25:06.344424 arp who-has 192.168.175.243 tell 172.16.150.2
07:25:07.347508 arp who-has 192.168.175.243 tell 172.16.150.2
07:25:08.354550 arp who-has 192.168.175.243 tell 172.16.150.2

WTF is an "arp who-has"?!?!?!?
 
Reading tcpdump output can be tough. I don't get some of what your previous dump means, but I have trouble when I don't have a lot to look at. Did you remember to turn on ip forwarding? (hint 0: sysctl. hint 1: /etc/sysctl.conf hint 2: If you need another hint, go back to linux 😉 no, if you need another hint, or for me to spell it out, just ask)

Originally posted by: xyyz
Originally posted by: n0cmonkey
Try a "from any" and see if that works. Eliminate possibilities... It's kind of like nuking them from orbit, it's the only way to be sure.

grrrr.... this was the last thing i wanted to do... but relucatantly i'll do it.

so right now my rule's are "pass in all" and "pass out all"

well... the good news is that now i can telnet to my server from the opbsd box... but the badnews is that the friggin workstation cannot telnet to it.

We have to take steps to figure out what is going wrong. We will fix things as we eliminate problems or what could have been problems. Unfortunately, it is the easiest way to find the problem and fix it 🙁

here's the tcpdump output:

07:24:36.128654 192.168.175.243.3727 > 172.16.150.2.telnet: S [tcp sum ok] 3103999837:3103999837(0) win 65520 <mss 1260,nop,nop,sackOK> (DF) (ttl 127, id 30400)
07:24:36.131808 arp who-has 192.168.175.243 tell 172.16.150.2
07:24:38.144949 arp who-has 192.168.175.243 tell 172.16.150.2
07:24:39.106145 192.168.175.243.3727 > 172.16.150.2.telnet: S [tcp sum ok] 3103999837:3103999837(0) win 65520 <mss 1260,nop,nop,sackOK> (DF) (ttl 127, id 30403)
07:24:39.108198 arp who-has 192.168.175.243 tell 172.16.150.2
07:24:42.173214 arp who-has 192.168.175.243 tell 172.16.150.2
07:24:45.113908 192.168.175.243.3727 > 172.16.150.2.telnet: S [tcp sum ok] 3103999837:3103999837(0) win 65520 <mss 1260,nop,nop,sackOK> (DF) (ttl 127, id 30406)
07:24:45.115971 arp who-has 192.168.175.243 tell 172.16.150.2
07:24:50.229061 arp who-has 192.168.175.243 tell 172.16.150.2
07:25:06.341215 arp who-has 192.168.175.243 tell 172.16.150.2
07:25:06.344424 arp who-has 192.168.175.243 tell 172.16.150.2
07:25:07.347508 arp who-has 192.168.175.243 tell 172.16.150.2
07:25:08.354550 arp who-has 192.168.175.243 tell 172.16.150.2

WTF is an "arp who-has"?!?!?!?

It is an arp request. It can get complicated, but it is required for ethernet (and probably just tcp/ip routing in general). An arp (Addresss Request Protocol?) maps ip addresses to MAC addresses. So one machine asks the broadcast net "Yo, who has ip address 192.168.175.243? Tell 172.16.150.2!" 192.168.175.243 should respond with something like "I do, my MAC is 00:03:93:4b:27:5a." Is 192.168.175.243 your OpenBSD firewall? If it is your internal cisco thing(?) you have a routing issue. If it is your firewall, it doesn't seem to be responding to arps, which is wierd. A security thing you can do is to hardcode arp addresses (arp -s).

Hope this atleast narrows down a bit. If you have more questions on what I posted, or more information, please post it.
 
any ideas why i can ping the access server from the workstaion, but not telnet to it... while i can both ping and telnet to it from the OBSD box... especially since the only rules are: "pass in all" and "pass out all"?


 
problem solved... and it had nothing to do with PF... no please don't kick me.

it was a problem with the access point. there was no default gateway. which still confuses me. why do you need a default gateway when there will be no traffic that will originate from the access point and go outwards. all traffic will come into the access server.

anyways, i put in a default gateway... and it works... however, while it works, as you can see, conceptually, i'm on shaky ground, which i dont like.
 
Back
Top