I connect to a Cisco VPN Server and want to share that connection via wifi.

Using the macOS Internet Sharing feature, I can only select one interface to share - either my LAN adapter, or the VPN connection. Clients on the wifi can then only connect to either the iNet, or the VPN.

The VPN Server is only creating a split-tunnel connection - and switching to full tunnel is unfortunately not an option.

Setting my nat rules directly in /etc/pf.conf/ works fine and solves my problem to a degree.

I want to script and dynamically add them using a nat-anchor. Setting the anchor with load for an external config works, however when I define my anchor in pf.conf and try to populate my rules using pfctl like so:

echo "                                                                                                                                      
nat on en8 from bridge100:network to any -> (en8)
nat on utun1 from bridge100:network to any -> (utun1)" | pfctl -a my.anchor -f -

or as a one-liner:

echo -e "nat on en8 from bridge100:network to any -> (en8)\nnat on utun1 from bridge100:network to any -> (utun1)\n" | pfctl -a my.anchor  -f -

(w/ or w/o the trailing \n)

I can confirm that the rules are set on my anchor using pfctl -sn -a my.anchor but the actual routing remains unchanged.

What am I doing wrong here?

  • too many text per logical unit
    – poige
    Mar 30, 2020 at 9:18
  • let me shorten it for you: How come adding a nat rule to an anchor using pfctl does not work on macOS?
    – CygnusOlor
    Mar 30, 2020 at 13:01
  • Still not cleared up. It doesn't add or it does but w/o changing NAT policy?
    – poige
    Mar 30, 2020 at 14:28
  • rules add, but don't actually change the policy when using pfctl. Same goes for flushing rules using pfctl -a my.anchor -F nat i can confirm there are no more rules on the anchor using pfctl -sn my.anchor - however clients still reach the network.
    – CygnusOlor
    Mar 30, 2020 at 15:21
  • Well, given it's stateful, only new connections should be failing after rules flush.
    – poige
    Mar 30, 2020 at 16:49

2 Answers 2


This sounds like the top-level rules (the ones with empty anchor) do not have a reference to your nat-anchor. You need to make sure there is a nat rule with a "nat-anchor " in the TOP level rules linking to your anchor.

In general, for any rules to apply, you should be able to trace "nat-anchor" (or "WHATEVER-anchor") inclusion rules from the top level all the way to your anchor's config.

You can use 'pfctl -sn' to see the top-level nat rules. Should see a line like this:

nat-anchor "myanchor" all

For those with more deeply nested anchors, you can dump everything for all anchors using this script. The recursive printing mentioned in the man page has a bug and does not work (prints some stuff and 'DIOCGETRULES').

Anyway, just make sure each anchor from root to your rules has a nat-anchor directive, and it's either explicit, or if there are wildcard *s in the anchor string (was just "myanchor" here), then there is some intermediate or final anchor that matches the wildcard (wildcards match one level only).

Related answer here: pfctl - howto add an anchor and make it active / load it


I think you need to call sudo sysctl -w net.inet.ip.forwarding=1 to enable packet forwarding.

You don't need to modify /etc/pf.conf. It should be sufficient, if you change -a my.anchor to -a 'com.apple/my.anchor'.

You must log in to answer this question.

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