PF on the bridge

hello!
I'm having some problems setting up PF filtering on my bridged interfaces. Basically i have 2 network cards - int_if (connected to my LAN) and ext_if (for wan). i also managed to set up routed vpn server on this machine (interface tun0). Now what i'm struggling with is simple understanding how does the filtering work on the bridge at all - which traffic is IN and OUT for individual interfaces, does PF automatically filter tun0, bridge0 etc? I'm sorry if the question is silly but i'm really confused and could use some help!
 
Incoming is always from a NIC to the kernel, outgoing is always from the kernel to a NIC.

So on your $int_if, traffic to your LAN is outbound, traffic from your LAN is inbound. On your $ext_if, traffic from the WAN/Internet is inbound, traffic to the WAN/Internet is outbound. More general: traffic to the server (from any direction) is inbound, traffic from the server (in any direction) is outbound.

'Automatic filtering' does not exist, but if you start with a block rule and add pass rules for specific interfaces and traffic flows later, you will have to configure each and every interface in pf.conf, or at least add a skip rule for an interface (usually for lo0) to exclude it from the default block rule.

pf.conf(5) is your friend.
 
Are you routing between those networks or did you create an if_bridge(4) between them?

Traffic direction is always viewed from the port side, i.e. how the port sees the packet. From it means out (egress), to it means in (ingress).

Now the question is what are you trying to achieve exactly?
 
Matoatlantis - i created a bridge on two interfaces (ext and int) and placed the freebsd box between the router and my internal network. The idea is that the box will act as a firewall filtering all the traffic going in and out (i didn't want to configure another subnet for NAT that is why I choose to use bridge)also as a vpn server and perhaps ,if everything works well, some day I'll add SNORT, Squid and some other things. I managed to install and get openvpn working for the routed vpn. Now i've been struggling a bit with setting up pf filtering properly. Example question (among many others i will have to find the answer to ) is - how does the int_if see the vpn traffic originating from tun0? is it in/out ? Please don't get me wrong - i guess most of the people would simply keep trying until they got the correct set up but i'd like to know "why/how" first so I could avoid any major mistakes.

regards
 
Traffic coming in from the tun0 interface isn't treated any differently to other traffic that enters the system. If the traffic is destined to a host on the network connected to int_if the traffic will be flowing out via the int_if interface.
 
You can filter traffic on either interface - physical or virtual. Personally, I prefer the following: filter all incoming traffic on $ext_if. If needed, filter unwanted LAN traffic on $int_if too.

I'm not quite sure if I understand your goal and network topology though; I would expect bridge to join two separate segments of the same network (due to transparent firewall for example).

As @kpa stated, tun is treated as any other interface - you can apply filtering to it as such.
 
Guys, thank you for your comments, all are appreciated! I'm sorry but I've been very busy for the last few days with some other things, I'll try to post more info during the weekend. The freebsd machine is going to be placed between the broadband router and the internal network. The router i have is fairly good so i don't want to completely replace it with freebsd box.
 
Code:
lo0
                     \
LAN <------->eth1__________eth0<--------->Router<-------->WAN                                                              
                   \    \                                                                           
              bridge0   tun0                                                     

eth0 - 10.0.0.2
eth1 - 10.0.0.3
Router - 10.0.0.1 
LAN - 10.0.0.0 
tun0 subnet -172.16.5.0/24
Right so first thing - this is a second bb line dedicated for the vpn only so no traffic originting from the lan side.
As I wrote before I couldn't completely replace the adsl router with the freebsd box so I did set up a bridge between eth0 and eth1 and placed the box between the router and LAN. Then I configured routed ovpn and all worked well with pf disabled. At first i used very simple ruleset :

Code:
set skip on lo0
set skip on bridge0
set skip on tun0
scrub in all
block in log
pass in quick on $ext_if inet proto udp from any to 10.0.0.2 port 1194
pass out quick on $int_if inet proto tcp from 172.16.5.0/24 to any
Then I established a vpn connection but i couldn't access any machines in my lan
Trying to access my internal web server i got these entries in the log:
Code:
0/0(match): block in on eth1: 10.0.0.11.80 > 172.16.5.6.4639

so it looked like i would also have to open in connections to tun0 on coresponding ports on eth1? Later on I replaced the last line with:

Code:
pass out quick on $int_if inet proto tcp from any to any

and it still didn't work. So i finally tried just simple pass out quick after block in entry and that worked but i'm not sure why...
So now i'm thinking - if i move filtering of the vpn traffic to Tun0(block in pass out only selected traffic) and allow all tun0<->lan traffic on int_if will it work?
 
right...so i guess i'm stuck with
Code:
pass out all
so far no matter what i try i always find traffic returning to my 172.16.5.client blocked on eth1. it works only after
Code:
 pass out all
any suggestions pretty please?
 
Try
Code:
pass out all
in PF and then
Code:
tcpdump
in console on your freebsd router. After that comment out your rule
Code:
 pass out all
and start
Code:
tcpdump
again.
 
ok so I think I finally figured it out.
At first i changed
Code:
block in log
to
Code:
block log all
and after that i started seeing log entries indicating that the out traffic from vpn clients to LAN was always blocked on $ext_if- so at first i was like wtf? I tried netstat -r and noticed that all the traffic to the local LAN was to go through eth0 first? :
Code:
10.0.0.0/8         link#1             U           0   603200   eth0
so i'm guessing that was the reason why it worked with
Code:
pass out all

so i tried :
Code:
pass in quick on $ext_if inet proto udp from any to 10.0.0.2 port 1194
pass out quick on $ext_if inet proto tcp from 172.16.5.0/24 to 10.0.0.11 port 80
pass out quick on $int_if inet proto tcp from 172.16.5.0/24 to 10.0.0.11 port 80
block log all

This time it worked so i added a static route to 10.0.0.0/24 through eth1 and removed:
Code:
pass out quick on $ext_if inet proto tcp from 172.16.5.0/24 to 10.0.0.11 port 80
Now it's working fine.

Thanks for your help, tcpdump did help indeed.
I still don't understand though why initially i got log entries telling me the returning in traffic from 10.0.0.0->172.16.5. was blocked and not a single word about eth0?
 
Back
Top