Page 1 of 2
Using dynamic host interfacing as non-root user
Posted: 19. Jul 2007, 19:54
by randomchance
My host machine is running Gentoo AMD64. I'm running the binary version of VBox 1.4 (app-emulation/virtualbox-bin), not the OSE version (app-emulation/virtualbox). Based on several sources, I've managed to put together a set of scripts that
should allow me to dynamically set up a tap interface that is owned by the user running VBox and add it to an existing bridge. Unfortunately, VBox doesn't seem to want to execute the scripts unless it is started by root.
Here's some background... I have my init scripts written to create the bridge interface (br0), add the actual physical interface (eth1) to the bridge, and obtain an IP address via DHCP at startup. I've also modified the udev rules to set the permissions of the /dev/net/tun device to 0666, and this has been verified by doing a ls -l /dev/net/. This all works fine and I end up with a working bridge interface (br0) and everything works fine on the host machine. I have installed (via emerge) virtualbox-bin and virtualbox-modules and I load the kernel module at boot time.
I have added my user (and the root user also) to the vboxusers group. I created the following scripts to create and destroy a tap interface:
vbox_up
Code: Select all
!#/bin/bash
#create the tap interface and make current user the owner
sudo /usr/sbin/tunctl –t $2 –u `whoami`
#bring it up unconfigured
sudo /sbin/ifconfig $2 up
#add the tap interface to the bridge (br0)
sudo /sbin/brctl addif br0 $2
vbox_down
Code: Select all
!#/bin/bash
#remove the tap interface from the bridge (br0)
sudo /sbin/brctl delif br0 $2
#destroy the tap interface
sudo /usr/sbin/tunctl –d $2
I also added the following line to my /etc/sudoers file
Code: Select all
%vboxusers ALL = NOPASSWD: /sbin/ifconfig, /sbin/brctl, /usr/bin/tunctl
so members of the vboxusers group can execute the necessary commands as root without having to enter a password. I placed the two scripts in /usr/bin (which is in the PATH) and did
Code: Select all
chown root:vboxusers vbox_up vbox_down
chmod a+x vbox_up vbox_down
to give vboxusers (and pretty much everybody else) permission to execute the scripts. I have verified that the scripts do indeed work for my non-root user by replacing the $2 with a specific interface name (vbox0) and executing them from a command shell as the non-root user. The interface is created correctly, is owned by the user that called the script, and is added to bridge - then it is cleanly removed from the bridge and destroyed by the other script. No passwords required for vboxusers, just as planned.
With the scripts working, I then changed Networking to 'Host Interface', typed 'vbox0' as the interface name, and added these scripts to the 'Startup Application' box (/usr/bin/vbox_up) and 'Terminate Application' box (/usr/bin/vbox_down). Now when VBox is started as root the tap interface is created and added to the bridge and works perfectly (I have connectivity in the WinXP guest and can ping back and forth between host and guest). When the VM is stopped the interface is destroyed - just as it should be. *However* when I start VBox as a non-root user and try to start the VM, I get the following error:
Failed to initialize Host Interface Networking.
VBox status code: -3100 (VERR_HOSTIF_INIT_FAILED).
Result Code: 0x80004005
Component: Console
No tap interface is created and the VM won't start. It appears that VBox will only execute the scripts as root - not as the non-root user. As mentioned above, I can execute the scripts from the command line as a non-root user and they work fine, but not from VBox. I also tried hard coding the interface (vbox0) in the scripts and it still doesn't work as non-root.
Am I overlooking something here, maybe some special execution method or permission - something OS related, or am I doing something wrong with VBox? I don't understand why I can execute my scripts from the command line as a non-root user, but VBox only executes them when started as root.
I have successfully started the VM as the non-root user by the following sequence
- execute the vbox_up script from the command line (replacing $2 with vbox0)
start VBox from the command line
start the VM
Doing it this way the VM starts and I have networking in the guest. When I'm done I close VBox and execute the vbox_down script (again replacing $2 with vbox0). While this works as long I only use one VM at a time, it is clumsy and still doesn't explain why VBox will execute the scripts as root but not as a non-root user.
Any ideas??
Thanks!
Posted: 19. Jul 2007, 23:30
by Joergle
I suspect that VBox doesn't get the complete environment of the host machine. This would explain why your user probably is not counted to the 'sudoers'.
I had a similar problem with system paths. This is what lets me think that your problem probably is caused by the same reason.
Posted: 20. Jul 2007, 01:10
by randomchance
Joergle wrote:I suspect that VBox doesn't get the complete environment of the host machine. This would explain why your user probably is not counted to the 'sudoers'.
I had a similar problem with system paths. This is what lets me think that your problem probably is caused by the same reason.
Perhaps I should try to chmod +s the ifconfg, tunctl, and brctl files and remove the sudo's from the scripts... Or maybe since root is the owner of the script files, I could chmod +s the scripts and and execute them as if the user was the root. I'm not sure if it works like that for scripts though. I guess I can try both ways and see what works. Another concern if VBox is not getting the complete environment is the `whoami` command in the tunctl statement. I wonder if that will come back right?
Okay, I'm now I'm off to try it out... Thanks for the help Joergle!
Posted: 20. Jul 2007, 01:24
by randomchance
Joergle - I just read your post about doing the same thing on SuSE and saw that you're using kdesu to run the scripts as root (instead of using sudo inside the scripts as I was doing). I think I'll take the sudo's out of the scripts and try that approach first since it means I don't have to change any permissions. If I understand right, kdesu authenticates via the sudoers file so maybe I can make a few mods there and find out what's going on...
Thanks!
Posted: 20. Jul 2007, 08:24
by randomchance
Okay, first I tried
Code: Select all
chmod +s on tunctl, brctl, and ifconfig
removed the sudo's from the scripts
no dice, VBox still won't execute the scripts. So I then tried
Code: Select all
/usr/kde/3.5/bin/kdesu -t vbox_up # in the Startup Application
/usr/kde/3.5/bin/kdesu -t vbox_down # in the Terminate Application
still no dice, VBox won't execute them.
I tried replacing tunclt in the scripts with VBoxTunctl. Turns out that VBoxTunctl won't work for anybody except root, even with sudo.
I finally ended up returning the scripts to the original commands and replacing the $2 with a hard-coded interface name. I then made a simple wrapper script for virtualbox that executes the vbox_up script to create the tap interface, runs VBox, and then executes the vbox_down script when virtualbox exits. This works and allows me to use dynamic host interfacing as a regular user. The catch is that the _up and _down scripts must be modified to create and destroy a different tap interface for each new VM I create that uses host interfacing. Primitive, but it works.
This seems to me to be a serious flaw in an otherwise excellent program. I have used VMWare Server to run my windows guests and I've never had any problem with bridging as a regular user there. I prefer VirtualBox because it runs windows *MUCH* smoother and faster than VMWare. When I go full screen, its almost indistinguishable from my native windows install. There are still a few things that I like better about VMWare (like the ability to control what is presented on the IDE bus, i.e. I can give the VM *both* of my DVD drives instead of having to switch one virtual drive between the two physical drives, and the fact that hardware monitors just hang but do not kill the VM in VMWare), but that is not enough to make me switch back.
If VBox would run the Startup and Terminate scripts as a non-root user it would be just about perfect I think. Although I can't get the shared folders to work (I've added them using VBoxManage and they show up as Machine Shares - I just can't access them in the WinXP guest), Samba allows me to share folders between the host and guest just fine. Maybe someone who knows more than I do can track down the root cause of this not-executing-the-scripts problem and present a way to fix it. Until then I'll stick with my simple wrapper script so that I can use VBox as my virtualization platform. Its definitely worth the headache it has been...
Posted: 20. Jul 2007, 10:00
by Joergle
Hi there, glad to hear that you made it!
Absolutely agree with what you said. There seems to be some trouble in dealing with the environment and privileges. I don't have the full picture yet, but some things are not as I would wish them to be.
Other than that I also agree with your judgement about the VBox in general. For me it works a lot smoother (and faster) as the VMWare ever did.
Posted: 10. Jul 2008, 15:31
by NickLeverton
I know this thread is a year old but, since I ran into the same problem it might be worth documenting a solution.
When you use sudo to invoke the dynamic interface scripts, sudo sanitises the environment and removes all non-essential environment variables. So your script cannot tell which user is actually running it.
There are a number of ways round it but most of them involve editing /etc/sudoers in arcane and not-well-documented ways. But one quick simple way is to pass the username into the script when you run it. I don't know how to make kdesu and friend do this, but with sudo you can do something like this:
sudo LOGNAME=$LOGNAME /usr/local/bin/vbox_up
then use $LOGNAME inside your script when you want the user name. Or of course you can just hard code your username as the user docs suggest but it's a bit kludgy !
Incidentally running the entire script under sudo as above means you only need to add the script name to /etc/sudoers, rather than all of ifconfig, brctl and tunctl.
Posted: 10. Jul 2008, 16:34
by TerryE
Thanks Nick. A useful post. One to remember.
Posted: 27. Jul 2008, 05:32
by bundabrg
I'll have dig out my dynamic script I use, but essentially it does this: -
Assuming a Vbox Guest has 3 networkcards. In my config file (I use my own config that generates the VBox Config) I have a line:
What that means, is that I want the VM to have 3 network cards, the first bridged to eth0, the second to eth0 and the third to eth1.
My script does the following: -
- If not created, creates a bridge called 'br_<realinterfacename>'. IE, 'br_eth0'.
- Adds (if not already added) realinterface to that bridge. IE, 'brctl addif br_eth0 eth0'
- Creates a new TAP interface using VBoxTunCtl called 'br_<realinterface>_v<intnumber>'. For example, 'br_eth0_v1' and 'br_eth0_v2'.
- Adds that TAP device to the bridge
- Instructs Virtualbox to now use that virtual inteface
Phew, so by the end I have in total on my host (for this vm): -
Code: Select all
eth0
eth1
br_eth0
br_eth1
br_eth0_v1
br_eth0_v2
br_eth1_v1
- Brendan
Posted: 5. Sep 2008, 15:17
by sej7278
Seeing as how bridged networking has always put me off VirtualBox and I've now got working 2.0.2/2.0.6 CentOS 5.2 and Fedora 9/10 systems setup, I thought I'd share how I did it, and how I've got around some of the issues mentioned above.
I wanted a permanent bridge, but dynamic taps, with fixed IP for guests (and host) and wanted to access LAN and WAN.
1. Created /etc/sysconfig/network-scripts/ifcfg-br0:
Code: Select all
DEVICE=br0
TYPE=Bridge
ONBOOT=yes
BOOTPROTO=static
IPADDR=192.168.0.6
NETMASK=255.255.255.0
NETWORK=192.168.0.0
BROADCAST=192.168.0.255
GATEWAY=192.168.0.1
NOZEROCONF=yes
2. Removed IP config for the physical interface (that's now in br0 above); /etc/sysconfig/network-scripts/ifcfg-eth0:
Code: Select all
DEVICE=eth0
BOOTPROTO=static
ONBOOT=yes
BRIDGE=br0
3. As I can never get UDEV changes to work on CentOS 5.2, I added this to /etc/security/console.perms.d/50-default.perms so that anyone in the vboxusers group can write to /dev/net/tun:
Code: Select all
<tunnel>=/dev/net/tun
<console> 0660 <tunnel> 0660 root.vboxusers
4. added my user to vboxusers group, if you want CD/DVD burner access you might also need to add yourself to the disk group:
Code: Select all
usermod -a -G vboxusers,disk myusername
5. setup /etc/sudoers to not require a password for the whole script, also remove the requirement for a TTY - this is the problem that stops you running sudo as part of the startup command for host networking as its running from a QT GUI, not a TTY:
Code: Select all
#Defaults requiretty
myusername ALL = NOPASSWD: /usr/local/vbox/setuptap.sh, /usr/local/vbox/cleanuptap.sh
6. created /usr/local/vbox/cleanuptap.sh, this is based on the script in the userguide.pdf - chmod a+x it to make it executable:
Code: Select all
#!/bin/bash
/usr/sbin/brctl delif br0 $2
/usr/bin/VBoxTunctl -d $2
7. created /usr/local/vbox/setupuptap.sh:
Code: Select all
#!/bin/bash
interface=`/usr/bin/VBoxTunctl -b -u myusername`
if [ -z "$interface" ]; then
exit 1
fi
echo $interface
/sbin/ifconfig $interface up
/usr/sbin/brctl addif br0 $interface
Then call /usr/sbin/sudo /usr/local/vbox/setuptap.sh as the startup, and cleanuptap.sh as the shutdown script.
8. REMOVED (ip forwarding is not required).
9. allow forwarding from the br0 interface in /etc/sysconfig/iptables:
10. Additionally, for USB support add the following to /etc/fstab - assuming the vboxusers group was gid=502:
Code: Select all
none /sys/bus/usb/drivers usbfs devgid=502,devmode=664 0 0
I also checked for config files where I had bound to the eth0 interface - such as iptables, samba etc.
I'm not particularly happy with the security implications of this method - you've got to lower permissions on the tunnel, disk and usb devices, enable IP forwarding in the kernel, drop the firewall level, lower the security of sudo..... VMWare still does it much better.
Posted: 2. Dec 2008, 11:50
by skoehler
Here's a more advanced script, that catches most errors and most important:
it deleted the just created tap interface if something fails.
Code: Select all
#!/bin/bash
p_vboxtunctl="/usr/bin/VBoxTunctl"
p_ifconfig="/sbin/ifconfig"
p_brctl="/sbin/brctl"
user="$SUDO_USER"
bridgename="br0"
ifname=""
die() {
echo "error: $1" 1>&2
[ -n "$ifname" ] && "$p_vboxtunctl" -d "$ifname" >/dev/null
exit 1
}
testexec() {
[ -x "$1" ] || die "$1 is not executable"
}
testexec "$p_vboxtunctl"
testexec "$p_ifconfig"
testexec "$p_brctl"
#TODO test for bridge
[ -n "$user" ] || die "username unknown"
ifname=$("$p_vboxtunctl" -b -u "$user")
[ -n "$ifname" ] || die "no interface name"
"$p_ifconfig" "$ifname" up || die "could not up interface"
"$p_brctl" addif "$bridgename" "$ifname" || die "could not add interface to bridge"
echo "$ifname"
Posted: 3. Dec 2008, 07:21
by cdolson
Hello skoehler,
Please excuse my newbishness - but I am trying to learn some more advanced linux techniques and at the same time trying to get VBox working with host networking, with some understandable difficulties.
I initially used the advice found in the help manual for VirtualBox, but found when I rebooted my Ubuntu 8.10 installation, the host could not reach the internet, but the guest in VBox could.
That aside, I've been looking into other options in my quest for knowledge - which has led me to your script.
I was hoping you could answer just one question for me (for the moment): Why do I get the error "/sbin/brctrl is not executable", and how should I fix it?
If I try to invoke brctrl directly from the shell it seems to run fine, so I am not sure where I am going wrong here.
Posted: 3. Dec 2008, 12:09
by sej7278
try "which brctl" to find where its installed for you, for instance on fedora its /usr/sbin/brctl
Posted: 3. Dec 2008, 17:39
by cdolson
Perfect! That worked. Thank you!
Now, host networking seems to work perfectly by adding the script to the network startup scripts in VBox, using gksudo.
What would be the proper way to take down the tap0 interface, and is this even necessary?
Thanks again for your help. This script is going to be a lifesaver.
Posted: 3. Dec 2008, 18:48
by cdolson
This is a bit off the specific topic, but somewhat related.
I seem to be having an issue creating the bridge, br0, and having my eth0 port continue to work on it.
I am using Ubuntu Intrepid, 8.10.
Before adding entries to the /etc/network/interfaces file, it looks like this:
auto lo
iface lo inet loopback
It seems as though the NetworkManager Applet does all the network configurations automagically in Ubuntu.
So, to get a working bridge created, I add this to the interfaces file, and restart networking:
auto br0
iface br0 inet dhcp
bridge_ports eth0
This creates a bridge, and maps eth0 to the bridge. Both eth0 and the bridge then have the same IP Address.
So, this setup enables your script to work. This seems to work fine for the first 5 or 10 minutes, but then I lose all connectivity via the host system. I cannot ping anything, or open web pages via the Ubuntu host, however it all works in the guest.
I receive replies to my pings from the brdige, seemingly, Destination Unreachable replies from 192.168.1.77.
Also, after reboot, the host system is still unable to access the network.
I have a feeling that there is a problem with how I am configuring the interfaces file to create the br0 bridge. Does anyone know what may be the issue here?