Important distinction to make here, is that the destination or the source address range? And do you need this for incoming or outgoing traffic?How should the rule be to pass all outgoing traffic in the ip range 192.168.1.1 to 192.168.1.254.
pass out from 192.168.1.0/24 to any
pass out from any to 192.168.1.0/24
table <clients> persist { 192.168.1.0/24, !192.168.1.9}
pass inet proto tcp from <clients> to any
A network packet doesn't have that information, so how is PF going to determine which user sent it? Now you can filter on user but this requires the process (and the user) to be on the same machine as PF. I don't think anybody uses that functionality though. If you want to limit what users can access you should look into setting up proxy (with authentication). That works really good for web traffic, it's a little tricky for other protocols.Is it possible to restrict by user?
Yes, the user, the process and the PF are all on the same machine. I have that requirement. How should the PF rule be now? I triedNow you can filter on user but this requires the process (and the user) to be on the same machine as PF. I don't think anybody uses that functionality though.
user ⟨user⟩
This rule only applies to packets of sockets owned by the specified
user. For outgoing connections initiated from the firewall, this
is the user that opened the connection. For incoming connections
to the firewall itself, this is the user that listens on the
destination port. For forwarded connections, where the firewall is
not a connection endpoint, the user and group are unknown.
All packets, both outgoing and incoming, of one connection are
associated with the same user and group. Only TCP and UDP packets
can be associated with users; for other protocols these parameters
are ignored.
User and group refer to the effective (as opposed to the real) IDs,
in case the socket is created by a setuid/setgid process. User and
group IDs are stored when a socket is created; when a process
creates a listening socket as root (for instance, by binding to a
privileged port) and subsequently changes to another user ID (to
drop privileges), the credentials will remain root.
User and group IDs can be specified as either numbers or names.
The syntax is similar to the one for ports. The value unknown
matches packets of forwarded connections. unknown can only be used
with the operators = and !=. Other constructs like user ≥ unknown
are invalid. Forwarded packets with unknown user and group ID
match only rules that explicitly compare against unknown with the
operators = or !=. For instance user ≥ 0 does not match forwarded
packets. The following example allows only selected users to open
outgoing connections:
block out proto { tcp, udp } all
pass out proto { tcp, udp } all user { < 1000, dhartmei }
With the caveat that this only works for processes and users on the same system as the PF firewall.Filter by user is possible.