utmapp / UTM

Virtual machines for iOS and macOS
https://getutm.app
Apache License 2.0
26.31k stars 1.31k forks source link

Configure shared networking IP address #3294

Open GregOriol opened 2 years ago

GregOriol commented 2 years ago

Describe the issue When using shared networking mode with macOS (12) and ubuntu (20.04), the IPv4 address that the VM gets on my mac is 192.168.64.2. However, for some use-cases, I need the address to be something else and something pre-defined (for example when using the VM as a development server and some other service has the IP in its configuration).

How could it be possible to define or change the assigned IP to something else? I've tried many options in the advanced settings of the Network tab, but most are not accepted with the shared mode, and none seem to have an effect on the IP address the guest gets.

I've also tried manipulating vmnet from macOS with ifconfig (ipconfig set bridge bridgeX...), but I could only change the IP of the bridge and not the VM.

nb: I cannot use the bridged mode with another DHCP server because I don't have control over it.

Configuration

ktprograms commented 2 years ago

The shared networking is based on the vmnet framework. You could take a look at this example and see if you can adapt it to QEMU. The thing of interest would probably be vmnet_start_address_key, vmnet_end_address_key and vmnet_subnet_mask_key. The online (developer.apple.com) documentation doesn't cover these keys, but if you look in /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks/vmnet.framework/Versions/A/Headers/vmnet.h, you can find the documentation comments for everything in vmnet.framework. (You need Xcode installed).

GregOriol commented 2 years ago

@ktprograms Is the management of vmnet part of UTM or of qemu or of something else? I can't figure out where this is managed: I have seen that parameters are passed to qemu but not where "vmnet-macos" type is handled from there.

ktprograms commented 2 years ago

Well, vmnet-macos was implemented into QEMU with https://lists.gnu.org/archive/html/qemu-devel/2021-02/msg04637.html. The vmnet-macos code is in https://github.com/utmapp/qemu/blob/utm-edition/net/vmnet-macos.c.

Although it's supposed to be that you can specify dhcp-start-address, dhcp-end-address and dhcp-subnet-mask to the -netdev vmnet-macos,... but when I try that, it vmnet.framework has a Console.app message vmnet_start_address "192.168.72.88" is not a valid IP address. The dhcp-* stuff is in qapi/net.json in the linked patch.

GregOriol commented 2 years ago

I think I have found a way to control it without going through the code. It would be better if it could be configured through the interface in UTM though.

Here is what I found. On the macOs host, by editing the file /Library/Preferences/SystemConfiguration/com.apple.vmnet.plist and looking for the value of Shared_Net_Address, which is 192.168.64.1, we can change the "range" to some other within 192.168.x.x. Then, when the vm has been up at least once, the dhcp assigned IP can be changed by editing the file /var/db/dhcpd_leases and setting ip_address for the appropriate machine

brad-x commented 2 years ago

Having built QEMU with the vmnet-macos patches I've found it next to impossible to configure the vmnet address range - however the v5 patchset at https://lore.kernel.org/all/20211112091414.34223-1-yaroshchuk2000@gmail.com/T/#m96c27aa28b0e2a7f11eea5be0ccb78865030128e functions quite reliably in this regard.

Patch applies against latest QEMU master, needs some effort to merge with 6.1.0 though. Example:

qemu-system-x86_64 [ ... ] -netdev vmnet-shared,id=internal,dhcpstart=10.0.2.1,dhcpend=10.0.2.254,subnet-mask=255.255.255.0" [ ... ]

toddbu commented 1 year ago

For those who need to stick with shared networking then I am in the same boat as you and would love to see a way to do reserved IPs in UTM so that VMs can be found at predictable IPs

For those willing to switch to bridged mode then you can set up reserved IPs for the VM mac address using your router. This works great... until it doesn't. When I set up my IP reservations at home then all is fine, but as soon as I hit the road then my IPs all change again. To solve this problem I bought a GL.iNet GL-AR300M Mini VPN Travel Router from Amazon and duplicated all of my IP settings in there. It works fairly well, but requires me to power up the router each time I move to a new location. That's why I would love to see UTM have a way to configure reserved IPs right from the console

ghost commented 10 months ago

If an IP isn't reliably getting assigned to the VM in shared network mode you could make a systemd boot service assign one.

  1. While the VM is off, edit the VM settings to add a serial terminal device or display

  2. Boot the VM and log in to root (or sudo)

  3. Add a script that assigns an IP address

    /root/assign-ip-on-boot.sh

    #!/bin/bash
    
    IPADDR=192.168.64.2
    
    ip route add 192.168.64.1 dev enp0s1
    ip route add default via 192.168.64.1 dev enp0s1
    ip addr add $IPADDR/24 brd + dev enp0s1
  4. Make the script executable

    # chmod +x /root/assign-ip-on-boot.sh

  5. Configure a systemd service that runs at boot

    /etc/systemd/system/assign-ip-on-boot.service

    [Unit]
    Description=Assign IP
    
    [Service]
    ExecStart=/root/assign-ip-on-boot.sh
    
    [Install]
    WantedBy=multi-user.target
  6. Enable the systemd service

    # systemctl enable assign-ip-on-boot
  7. Shut down the VM and remove the serial device or display

  8. Boot the VM again. The VM should have the IP address that was defined in the script and you can SSH in.

You may need to stop and disable any running dhcp services on the VM for example dhcpcd (systemctl disable dhcpcd).

vitalytarasov commented 9 months ago

Another possible solution is resolve VM host names to their dynamic IP addresses instead of trying to assign them static ones:

hraban commented 7 months ago

Another possible solution is resolve VM host names to their dynamic IP addresses instead of trying to assign them static ones:

* MacOS already does that with mDNS (Bonjour) - you can access them as `HOST.local` name (where `HOST` is the name of your VM in System Settings -> General -> Sharing -> Hostname)

* on Linux you need to install `sudo apt install avahi-daemon` which will advertise `HOST.local` where `HOST` is set with `sudo hostnamectl`

wow thank you for this , huge improvement over my shoddy workflow!

Step72 commented 6 months ago

Hello, When I create a VM with a shared network I end up with an IP address in 192.68.64.x but I would need an address in 192.168.1.x

How to adjust or configure UTM?

Capture d’écran 2024-02-25 à 16 12 55 Capture d’écran 2024-02-25 à 16 13 31
lrtfm commented 3 weeks ago

I encountered a similar issue where the subnet address changes consistently. Specifically, the output of:

sudo defaults read /Library/Preferences/SystemConfiguration/com.apple.vmnet.plist Shared_Net_Address

varies each time. When starting macOS and Linux guest operating systems sequentially in UTM, the subnet address assigned to vmnet increases. Is there a way to fix this value?"