Sometimes you have a virtual machine that needs internet, but the normal network is blocked or unavailable.
In my case, I had an Ubuntu 22.04 VM running in Hyper-V on a Windows work machine. The VM needed internet access, but it could not get online through the usual network. I also had an iPhone with USB tethering, so the question was:
Can I use the iPhone internet connection inside the Hyper-V Ubuntu VM?
The answer is: yes, but not the obvious way.
The simple idea that did not work
The first idea was to plug the iPhone into the Windows host and create a Hyper-V External Virtual Switch using the iPhone adapter.
The iPhone showed up in Windows as:
Apple Mobile Device Ethernet
Then Hyper-V created a virtual adapter called something like:
vEthernet (Apple)
The Windows host got an IP address like:
172.20.10.9
The iPhone gateway was:
172.20.10.1
So far, that looked good.
But inside Ubuntu, the VM could not get an IP address with DHCP. When I manually gave it an IP address, it still could not ping the iPhone gateway.
Example:
sudo ip addr add 172.20.10.10/28 dev eth0
sudo ip route replace default via 172.20.10.1 dev eth0
ping 172.20.10.1
Result:
Destination Host Unreachable
That means the VM could not talk directly to the iPhone network.
So the direct bridge method failed.
Why it failed
An iPhone USB tether is not the same as a normal Ethernet network.
A normal Ethernet network can usually handle multiple devices. But an iPhone USB tether often expects to talk to the computer it is plugged into, not to extra virtual machines behind it.
So even though Windows could use the iPhone internet, the Ubuntu VM could not directly use it as a separate network client.
The method that worked: Hyper-V NAT
The working solution was to use NAT.
NAT means the Ubuntu VM does not talk directly to the iPhone. Instead, the VM talks to Windows, and Windows talks to the internet for it.
The setup looks like this:
Ubuntu VM
192.168.250.2
↓
Hyper-V Internal Switch
192.168.250.1 on Windows
↓
Windows NAT
↓
iPhone USB tether / work network / internet
To the outside world, the traffic looks like it came from Windows.
Step 1: Create an internal Hyper-V switch
Run this on the Windows host in PowerShell as Administrator:
New-VMSwitch -Name "AppleNAT" -SwitchType Internal -ErrorAction SilentlyContinue
Then connect the Ubuntu VM to that switch:
Connect-VMNetworkAdapter -VMName "Ubuntu 22.04 LTS" -SwitchName "AppleNAT"
Step 2: Give the Windows side an IP address
Run:
New-NetIPAddress -IPAddress 192.168.250.1 -PrefixLength 24 -InterfaceAlias "vEthernet (AppleNAT)" -ErrorAction SilentlyContinue
This gives the Windows side of the private VM network this address:
192.168.250.1
Step 3: Create the NAT rule
Run:
New-NetNat -Name "AppleNAT" -InternalIPInterfaceAddressPrefix 192.168.250.0/24 -ErrorAction SilentlyContinue
This tells Windows:
Anything from the 192.168.250.x network should be NATed out through the host’s internet connection.
Step 4: Configure Ubuntu manually
Inside Ubuntu, run:
sudo ip addr flush dev eth0
sudo ip addr add 192.168.250.2/24 dev eth0
sudo ip route replace default via 192.168.250.1 dev eth0
echo "nameserver 1.1.1.1" | sudo tee /etc/resolv.conf
This gives Ubuntu:
Ubuntu IP: 192.168.250.2
Gateway: 192.168.250.1
DNS: 1.1.1.1
Step 5: Test the connection
First test whether Ubuntu can see the Windows host:
ping -c 3 192.168.250.1
If that works, test internet by IP:
curl -4 -I --connect-timeout 8 http://1.1.1.1
If that works, test DNS:
curl -4 -I --connect-timeout 8 http://example.com
If the first one works but the second one does not, your internet path is working but DNS is broken.
Useful host-side checks
On the Windows host, this command shows whether the main pieces are in place:
Get-NetAdapter | Format-Table Name,InterfaceDescription,Status,LinkSpeed,ifIndex
Get-VMSwitch | Format-Table Name,SwitchType,NetAdapterInterfaceDescription,AllowManagementOS
Get-VMNetworkAdapter -VMName "Ubuntu 22.04 LTS" | Format-Table VMName,Name,SwitchName,Status,Connected,IPAddresses
Get-NetNat | Format-Table Name,Active,InternalIPInterfaceAddressPrefix
Get-NetIPAddress -InterfaceAlias "vEthernet (AppleNAT)" -AddressFamily IPv4
You want to see:
Ubuntu VM connected to AppleNAT
AppleNAT active
vEthernet (AppleNAT) has 192.168.250.1
Ubuntu has 192.168.250.2
If NAT stops working
Sometimes Windows NAT gets stuck. This reset helped:
Restart-Service hns -Force
Remove-NetNat -Name "AppleNAT" -Confirm:$false -ErrorAction SilentlyContinue
New-NetNat -Name "AppleNAT" -InternalIPInterfaceAddressPrefix 192.168.250.0/24
Set-NetIPInterface -InterfaceAlias "vEthernet (AppleNAT)" -Forwarding Enabled
Then reapply the Ubuntu settings:
sudo ip addr flush dev eth0
sudo ip addr add 192.168.250.2/24 dev eth0
sudo ip route replace default via 192.168.250.1 dev eth0
echo "nameserver 1.1.1.1" | sudo tee /etc/resolv.conf
What NAT is doing in plain English
NAT is like a helper sitting between Ubuntu and the internet.
Ubuntu says:
“I want to talk to this website.”
Windows says:
“I will ask for you.”
The website only sees Windows. It does not see Ubuntu directly.
Then Windows receives the reply and hands it back to Ubuntu.
That is why NAT works even when the VM cannot connect directly to the iPhone.
Why “Allow management operating system to share this adapter” mattered
In Hyper-V, the External switch had this option:
Allow management operating system to share this network adapter
When that was turned off, things stopped working.
That is because Windows needs a host-side virtual adapter, such as:
vEthernet (Apple)
Without that, Windows itself loses access to the iPhone route. Since Windows NAT runs on the host, NAT also stops working.
So for this setup, that option needs to stay on.
Can the iPhone adapter be isolated from the host?
Not fully with this method.
Because Windows is doing the NAT, Windows must be able to use the iPhone adapter.
You can make Windows prefer the normal work network instead:
Set-NetIPInterface -InterfaceAlias "vEthernet (Apple)" -InterfaceMetric 9000
Set-NetIPInterface -InterfaceAlias "Ethernet" -InterfaceMetric 10
And when you want the VM to use the iPhone path, you can temporarily prefer the iPhone:
Set-NetIPInterface -InterfaceAlias "vEthernet (Apple)" -InterfaceMetric 1
Set-NetIPInterface -InterfaceAlias "Ethernet" -InterfaceMetric 9000
Then restore it later:
Set-NetIPInterface -InterfaceAlias "Ethernet" -InterfaceMetric 10
Set-NetIPInterface -InterfaceAlias "vEthernet (Apple)" -InterfaceMetric 9000
But this is not true isolation. It is just route priority.
Final lesson
Hyper-V is not great at raw USB passthrough.
An iPhone USB tether does not behave like a normal bridgeable Ethernet adapter for a Hyper-V guest.
The working solution was:
Use an Internal Hyper-V switch + Windows NAT
That gave Ubuntu internet access through the Windows host.
The important commands were:
New-VMSwitch -Name "AppleNAT" -SwitchType Internal
New-NetIPAddress -IPAddress 192.168.250.1 -PrefixLength 24 -InterfaceAlias "vEthernet (AppleNAT)"
New-NetNat -Name "AppleNAT" -InternalIPInterfaceAddressPrefix 192.168.250.0/24
And inside Ubuntu:
sudo ip addr add 192.168.250.2/24 dev eth0
sudo ip route replace default via 192.168.250.1 dev eth0
echo "nameserver 1.1.1.1" | sudo tee /etc/resolv.conf
In short:
Don’t try to pass the iPhone directly into the Hyper-V VM. Let Windows use the iPhone, then NAT the Ubuntu VM through Windows.
Leave a Reply