Solved Port Forwarding into NAT Bhyve VM under pf(4) Firewall

Hi,

I have successfully setup NAT on pf(4) with this in /etc/pf.conf file:

Code:
nat on wlan0 inet from 10.1.1.0/24 to any -> (wlan0) round-robin

I am now trying to achieve the same what is available out of the box on VirtualBox - port forwarding.

For example one of my Bhyve virtual machines is available on 10.1.1.10/24 address space - and with port forwarding I would like to use ssh(1) to connect to it from the host on 127.0.0.1 port 22222 for example - so the redirection would be to the 10.1.1.10 port 22.

The NAT works as desired. Its on a vm-public bridge that was created by vm-bhyve command.

That 10.1.1.10 Bhyve FreeBSD machine uses tap0 interface that is a member of a vm-public switch.

My entire /etc/pf.conf file looks as follows.

Code:
# BASICS
  ext_if = "wlan0"

# NAT bhyve(8) VMS
  nat on $ext_if from {10.1.1.1/24} to any -> ($ext_if)

# RDR
  rdr pass              inet proto tcp from any to 127.0.0.1 port 22222 -> 10.1.1.10 port 22
  rdr pass on vm-public inet proto tcp from any to 127.0.0.1 port 22222 -> 10.1.1.10 port 22
  rdr pass on $ext_if   inet proto tcp from any to 127.0.0.1 port 22222 -> 10.1.1.10 port 22
  rdr pass on lo0       inet proto tcp from any to 127.0.0.1 port 22222 -> 10.1.1.10 port 22
  rdr pass on tap0      inet proto tcp from any to 127.0.0.1 port 22222 -> 10.1.1.10 port 22
# PASS IN/OUT ALL
  pass in all
  pass out all

As you can see I have tried various rdr rules - but without success.

There is absolutely zero traffic on a vtnet0 interface inside that 10.1.1.10 VM.

Any help or hints welcome.

One more thing - I do not insist on using pf(4) firewall - I can also use ipfw(4) instead if you have some answers.

Thanks in advance,
vermaden
 
For example one of my Bhyve virtual machines is available on 10.1.1.10/24 address space - and with port forwarding I would like to use ssh(1) to connect to it from the host on 127.0.0.1 port 22222 for example - so the redirection would be to the 10.1.1.10 port 22.
Traffic never passes wlan0 and so the NAT never applies here.

The NAT works as desired.
It does for traffic leaving the host, passing wlan0 on the way out. It does not apply to traffic that's going to and from the host itself.

Code:
  rdr pass              inet proto tcp from any to 127.0.0.1 port 22222 -> 10.1.1.10 port 22
  rdr pass on vm-public inet proto tcp from any to 127.0.0.1 port 22222 -> 10.1.1.10 port 22
  rdr pass on $ext_if   inet proto tcp from any to 127.0.0.1 port 22222 -> 10.1.1.10 port 22
  rdr pass on lo0       inet proto tcp from any to 127.0.0.1 port 22222 -> 10.1.1.10 port 22
  rdr pass on tap0      inet proto tcp from any to 127.0.0.1 port 22222 -> 10.1.1.10 port 22
None of these will ever work because you cannot 'bounce' packets out of the same interface they came in on. Those IP addresses are all "local" from the host's perspective, they never pass in or out of an interface (virtual or otherwise).
 
But that information does not help me in any way.

Propose what I need to change in my setup to achieve what I need.

I am using wlan0 interface over WiFi to connect to Internet. I know it would be much easier with any LAN interface where I would not need NAT and bridge would just work - but this is on a laptop and wlan0 is the only Internet provider.
 
Just connect to port 22 of 10.1.1.10 from the host itself. Or actually run the ssh daemon on port 2222.
F*ck me ... it was that brain dead simple ... thank you a lot for the solution.

I wasted about 2-3 days trying to achieve what was so close :)

I will not close the thread as its solved 100%.

Thank You again.

Regards,
vermaden
 
Side question...
I know you guys can just look at config files and know that his traffic wasnt routed right, but how do you actually test this stuff like firewalls and routing tables etc?
Is there a way to send a packet through and watch where it goes?
 
Back
Top