Sharing a network between your VMware Fusion Linux guest and your Mac OS X host

Patrick R. Donahue
up in atoms
Published in
7 min readJan 11, 2016

Instructions for adding a secondary NIC to your Linux guest, assigning it a static IP address via DHCP, and using it to communicate with your Mac.

The Problem

By default, a new VMware Fusion guest will have a single NIC configured to use Internet Sharing (e.g., “Share with my Mac”). This allows the guest to communicate with the outside world — resolve DNS records, download operating system updates, access arbitrary Internet resources — using network address translation (NAT). Through an internal DHCP service, the guest is assigned a private, RFC1918 address, which VMware translates to the host’s IP address before forwarding along to the appropriate gateway (typically, the “default gateway”, i.e., the upstream router).

Default NIC configuration on VMware Fusion guest (Linux)

While the above configuration works just fine for accessing the Internet or consuming services on the LAN, it is not ideal — or even practical — for hosting services or serving (development) websites. At CloudFlare, like many other technology companies, we host production services on Linux but develop and test on our Macs. For example, if you’re a developer working on the client dashboard, you’ll typically clone the appropriate repositories, make code changes, and then review them live in your browser before submitting pull requests. To eliminate any bugs caused by heterogenous hosting environments, you make sure your dev environment is as close to production as possible; this means using the same operating system, kernel, packages, etc. rather than trying to run something like NGINX on your Mac.

Once services are running on the Linux guest, you’ll need an easy way to communicate with them from your Mac. Ideally, they should always be found at the same IP address and hostname(s), so that you can focus on your work and not on your development environment.

The Solution

The instructions below show how to add a second NIC to your VMware Fusion[1] guest, configure it to use a static IP address, and configure your Mac to resolve all development hostnames that match a particular pattern (e.g., “.dev”) to that IP address.

Step 1: Add an additional network adapter

First, shutdown your virtual machine. Then, in the Virtual Machine Library (accessed by hitting shift+⌘+L), right-click on your VM and click Settings. In the window that appears, click the “Add Device…” button in the top-right hand corner and then click the Network Adapter icon.

Initial Settings window. Click Add Device… in the top-right.
Add Device window. Double-click the Network Adapter icon.

Step 2: Configure the new NIC

After double-clicking the Network Adapter icon, you’ll be shown the configuration screen for a NIC labeled “Network Adapter 2”. By default, the top radio button — “Share with my Mac” — will be selected; change this selection to “Private to my Mac”.

Then, expand the Advanced options section by clicking the rightward-facing triangle. By default, the MAC Address input box will be empty, so you should click the Generate button. A random[2] MAC address will be generated; you should either write this down somewhere or copy it to your clipboard as it will be used momentarily to configure DHCP.

Step 3: Configure DHCP to assign your new NIC a static IP

If you didn’t record the MAC address of the new NIC in Step #2, go back and do that now. We are going to configure the DHCP server listening on your Mac’s vmnet1 NIC to map this MAC to a static IP address. Note that VMware Fusion (and other related VMware products) use vmnet1 for “host-only” networking and use vmnet8 for NAT/shared connections:

mac$ ifconfig vmnet1
vmnet1: flags=8863<UP,BROADCAST,SMART,RUNNING,MULTICAST> mtu 1500
ether 00:50:56:c0:00:01
inet 192.168.7.1 netmask 0xffffff00 broadcast 192.168.7.255
mac$ ifconfig vmnet8
vmnet8: flags=8863<UP,BROADCAST,SMART,RUNNING,MULTICAST> mtu 1500
ether 00:50:56:c0:00:08
inet 172.16.163.1 netmask 0xffffff00 broadcast 172.16.163.255

As you can see from the above output — run from my Mac — the vmnet1 network is using the 192.168.7.0/255 network. (You can also find these networks by cat’ing /Library/Preferences/VMware\ Fusion/networking). It is within this RFC1918 network that we need to select an unused IP address for the guest to be assigned on boot. However, we first need to check which IPs may be automatically given out by the VMware DHCP server, so that we can avoid an overlapping assignment:

mac$ grep range /Library/Preferences/VMware\ Fusion/vmnet1/dhcpd.conf
range 192.168.7.128 192.168.7.254;

The above grep output, part of a subnet stanza, instructs the DHCP server to hand out IP addresses between 192.168.7.128–254 to guests. You should choose an IP outside this range, but not .1 as that’s assigned to the vmnet1 NIC itself; for this example, I’ve chosen 192.168.7.100 for my “brady” VMware guest. Next, armed with (x) your newly selected IP address and (y) previously generated MAC address from step #2, add a reservation using either your favorite[3] editor or tee and then restart the DHCP server:

// add the static reservation
mac$ sudo tee -a /Library/Preferences/VMware\ Fusion/vmnet1/dhcpd.conf >/dev/null <<'EOF'
host brady {
hardware ethernet 00:50:56:2B:31:19;
fixed-address 192.168.7.100;
option domain-name-servers 8.8.8.8, 8.8.4.4;
}
EOF
// restart the DHCP server
mac$ sudo /Applications/VMware\ Fusion.app/Contents/Library/vmnet-cli --configure
Stopped DHCP service on vmnet1
Disabled hostonly virtual adapter on vmnet1
Stopped DHCP service on vmnet8
Stopped NAT service on vmnet8
Disabled hostonly virtual adapter on vmnet8
Stopped all configured services on all networks
Backed up existing network settings to backup file "/tmp/vmware.VPXkfQ"
Restored network settings
mac$ sudo /Applications/VMware\ Fusion.app/Contents/Library/vmnet-cli --stop
Stopped all configured services on all networks
mac$ sudo /Applications/VMware\ Fusion.app/Contents/Library/vmnet-cli --start
Enabled hostonly virtual adapter on vmnet1
Started DHCP service on vmnet1
Started NAT service on vmnet8
Enabled hostonly virtual adapter on vmnet8
Started DHCP service on vmnet8
Started all configured services on all networks

Note that I’ve instructed VMware to provide the guest with Google’s public (recursive resolving) DNS servers 8.8.8.8 and 8.8.4.4. If your guest needs to resolve local/corporate services, replace this value with a comma-separated list of the IP address(es) of your DNS server(s).

Step 4: Boot the VM and verify configuration

Back in the Virtual Machine Library, boot the machine by right-clicking on the guest and clicking “Start Up”. Log in to the machine, run /sbin/ifconfig to verify that you have a NIC with the IP address you chose in step #3, and make sure you can ping that IP from your host (Mac).

// verify the guest has correct IP address
linux$ ifconfig|grep -B 1 192.168.7.100
eno33554984: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.7.100 netmask 255.255.255.0 broadcast 192.168.7.255
// ..and that it's reachable from your host
mac$ ping -c 1 192.168.7.100
PING 192.168.7.100 (192.168.7.100): 56 data bytes
64 bytes from 192.168.7.100: icmp_seq=0 ttl=64 time=0.460 ms
--- 192.168.7.100 ping statistics ---
1 packets transmitted, 1 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 0.460/0.460/0.460/0.000 ms

Step 5: Simplify access with dnsmasq (or /etc/hosts)

While you can now access your guest with an IP address, it’s much more practical to use a hostname (or multiple hostnames, as your application dictates). The simplest way would be to just add an /etc/hosts entry:

mac$ echo "192.168.7.100 www.example.dev example.dev" | sudo tee -a /etc/hosts

But then you’re stuck updating this record each time you add a new application, domain, etc. A better result would be mapping an entire TLD to that IP address; this way, you can simply configure your http daemon to expect the request and avoid doing anything on your Mac other than using the new hostname in your browser (or wherever).

// install and configure dnsmasq
mac$ brew up && brew install dnsmasq
mac$ sudo tee -a /usr/local/etc/dnsmasq.conf >/dev/null <<'EOF'
address=/dev/192.168.7.100
EOF
// set it to start on boot, and start it now
mac$ sudo cp -fv /usr/local/opt/dnsmasq/*.plist /Library/LaunchDaemons
mac$ sudo chown root $_/homebrew.mxcl.dnsmasq.plist
mac$ sudo launchctl load $_

Lastly, you’ll need to configure your Mac to route all DNS resolution requests for the .dev domain to the newly started server listening at 127.0.0.1. After doing so, make sure you can access using the hostname.

// configure resolution
mac$ sudo mkdir /etc/resolver
mac$ sudo tee /etc/resolver/dev >/dev/null <<'EOF'
nameserver 127.0.0.1
EOF
// test that arbitrary .dev hostnames are resolving
mac$ ping -c 1 www.example.dev|head -n1
PING www.example.dev (192.168.7.100): 56 data bytes
mac$ ping -c 1 another-example.dev|head -n1
PING another-example.dev (192.168.7.100): 56 data bytes

Step 6: Get a beer and admire your handiwork

May I recommend Allagash Brewing Company’sCurieux”?

Allagash Curieux was our first foray into barrel-aging. Curieux is made by aging our Tripel Ale in Jim Beam bourbon barrels for eight weeks in our cold cellars. The aged beer is then blended back with a portion of fresh Tripel. The resulting beer is smooth with coconut and vanilla notes and hints of bourbon.

Miscellaneous Thoughts

  1. Host-only network: The instructions above show one how to create a host only network. While this is advantageous in most cases — others can’t access your potentially sensitive services — you may want to let others on your LAN test your hosted resources. However, unless you have spoken with your administrator about a static DHCP reservation (or free address you can use without DHCP), you’ll need to hand out your vmnet8 IP address each time. Be sure to check that your services are bound to 0.0.0.0 on the guest, otherwise they may only be listening on the vmnet1-associated NIC.

Endnotes

[1] The screenshots were taken on VMware Fusion 8, but the technique should apply just the same to previous versions.

[2] Technically, there’s some rhyme and reason to the MAC address as the first six hexadecimal characters (XX:XX:XX) indicate the manufacturer. However, there is enough entropy in the remaining characters that, when randomly generated, should not result in any sort of LAN collision. If in the extremely rare chance that it does, you can simply update the value.

[3] Any editor on your Mac will do, but [insert your favorite deity here] looks down on those who use anything other than vi(m).

--

--