I have MySQL running locally on my host machine and for reasons™ I can't run it inside of my Vagrant machine. I know that there's a way to address this issue with iptables by forwarding all traffic to 3306 on the guest to the host's IP address and port, but this complicates things a lot for me as I'll have to play around with iptables rules and probably get into TCP masquerading, which would be nice to avoid.
Is there a way in Vagrant (VirtualBox VM) to forward a host TCP port to the guest so that the guest can access 127.0.0.1:3306
and have all traffic forwarded to host:3306
seamlessly? If not, how exactly would I set this up in iptables?
According to this answer, Docker provides a way to do this natively without having to screw around with IP tables rules. Does VirtualBox and Vagrant provide a way to mimic this functionality?
To forward ports in VirtualBox, first open a virtual machine's settings window by selecting the Settings option in the menu. Select the Network pane in the virtual machine's configuration window, expand the Advanced section, and click the Port Forwarding button.
Port forwarding is a technique that is used to allow external devices access to computers services on private networks. It does this by mapping an external port to an internal IP address and port. Most online gaming Applications will require you to configure port forwarding on your home router.
If you want to connect to the guest machine from the host, using NAT Network: First, create a NAT Network - create the network in the VirtualBox Manager, File -> Preferences -> Network, and give it a name. Assign that named NAT Network to each of the guest machines in their Network configurations in VirtualBox.
Ports 22, 443, 3389, 18083, and 49152-65534 are configurable. On VirtualBox hosts, the HTTPS port is configured when you install VirtualBox. The VRDP ports are only required if the VRDP protocol is used to connect to desktops.
I have two solutions, one involving iptables hacking and one more straightforward using SSH.
When connecting to the guest using vagrant ssh
, pass the port along as an argument:
vagrant ssh -- -R 3306:localhost:3306
This will forward the local port 3306 to the remote machine at port 3306.
We can use iptables
on the guest to forward all traffic to a local port on the guest to a remote port on the host. We need to ensure that the host and guest have more or less static IP addresses in relation to each other to ensure that everything works fine. We'll also need to open a port on the host's firewall to allow the guest to do this.
In your Vagrantfile
, set a static IP address for the guest:
config.vm.network "private_network", ip: "10.10.10.10"
Now, when you hit 10.10.10.10
, you'll always* be hitting your guest.
Found in this awesome answer in Server Fault:
$ remote_ip=10.0.2.2
$ mysql_port=3306
$ sudo iptables -t nat -A PREROUTING -i eth0 -p tcp --dport $mysql_port \
-j DNAT --to $remote_ip:$mysql_port
$ sudo iptables -N INET-PRIV
$ sudo iptables -A FORWARD -i eth0 -o eth1 -j INET-PRIV
$ sudo iptables -A FORWARD -j drop
$ sudo iptables -A INET-PRIV -p tcp -d $remote_ip --dport $mysql_port \
-j ACCEPT
$ sudo iptables -A INET-PRIV -j DROP
Then, enable port forwarding:
$ echo "1" | sudo tee /proc/sys/net/ipv4/ip_forward
First, test it out, then when you're sure it works, run:
$ sudo iptables-save
I'm not sure that /proc/sys/net/ipv4/ip_forward
will remember settings on boot, so you might want to add that to a startup script.
SSH is definitely easier to do, but there's a bit of a performance overhead of having to encrypt that port's traffic and forward it back to the host.
iptables feels like black magic, but once you get it working, it's really nice and fairly seamless.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With