1

I'm trying to configure a packet filter firewall to block access to a small range of IP addresses when a VPN is not connected.

My rules should allow https/http traffic apart from this small, specific list of IP addresses. It's important the device can not reach these IP address when the VPN is not connected.

I'm using the built in macOS VPN in 10.13

I've got some fairly standard stuff in my rules so far:

vpn_ifs = "{ utun1 ipsec0 }"
hw_ifs = "{ en0 en1 en2 }"
...
pass quick on $vpn_ifs

The reason for my request is that I have a web based resource I can only access once the VPN is connected. Allowing connectivity to this resource before the VPN is connected disables access to my account.

I need access to http and https traffic before the VPN is established to enable services that need to function before the VPN connection is up. Including, but not limited to captive portal support.

  • Shouldn't 1. pass out quick on $vpn_ifs from any to { <web_res1> <web_res2> } no state and then 2. block out quick on $hw_ifs from any to { <web_res1> <web_res2> } no state work? – klanomath Mar 28 '18 at 20:48
  • Also added:Allow out on $hw_ifs to { 80 443 } to meet my other requirement for http and https without VPN. – John Mar 29 '18 at 16:12
  • Oh, I didn't read this additional requirement. Are the ports 80/443 somehow related to the "web based resources"? Then the right sequence of the quick rules and the 80/443 rule matters... – klanomath Mar 29 '18 at 16:17
  • Two different things. 1. Access to 80 , 443 before VPN is established - not controlled by IP range 2. No access to some specific ‘web resources’ before VPN is established. All access to these specific ‘web resources’ remains blocked when the VPN is not connected. – John Mar 29 '18 at 16:30
0

Each packet is evaluated against the filter ruleset from top to bottom and the last matching rule wins. The quick keyword is the only exception: the packet will be blocked or passed immediately unperturbed by any later rule.

Assuming you are using the deny all approach you have to explicitly allow packets to pass in or out.

Rule set:

block all
...

To meet your "web based resource" requirement you have to quick allow/deny packets depending on the interface:

pass out quick on $vpn_ifs from any to { <web_res1>, <web_res2> } no state  
block out quick on $hw_ifs from any to { <web_res1>, <web_res2> } no state

To meet your "http and https traffic" requirement you have to allow outgoing traffic to port 80/443:

pass out on $hw_ifs from any to any port { 80, 443 }

Using the deny all approach you have add some more rules (e.g. to allow traffic from/to local networks).

The final rule set looks like this then:

block all
...
rules
...
pass out quick on $vpn_ifs from any to { <web_res1>, <web_res2> } no state  
block out quick on $hw_ifs from any to { <web_res1>, <web_res2> } no state
...
pass out on $hw_ifs from any to any port { 80, 443 }
...
more rules

Here is an example of a deny all pf.conf with a lot of rules explained. The rules are used on a FreeBSD Gateway though: some mustn't be applied or aren't useful in your environment. Single rules don't work at all (e.g. ALTQ related features).

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .