If we are using the default firewall for OpenBSD, how can we modify it to disable all the network access for a normal user except for one thing: we want to ssh to the user from random hosts!

So example if the user want's to "wget google.com", it shouldn't have firewall permission to it. If we want to copy something via scp to the user from a random machine, the firewall would need to allow it. If the user wants to ssh to some other hosts, it shouldn't have access.

| improve this question | | | | |
  • There is no way a gateway like OpenBSD with pf know that is the local user of a computer to deny or allow access. But, if this traffic have the OpenBSD box as origin, you can use the user rule as the manpages example: block out proto tcp all, pass out proto tcp from self user { < 1000, dhartmei } - openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man5/… - Combine with other objects(like ports, or "in") to create more specific rules. – user34720 Mar 5 '15 at 19:21

I think you're looking for authpf.


Authpf(8) is a user shell for authenticating gateways. An authenticating gateway is just like a regular network gateway (a.k.a. a router) except that users must first authenticate themselves to the gateway before it will allow traffic to pass through it. When a user's shell is set to /usr/sbin/authpf (i.e., instead of setting a user's shell to ksh(1), csh(1), etc) and the user logs in using SSH, authpf will make the necessary changes to the active pf(4) ruleset so that the user's traffic is passed through the filter and/or translated using Network Address Translation or redirection. Once the user logs out or their session is disconnected, authpf will remove any rules loaded for the user and kill any stateful connections the user has open. Because of this, the ability of the user to pass traffic through the gateway only exists while the user keeps their SSH session open.

# macros
wifi_if = "wi0"
ext_if  = "fxp0"
dns_servers = "{, }"

table <authpf_users> persist

# filter
block drop all

pass out quick on $ext_if inet proto { tcp, udp, icmp } \
   from { $wifi_if:network, $ext_if }

pass in quick on $wifi_if inet proto tcp \
   from $wifi_if:network to $wifi_if port ssh

pass in quick on $wifi_if inet proto { tcp, udp } \
   from <authpf_users> to $dns_servers port domain

anchor "authpf/*" in on $wifi_if
| improve this answer | | | | |

I can't give you a general plan and then hopefully someone else can fill in the details.

It looks like you're going to need to do the following:

  1. Create a chroot
  2. Somehow allow only one interface to it.
  3. Then look at packet queuing for that interface or write your pf rules on that interface.

Honestly, I think it'd be easier with FreeBSD jails, but your probably don't have that option.

This may not be much of an answer, but hopefully it'll point you in the right direction. I'd post this as a comment, but I think it is too long.

| improve this answer | | | | |

Firewalls generally look at network packets. They can see where packets come from, but unless it's somehow revealed by packet introspection, they don't know who is responsible for those packets.

You could start with everything locked down for everyone, and then add in authenticated access as needed. e.g. via an authenticated proxy which all external web requests must pass through.

| improve this answer | | | | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy