On Thu, May 25, 2023 at 02:11:29AM +0200, Joel Carnat wrote:
> Hi,
> 
> I'd like confirm I understood how pf works in a mixed veb/vport/tap
> environment. I'm using OpenBSD 7.3/amd64 (if that matters).
> 
> I have a physical host that runs services (relayd, httpd...) the "classical"
> way and also provides VM using vmd. I have a couple of public IPs that are
> either affected to the host (via vportN) or to some VMs (via tapN). I'm
> doing all the IP filtering on the host's pf (because some VMs are Linux and
> I don't know iptables).
> 
> Here's a sum'up of my configuration:
>   # cat /etc/hostname.em0
>   up
>   # cat /etc/hostname.vport0
>   rdomain 0
>   inet aa.bb.cc.5 255.255.255.0
>   !route -n add -inet default aa.bb.cc.1
>   up
>   # cat /etc/hostname.vport1
>   rdomain 1
>   inet aa.bb.cc.6 255.255.255.0
>   !route -T 1 -n add -inet default aa.bb.cc.1
>   up
>   # cat /etc/hostname.tap2
>   rdomain 2
>   up
>   # cat /etc/hostname.veb0
>   add em0
>   add vport0
>   add vport1
>   add tap2
>   up
>   # cat /etc/vm.conf
>   (...)
>   switch "wan"   { interface veb0 }
>   (...)
>   vm linux {
>   (...)
>     interface tap2 {
>       rdomain 2
>       switch "wan"
>       # configure enp0s2 with aa.bb.cc.7/24
>     }
>   (...)
> 
> My initial pf configuration looked like:
>   block return log
>   pass on lo
>   pass in on vport0 proto tcp to vport0 port ssh
>   pass in on vport1 proto tcp to vport1 port { http, https }
>   pass in on tap2   proto tcp to aa.bb.cc.7 port ssh
>   pass out
> 
> This filters properly on vport0 and vport1. But nothing is filtered on tap2:
> the http service running in the VM is accessible via aa.bb.cc.7.
> 
> First question: is it expected that pf doesn't filter inbound traffic on a
> tap interface by default? Or is it specific to the fact that tap2 belongs to
> veb0?

it's because tap is part of a veb, as per the first part of the veb
manpage.

> After re-reading veb(4), I ran `ifconfig veb0 link1` and could achieve the
> wished filtering by modifying my pf configuration as such:
>   block return log
>   pass     on lo
>   pass     on em0
>   pass in  on vport0 proto tcp to vport0     port ssh
>   pass in  on vport1 proto tcp to vport1     port { http, https }
>   pass out on tap2   proto tcp to aa.bb.cc.7 port ssh
>   pass out on vport0
>   pass out on vport1
>   pass in  on tap2
> 
> Second question: is this the proper way to configure veb0 and pf or is there
> a "better" way of doing the filtering?

no, that's what link1 is for.

just note the following:

- you want to avoid pf matching a packet against the same state multiple
times. this means you want to avoid pf running a packet in the
same direction in the same rdomain.

- pf running on ports in a veb (except vports) uses the rdomain from the
veb interface, it ignores the rdomain on ports (except vport).

- if veb can't find a single outgoing interface for a packet, it will run it
through pf on veb. ie, broadcast, multicast, and unknown unicast can be
matched in pf with "pass out on veb0" because those packets will be
flooded to all ports.

so avoid having vports and vebs in the same rdomain is my advice.

Reply via email to