How to forward traffic from one machine to another with `pfctl`?
This is how I got it to work.

My example uses three hosts on my network (10.10.0.0/16):

10.10.10.10 = Linux client
10.10.6.237 = Mac "real server" providing a service on port 3000
10.10.1.200 = Mac "server" performing pf redirection, listening on port 2004, interface vlan0

natrdr.pf

rdr on vlan0 inet proto tcp from 10.10.0.0/16 to 10.10.1.200 port 2004 -&gt; 10.10.6.237 port 3000
nat on vlan0 inet proto tcp from 10.10.0.0/16 to 10.10.6.237 port 3000 -&gt; 10.10.1.200


The specificity ensures your server isn't NATting traffic that it shouldn't.

For those doing this from scratch, after creating your natrdr.pf file above, run the following commands from the command line or a shell script, sudo or as root.  Integrating the pf rules with Apple's pf.conf files is an exercise left to the reader.

# Enable packet forwarding

sysctl -w net.inet.ip.forwarding=1

# Unless you have any rules you want to keep, let's flush existing NAT rules
pfctl -F nat

# Enable packet filtering
pfctl -e

# Load rules from our file
pfctl -f natrdr.pf

# Confirm rules are loaded
pfctl -s nat

# Check to see connections 
pfctl -s states


I then used telnet 10.10.1.200 2004 and was immediately forwarded to the Node/express server running on port 3000 on 10.10.6.237.

Example output of pfctl -s states to verify it's working:

ALL tcp 10.10.6.237:3000 &lt;- 10.10.1.200:2004 &lt;- 10.10.10.10:40744       ESTABLISHED:ESTABLISHED
ALL tcp 10.10.10.10:40744 -&gt; 10.10.1.200:35947 -&gt; 10.10.6.237:3000       ESTABLISHED:ESTABLISHED


So, to make it match your setup:

rdr on en0 inet proto tcp from 192.168.1.0/24 to 192.168.1.186 port 1234 -&gt; 192.168.1.198 port 80
nat on en0 inet proto tcp from 192.168.1.0/24 to 192.168.1.198 port 80 -&gt; 192.168.1.186


The order of rules is important.

The redirect rule does what's expected: it forwards all traffic coming into the server to the real server.

The NAT rule changes the (now redirected) packets to have a source IP address of the redirecting server instead of the original client. 

The combination of these rules ensures that a reverse path for the return packets to follow is automatically created.