|
| 1 | +--- |
| 2 | +title: Managed networks on Linux |
| 3 | +weight: 34 |
| 4 | + |
| 5 | +--- |
| 6 | + |
| 7 | +| ⚡ Requirement | Lima >= 2.2, Linux | |
| 8 | +|-------------------|--------------------| |
| 9 | + |
| 10 | +On Linux hosts, the `shared`, `host` and `bridged` networks defined in |
| 11 | +`$LIMA_HOME/_config/networks.yaml` assign a "real" IP address that is reachable |
| 12 | +from the host, in the same way [socket_vmnet]({{< ref "/docs/config/network/vmnet" >}}) |
| 13 | +does on macOS. |
| 14 | + |
| 15 | +They are managed by `lima-net`, a privileged helper that ships with Lima and is |
| 16 | +installed to `<PREFIX>/libexec/lima/lima-net`. It creates a Linux bridge per |
| 17 | +network and attaches one tap device per instance. |
| 18 | + |
| 19 | +## Requirements |
| 20 | + |
| 21 | +`lima-net` calls the `dnsmasq` for DHCP and DNS, which must be installed. |
| 22 | +Only QEMU instances are supported. The VZ and krunkit drivers are macOS-only. |
| 23 | + |
| 24 | +## Setting up the `sudoers` file |
| 25 | + |
| 26 | +Creating a bridge and a tap device requires root, so the user either must have |
| 27 | +password-less `sudo` enabled, or add the required commands to a `sudoers` file: |
| 28 | + |
| 29 | +```bash |
| 30 | +limactl sudoers >etc_sudoers.d_lima |
| 31 | +less etc_sudoers.d_lima # verify that the file looks correct |
| 32 | +sudo install -o root etc_sudoers.d_lima /etc/sudoers.d/lima |
| 33 | +rm etc_sudoers.d_lima |
| 34 | +``` |
| 35 | + |
| 36 | +The generated file whitelists the exact command lines Lima needs, and nothing |
| 37 | +else: |
| 38 | + |
| 39 | +``` |
| 40 | +%wheel ALL=(root:root) NOPASSWD:NOSETENV: \ |
| 41 | + /usr/local/libexec/lima/lima-net start --pidfile=/run/lima/shared_lima-net.pid --mode=shared --bridge=lima-shared --gateway=192.168.105.1 --dhcp-end=192.168.105.254 --netmask=255.255.255.0, \ |
| 42 | + /usr/bin/pkill -F /run/lima/shared_lima-net.pid, \ |
| 43 | + /usr/local/libexec/lima/lima-net tap --bridge=lima-shared limatap[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f] |
| 44 | +``` |
| 45 | + |
| 46 | +Re-run `limactl sudoers` and re-install the file whenever `networks.yaml` |
| 47 | +changes, otherwise `sudo` will reject the new command line. |
| 48 | + |
| 49 | +The `group` setting in `networks.yaml` selects the group that is granted these |
| 50 | +permissions; it defaults to `sudo` or `wheel`, whichever exists on the host. |
| 51 | + |
| 52 | +`limactl sudoers` refuses to generate a file unless `paths.limaNet` is owned by |
| 53 | +`root` and none of its parent directories are writable by the user, so Lima must |
| 54 | +be installed with `sudo make install` rather than run from `_output`. |
| 55 | + |
| 56 | +## Configuration |
| 57 | + |
| 58 | +The defaults generated on a Linux host are: |
| 59 | + |
| 60 | +<details> |
| 61 | +<summary>Default</summary> |
| 62 | + |
| 63 | +<p> |
| 64 | + |
| 65 | +```yaml |
| 66 | +paths: |
| 67 | + socketVMNet: "" |
| 68 | + limaNet: "/usr/local/libexec/lima/lima-net" |
| 69 | + varRun: /run/lima |
| 70 | + sudoers: /etc/sudoers.d/lima |
| 71 | + |
| 72 | +group: wheel |
| 73 | + |
| 74 | +networks: |
| 75 | + user-v2: |
| 76 | + mode: user-v2 |
| 77 | + gateway: 192.168.104.1 |
| 78 | + netmask: 255.255.255.0 |
| 79 | + shared: |
| 80 | + mode: shared |
| 81 | + gateway: 192.168.105.1 |
| 82 | + dhcpEnd: 192.168.105.254 |
| 83 | + netmask: 255.255.255.0 |
| 84 | + bridged: |
| 85 | + mode: bridged |
| 86 | + interface: br0 |
| 87 | + # bridged mode doesn't have a gateway; dhcp is managed by outside network |
| 88 | + host: |
| 89 | + mode: host |
| 90 | + gateway: 192.168.106.1 |
| 91 | + dhcpEnd: 192.168.106.254 |
| 92 | + netmask: 255.255.255.0 |
| 93 | +``` |
| 94 | +
|
| 95 | +</p> |
| 96 | +
|
| 97 | +</details> |
| 98 | +
|
| 99 | +Instances can then reference these networks: |
| 100 | +
|
| 101 | +{{< tabpane text=true >}} |
| 102 | +{{% tab header="CLI" %}} |
| 103 | +```bash |
| 104 | +limactl start --network=lima:shared |
| 105 | +``` |
| 106 | +{{% /tab %}} |
| 107 | +{{% tab header="YAML" %}} |
| 108 | +```yaml |
| 109 | +networks: |
| 110 | +- lima: shared |
| 111 | + # MAC address of the instance; lima will pick one based on the instance name, |
| 112 | + # so DHCP assigned ip addresses should remain constant over instance restarts. |
| 113 | + macAddress: "" |
| 114 | + # Interface name, defaults to "lima0", "lima1", etc. |
| 115 | + interface: "" |
| 116 | +``` |
| 117 | +{{% /tab %}} |
| 118 | +{{< /tabpane >}} |
| 119 | +
|
| 120 | +The network daemon is started automatically when the first instance referencing |
| 121 | +it is started, and stops automatically once the last instance has stopped. |
| 122 | +Daemon logs are stored in the `$LIMA_HOME/_networks` directory. |
| 123 | + |
| 124 | +## Modes |
| 125 | + |
| 126 | +### shared (192.168.105.0/24) |
| 127 | + |
| 128 | +Creates the `lima-shared` bridge. Guests reach the host, each other, and the |
| 129 | +outside world through NAT (`MASQUERADE`, scoped to the network's own subnet). |
| 130 | +Enabling this turns on `net.ipv4.ip_forward` on the host; Lima restores it on |
| 131 | +teardown if it was the one that enabled it. |
| 132 | + |
| 133 | +### host (192.168.106.0/24) |
| 134 | + |
| 135 | +Creates the `lima-host` bridge. Guests reach the host and each other, but |
| 136 | +`FORWARD` rules block everything else, including other Lima networks. |
| 137 | + |
| 138 | +Note that an instance also has the default user-mode (slirp) network, which |
| 139 | +still provides outbound connectivity. The `host` network only guarantees that no |
| 140 | +traffic is routed *through the host* off the `lima-host` bridge. |
| 141 | + |
| 142 | +### bridged |
| 143 | + |
| 144 | +Attaches the instance directly to an existing host bridge, so that it gets an |
| 145 | +address from the outside network's DHCP server and is reachable from the LAN. |
| 146 | + |
| 147 | +Unlike on macOS, `interface` must name a **bridge that already exists**, created |
| 148 | +by the host administrator with NetworkManager, systemd-networkd or netplan. Lima |
| 149 | +never creates it and never enslaves a physical interface, because doing so can |
| 150 | +disconnect the host. |
| 151 | + |
| 152 | +> **Warning** |
| 153 | +> |
| 154 | +> A bridged instance is exposed to every host on the LAN, and its tap device |
| 155 | +> stays on the bridge until the network is torn down. |
| 156 | + |
| 157 | +## Firewall |
| 158 | + |
| 159 | +Guests must be able to reach the host's DHCP and DNS ports, which host firewalls |
| 160 | +block by default. |
| 161 | + |
| 162 | +- With **firewalld**, the bridge is bound to the first existing zone out of |
| 163 | + `lima`, `nm-shared`, and `libvirt`. All three forward the guests' traffic but |
| 164 | + expose only DHCP, DNS and ICMP on the host itself. Define a `lima` zone to |
| 165 | + override that policy. |
| 166 | +- With **ufw**, rules allowing UDP 67 and UDP/TCP 53 on the bridge are added. |
| 167 | +- Otherwise, equivalent `iptables` rules are added. |
| 168 | + |
| 169 | +All of them are removed when the network is torn down. |
| 170 | + |
| 171 | +## Security |
| 172 | + |
| 173 | +`lima-net` runs as root only to create the bridge and the tap devices. The tap |
| 174 | +device is handed to the calling user (`ip tuntap add ... user "$UID"`), so QEMU |
| 175 | +itself runs unprivileged and needs no network capabilities. |
| 176 | + |
| 177 | +The `varRun` directory (`/run/lima`) must stay owned by root and must not be |
| 178 | +writable by the user, because it holds the PID files that are passed to |
| 179 | +`pkill -F` as root. |
0 commit comments