View previous topic :: View next topic |
Author |
Message |
HuskyDog Tux's lil' helper
Joined: 20 Feb 2003 Posts: 82 Location: Wiltshire, UK
|
Posted: Fri Dec 14, 2007 3:41 pm Post subject: TUN/TAP and KVM (QEMU) |
|
|
When I try to run KVM (essentially QEMU) I get the following error:
Code: | warning: could not open /dev/net/tun: no virtual network emulation
Could not initialize device 'tap' |
So, I read the instructions and basically it says that if you are running a kernel >2.6.18 (mine is 2.6.22-gentoo-r8) then you need to use tunctl to set the appropriate permissions. So, I enter the following as root:
Code: | # tunctl -u my_user_name -t tap0
Set 'tap0' persistent and owned by uid 1000 |
That looks right to me. My user is indeed uid 1000. Clealy, the tap interface is running and that is confirmed by ifconfig.
However, when I try again with the following command as my user;
Code: | kvm -hda /dev/mapper/vols-andrew_root -cdrom ./install.iso -boot d -net nic,vlan=0 -net tap,vlan=0,ifname=tap0 -vnc :1 -k en-gb -monitor stdio
|
I get exactly the same error as above (i.e. the fix has made no difference at all). I should add that when I don't bother with this 'tap' lark and just stick with user networking my kvm works just fine.
So, this is one of those cases which occurs all too often with Linux where you get an error, find the exact error and a clearly defined fix, but when you apply the fix it makes no difference! Would anyone like to suggest another solution? |
|
Back to top |
|
|
VinzC Watchman
Joined: 17 Apr 2004 Posts: 5098 Location: Dark side of the mood
|
Posted: Fri Dec 14, 2007 9:27 pm Post subject: |
|
|
Having a tap0 interface is just not enough for QEMU/KVM. By default it tries to run a script, /etc/qemu-ifup, to configure the tap interface. (See the documentation.) If you don't have such a script, add script=no to the -net tap argument list.
If you have no script for KVM to setup the tap interface when launched, you must set the interface up, then add its IP address and routes. If you want it to be bridged against your LAN card, just set it up, create a bridge and add it to the bridge.
If you want your KVM virtual machine to be NAT'ed, setup IP forwarding and configure IPTABLES with a POSTROUTING rule that MASQUERADEs outgoing traffic through your wired or wireless ethernet card.
Additionally you might have to make sure /dev/net/tun can be written to by the user account that runs KVM. I usually do that by adding my regular user account to a group, say vmadmin. I then edit /etc/udev/rules.d/50-udev.rules and change the line that says Code: | KERNEL=="tun", NAME="net/%k", MODE="0660", OPTIONS+="ignore_remove" | into Code: | KERNEL=="tun", NAME="net/%k", MODE="0660", GROUP="vmadmin", OPTIONS+="ignore_remove" |
Hope this helps. _________________ Gentoo addict: tomorrow I quit, I promise!... Just one more emerge...
1739! |
|
Back to top |
|
|
HuskyDog Tux's lil' helper
Joined: 20 Feb 2003 Posts: 82 Location: Wiltshire, UK
|
|
Back to top |
|
|
VinzC Watchman
Joined: 17 Apr 2004 Posts: 5098 Location: Dark side of the mood
|
Posted: Sat Dec 15, 2007 10:15 am Post subject: |
|
|
Using script=no implies the tap interfaces must be up and ready before Qemu is run.
I also forgot to say that you need to provide a user name to tunctl when you create the tap interfaces. Basically it's your regular user account, as Mistik1 explained.
That user becomes the owner the tap interface. So there are two possible ways.- If you want to use Qemu graphical output to, say, check a bootable CDROM or run a virtual machine directly from the command line, then you need to pass your regular account to tunctl.
- If you plan to use Qemu as a daemon and want to control it with VNC, then you can create a user account that you will make member of the vmadmin group, as I mentioned earlier. That user must also be the owner of tap interfaces.
Note I don't like to use sudo to configure the network interfaces for Qemu. Hence I do all the tap stuff with a script that I run as root.
Both solutions above allow you to define tap interfaces in /etc/conf.d/net, the Gentoo way. I've tested Qemu in various ways and come to the conclusion that the ideal - maybe not most comfortable, it's a compromise - way is to create a user account that is dedicated to Qemu virtual machines; add it to a vmadmin group so that it can write to /dev/net/tun and launch Qemu with that user account in all circumstances, whether you're logged in with your regular account or running Qemu as a daemon. This has the main advantage to prevent you from editing your network configuration script each time you log on with a different account.
Create a udev rule as in my first post to automate the ACL on /dev/net/tun. You should then not need to chown/chmod manually. The only requirement is that your regular account must be member of the wheel group. Run either su - <vm-user> -c <qemu command> or sudo -u <vm-user> <qemu command>.
Sudo might fit best. At least it doesn't require root privileges. _________________ Gentoo addict: tomorrow I quit, I promise!... Just one more emerge...
1739! |
|
Back to top |
|
|
HuskyDog Tux's lil' helper
Joined: 20 Feb 2003 Posts: 82 Location: Wiltshire, UK
|
Posted: Sat Dec 15, 2007 5:59 pm Post subject: |
|
|
Quote: | I also forgot to say that you need to provide a user name to tunctl when you create the tap interfaces. |
Well, I'm already doing that, but it doesn't seem to make any difference. That is the whole nub of my problem! As I said in my initial post:
Code: | # tunctl -u my_user_name -t tap0
Set 'tap0' persistent and owned by uid 1000 |
So, unless someone else comes up with a solution to my basic problem of the above command not making any difference, then I will go with your "create a dedicated user and add it to the vmadmin group" scheme. |
|
Back to top |
|
|
VinzC Watchman
Joined: 17 Apr 2004 Posts: 5098 Location: Dark side of the mood
|
Posted: Sun Dec 16, 2007 10:50 am Post subject: |
|
|
I wasn't suggesting you to create a dedicated user right now, just explaining what I've done . So far, could you post your tap0 (ip addr show dev tap0) configuration, the results of ls -l /dev/net/tun and the results of id my_user_name?
EDIT: You could as well try once running KVM as root to check if you get such messages. _________________ Gentoo addict: tomorrow I quit, I promise!... Just one more emerge...
1739! |
|
Back to top |
|
|
HuskyDog Tux's lil' helper
Joined: 20 Feb 2003 Posts: 82 Location: Wiltshire, UK
|
Posted: Sun Dec 16, 2007 4:57 pm Post subject: |
|
|
Code: | # ip addr show dev tap0
6: tap0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast qlen 500
link/ether 00:ff:c9:00:34:11 brd ff:ff:ff:ff:ff:ff
inet 192.168.0.1/24 brd 192.168.0.255 scope global tap0
inet6 fe80::2ff:c9ff:fe00:3411/64 scope link
valid_lft forever preferred_lft forever |
Code: | # ls -l /dev/net/tun
crw-rw---- 1 root root 10, 200 Nov 17 09:54 /dev/net/tun |
Code: | # id my_user_name
uid=1000(my_user_name) gid=100(users) groups=100(users),10(wheel),19(cdrom),80(cdrw),1002(qemu),1004(kvm) |
Meanwhile, I think that I might have hit on a critical point. Reading /usr/src/linux/Documentation/networking/tuntap.txt it says:
Quote: | Set permissions:
e.g. chmod 0666 /dev/net/tun
There's no harm in allowing the device to be accessible by non-root users,
since CAP_NET_ADMIN is required for creating network devices or for
connecting to network devices which aren't owned by the user in question.
If you want to create persistent devices and give ownership of them to
unprivileged users, then you need the /dev/net/tun device to be usable by
those users. |
Until now, I had assumed that the 'tunctl -u my_user_name -t tap0' command created tap0 in such a way that it was basically owned by me and my user could therefore access it without any need of further access to /dev/net/tun, and that the benefit of this scheme was that it maintained the security of /dev/net/tun. But, perhaps this isn't true. If I do the above chmod, then my virtual machine works, but only if I have previously issued the tunctl command. Furthermore, despite allowing everyone read/write access to /dev/net/tun, I still need to be root to create the new tap interface, so perhaps this chmod has indeed not reduced the system security.
So, if the above is true then the correct fix to this problem is a patch to udev in order that the permissions of /dev/net/tun default to 666 as described in the documentation. |
|
Back to top |
|
|
VinzC Watchman
Joined: 17 Apr 2004 Posts: 5098 Location: Dark side of the mood
|
Posted: Sun Dec 16, 2007 5:13 pm Post subject: |
|
|
HuskyDog wrote: | So, if the above is true then the correct fix to this problem is a patch to udev in order that the permissions of /dev/net/tun default to 666 as described in the documentation. |
Not exactly; that's the reason why I suggested you changed the above UDEV rule so that the user that launches QEMU/KVM has write access to /dev/net/tun through group vmadmin. You only need to tweak /etc/udev/rules.d/50-udev.rules and add the GROUP= clause with the right group name.
Note the name vmadmin is not mandatory, just create a group for all users who would need to run QEMU and triturate tap interfaces. That group will need to be added to /etc/udev/rules.d/50-udev.rules accordingly with access mode 660.
Tap interfaces need to be created with root privileges. That's also the reason the best Gentoo way is to define them in /etc/conf.d/net.
All you'll have to care for after you a) have UDEV rule the ACLs of /dev/net/tun and b) have Gentoo network config file take care for the creation of your virtual tap interfaces is to run the virtual machine with the selected virtual interfaces. Everything else will have been done automatically at boot. _________________ Gentoo addict: tomorrow I quit, I promise!... Just one more emerge...
1739! |
|
Back to top |
|
|
sdauth l33t
Joined: 19 Sep 2018 Posts: 671 Location: Ásgarðr
|
Posted: Mon May 24, 2021 6:21 am Post subject: |
|
|
This finally resolved my issue.
I added :
Code: | KERNEL=="tun", NAME="net/%k", MODE="0660", GROUP="kvm", OPTIONS+="ignore_remove" |
to /etc/udev/rules.d/50-udev.rules
I used "kvm" since my user is already in kvm group, and I can finally start my VM with the tap device without needing root.
The wiki : https://wiki.gentoo.org/wiki/QEMU/Options#Networking
only says : "To successfully run VM you need permission for configure /dev/net/tun"
Now of course if you're experienced, it's an easy fix but it was confusing a little bit as I was afraid to manually chown /dev/net/tun. Well, thanks VinzC ! |
|
Back to top |
|
|
Hu Administrator
Joined: 06 Mar 2007 Posts: 23064
|
Posted: Mon May 24, 2021 3:08 pm Post subject: |
|
|
Another option would be to use tunctl -u user-who-runs-qemu. You can arrange for the openrc network scripts to do this for you for the interface kvm01 by setting: Code: | tuntap_kvm01=tap
tuntap_kvm01='-u user-who-runs-qemu' | Change the interface name as needed. If you do this, you may also want to use config_kvm01, mac_kvm01, and modules_kvm01 to configure other aspects of the device.
Although your solution is not as comprehensive in configuration, it has the virtue of relying only on udev, so your approach works equally for systemd and openrc users. Mine would require translation for a systemd user.
Regardless, please consider improving the Wiki to more explicitly describe at least one working solution. |
|
Back to top |
|
|
sdauth l33t
Joined: 19 Sep 2018 Posts: 671 Location: Ásgarðr
|
Posted: Mon May 24, 2021 5:02 pm Post subject: |
|
|
Thanks Hu, I will try that later again because I did try with :
Code: | tuntap_tap1="tap"
tunctl_tap1="-u sdauth" |
in /etc/conf.d/net but /dev/net/tun was still owned by root:root even after a reboot.
Full conf :
Code: | modules="dhclient"
config_eth0="null"
config_br0="192.168.1.19/24"
routes_br0="default via 192.168.1.1"
bridge_br0="eth0 tap1"
rc_net_br0_need="net.eth0 net.tap1"
config_tap1="null"
tuntap_tap1="tap"
tunctl_tap1="-u sdauth"
iproute2_tap1="user root"
bridge_forward_delay_br0=0
bridge_hello_time_br0=1000
bridge_stp_state_br0=0 |
By the way, it was not my solution but VinzC's one, a bit old but hey still valid. I'll see if I can add it to the wiki, I never did that before. |
|
Back to top |
|
|
Hu Administrator
Joined: 06 Mar 2007 Posts: 23064
|
Posted: Mon May 24, 2021 6:32 pm Post subject: |
|
|
Do you have tunctl installed? Last time I worked with this, that was required for the network script fragments I showed to work. It is part of sys-apps/usermode-utilities, which most desktop users would otherwise not have installed.
I see now, you are right about VinzC. Since you provided it in a code block as a ready-to-use sample, and I did not see such above, I attributed it to you. |
|
Back to top |
|
|
sdauth l33t
Joined: 19 Sep 2018 Posts: 671 Location: Ásgarðr
|
Posted: Mon May 24, 2021 9:16 pm Post subject: |
|
|
Indeed ! I was missing tunctl.
Nonetheless, it still doesn't work. /dev/net/tun is still owned by root:root
I also tried with "-g kvm" instead of "-u sdauth"
config_tap1="null"
tuntap_tap1="tap"
tunctl_tap1="-g kvm"
iproute2_tap1="user root"
also tried :
config_tap1="null"
tuntap_tap1="tap"
iproute2_tap1="group kvm"
Also, it seems tunctl is totally ignored at boot and iproute2 is somehow used to create the node.
I also tried to use tun as a module (It was compiled in previously) but no change.
For now, I give up. |
|
Back to top |
|
|
Hu Administrator
Joined: 06 Mar 2007 Posts: 23064
|
Posted: Tue May 25, 2021 12:57 am Post subject: |
|
|
For me, /dev/net/tun remains root:root even when tunctl has successfully made a specific device accessible to my unprivileged user. I am not aware of a way to test this other than to try starting the qemu process and let it try to access the device. |
|
Back to top |
|
|
sdauth l33t
Joined: 19 Sep 2018 Posts: 671 Location: Ásgarðr
|
Posted: Tue May 25, 2021 8:14 am Post subject: |
|
|
You're right.
I experimented a little bit and went back to the previous working /etc/conf.d/net config without the custom udev rules (to set root:kvm on /dev/net/tun)
Code: | modules="dhclient"
config_eth0="null"
config_br0="192.168.1.19/24"
routes_br0="default via 192.168.1.1"
bridge_br0="eth0"
bridge_forward_delay_br0=0
bridge_hello_time_br0=1000
bridge_stp_state_br0=0 |
So as you can see, here only br0 is created, then when I fire up a vm (as a user), qemu automatically create a tap device without requesting any root password for /dev/net/tun, which indeed stays as root:root, I don't even need to have tunctl installed for this to work.
Code: | crw-rw-rw- 1 root root 10, 200 25 mai 09:52 /dev/net/tun |
In my /etc/qemu/bridge.conf (-rw-r----- 1 root kvm 472 25 mai 09:39 bridge.conf)
I have :
which allows me to add devices to br0.
The network part of the qemu command line is :
Code: | -net nic,macaddr="$macaddr" -net bridge,br=br0 |
To summarize, the issue seems that if I create tap* devices upfront in /etc/conf.d/net, then for some reason, qemu cannot access them. (unless I use the udev "trick" to set owner root:kvm on /dev/net/tun of course)
Here is the network part of the qemu command line used :
Code: | -net nic,macaddr="$macaddr" -net tap,ifname=tap1,script=no,downscript=no |
I also tried :
Code: | -device e1000,netdev=tap1,macaddr="$macaddr" -netdev tap,id=lan,ifname=tap1,script=no,downscript=no |
|
|
Back to top |
|
|
sdauth l33t
Joined: 19 Sep 2018 Posts: 671 Location: Ásgarðr
|
Posted: Tue May 25, 2021 2:49 pm Post subject: |
|
|
Since I was almost certain the issue was caused by iproute2, I checked again the conf and noticed one last thing I hadn't tried yet.
config_tap1="null"
tuntap_tap1="tap"
iproute2_tap1="user sdauth group kvm"
Bingo. With these iproute2 options passed to the tap, qemu doesn't complain anymore and I can start my vm with my tap1 device without sudo. (also, tunctl is not needed, neither the udev trick)
network part of qemu command line (here with tap1 device as defined in /etc/conf.d/net)
Code: | -net nic,macaddr="$macaddr" -net tap,ifname=tap1,script=no,downscript=no |
I guess the benefit of using tap instead of plain br0 (and qemu-bridge-helper) is that it allows you to define custom option like, for example, MAC addresses for each tap in /etc/conf.d/net in a more unified way. And to avoid to have them in the scripts I use to launch my VMs for example (so no need to use macaddr option on qemu command line), it is much cleaner to have them in one place.
EDIT : Well, if you don't set the macaddr on qemu command line, then qemu creates a new one for the VM.. instead of using one set in mac_tap*
So below example is valid, the MAC address is set for the tap* device created but qemu doesn't use the MAC unless you pass it to the qemu command line.
I will end my experimentation here since the initial issue is resolved and this one is rather minor.
Code: | modules="dhclient"
config_eth0="null"
config_br0="192.168.1.19/24"
routes_br0="default via 192.168.1.1"
bridge_br0="eth0 tap1 tap2"
rc_net_br0_need="net.eth0 net.tap1 net.tap2"
mac_br0="mac address from eth0"
config_tap1="null"
tuntap_tap1="tap"
iproute2_tap1="user sdauth group kvm"
mac_tap1="mac for tap1 device"
config_tap2="null"
tuntap_tap2="tap"
iproute2_tap2="user sdauth group kvm"
mac_tap2="mac for tap2 device"
# [etc..]
bridge_forward_delay_br0=0
bridge_hello_time_br0=1000
bridge_stp_state_br0=0 |
|
|
Back to top |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|