Re: [Qemu-devel] [PATCH 4/4] Add support for -net bridge
Avi Kivity wrote: On 11/08/2009 12:11 AM, Anthony Liguori wrote: You don't need root privileges to use a tap device. You can access a preconfigured tap device but you cannot allocate a tap device and connect it to a bridge without CAP_NET_ADMIN. btw, shouldn't we, in the general case, create a bridge per user and use IP NAT? If we have a global bridge, users can spoof each other's MAC addresses and interfere with their virtual machines. qemu-bridge-helper supports that model quite well :-) You would create a NAT'd bridge for each user as the administrator, then create a bridge.conf that consisted of per-user includes with appropriate permissions set on each of those files. They can also interfere with the real network. That's not a concern with most one-user-per-machine configurations, but the default configuration should be safe. Let's not kid ourselves, no matter what we do we're giving a user elevated privileges. Even with NAT, if the host can access the NAT'ed network, then you can run a privileged service (like NFS) in that network. Like it or not, some networks rely on privileged services being trusted as part of their security model (consider NIS). I think the best we can do is provide a tool that allows an administrator to grant users additional privileges in the tiniest increments possible. Putting people in wheel just so they can do virtualization is too much. I don't see having an fscap-based helper as creating policy. I see it as adding a mechanism for administrators to create policy. -- Regards, Anthony Liguori
Re: [Qemu-devel] [PATCH 4/4] Add support for -net bridge
Anthony Liguori wrote: Let's not kid ourselves, no matter what we do we're giving a user elevated privileges. Even with NAT, if the host can access the NAT'ed network, then you can run a privileged service (like NFS) in that network. I don't see how outgoing NAT (SNAT), where the guest can make _outgoing_ connections to the network, allows the guest to run a privileged service accessible to the network. Sure, the guest can run an NFS server, but it means nothing to the outside - it's on the guest's own private little network. Same as Slirp. The guest cannot even make an outgoing request which appears to come from an privileged port - if the SNAT rule has the appropriate options to force the port into an unprivileged range. For the guest's NFS server to be visible to the network requires incoming NAT (DNAT) on the host, often called port forwarding. But that is done by explicit administration; if you can do that, you can run a privileged service on the host anyway. I think the best we can do is provide a tool that allows an administrator to grant users additional privileges in the tiniest increments possible. Putting people in wheel just so they can do virtualization is too much. I don't see having an fscap-based helper as creating policy. I see it as adding a mechanism for administrators to create policy. I agree with both of these. -- Jamie
Re: [Qemu-devel] [PATCH 4/4] Add support for -net bridge
Jamie Lokier wrote: Anthony Liguori wrote: Let's not kid ourselves, no matter what we do we're giving a user elevated privileges. Even with NAT, if the host can access the NAT'ed network, then you can run a privileged service (like NFS) in that network. I don't see how outgoing NAT (SNAT), where the guest can make _outgoing_ connections to the network, allows the guest to run a privileged service accessible to the network. Sure, the guest can run an NFS server, but it means nothing to the outside - it's on the guest's own private little network. Same as Slirp. The guest cannot even make an outgoing request which appears to come from an privileged port - if the SNAT rule has the appropriate options to force the port into an unprivileged range. For the guest's NFS server to be visible to the network requires incoming NAT (DNAT) on the host, often called port forwarding. But that is done by explicit administration; if you can do that, you can run a privileged service on the host anyway. You are correct except that I qualified this as NAT with host access which so far is the common model. If the host can access the NAT'd network behind the NAT, then port privileges are important. -- Regards, Anthony Liguori
Re: [Qemu-devel] [PATCH 4/4] Add support for -net bridge
Anthony Liguori wrote: You are correct except that I qualified this as NAT with host access which so far is the common model. If the host can access the NAT'd network behind the NAT, then port privileges are important. You're right. This is why QEMU guests should be run inside an LXC container :-) Or in the general case, a security-conscious net-setup script should ensure general user invocations are limited to admin-decided subnets with admin-decided firewall rules, so that they just look like processes with ordinary access to everything else. Iptables being what it is, that'd have to be distro specific and sometimes site specific. -- Jamie
Re: [Qemu-devel] [PATCH 4/4] Add support for -net bridge
On 11/08/2009 12:11 AM, Anthony Liguori wrote: You don't need root privileges to use a tap device. You can access a preconfigured tap device but you cannot allocate a tap device and connect it to a bridge without CAP_NET_ADMIN. btw, shouldn't we, in the general case, create a bridge per user and use IP NAT? If we have a global bridge, users can spoof each other's MAC addresses and interfere with their virtual machines. They can also interfere with the real network. That's not a concern with most one-user-per-machine configurations, but the default configuration should be safe. -- error compiling committee.c: too many arguments to function
Re: [Qemu-devel] [PATCH 4/4] Add support for -net bridge
On Sunday 08 November 2009 08:27:41 Avi Kivity wrote: On 11/08/2009 12:11 AM, Anthony Liguori wrote: You don't need root privileges to use a tap device. You can access a preconfigured tap device but you cannot allocate a tap device and connect it to a bridge without CAP_NET_ADMIN. btw, shouldn't we, in the general case, create a bridge per user and use IP NAT? If we have a global bridge, users can spoof each other's MAC addresses and interfere with their virtual machines. They can also interfere with the real network. That's not a concern with most one-user-per-machine configurations, but the default configuration should be safe. It also depends a lot on what you want to do with the virtual machine. If you want to run a game or a legacy application in a different operating system on your desktop, a NATed bridge is ideal, but it does not work on a server if the guest wants to listen on a socket with its own IP address. Arnd
Re: [Qemu-devel] [PATCH 4/4] Add support for -net bridge
On 11/08/2009 10:43 AM, Arnd Bergmann wrote: btw, shouldn't we, in the general case, create a bridge per user and use IP NAT? If we have a global bridge, users can spoof each other's MAC addresses and interfere with their virtual machines. They can also interfere with the real network. That's not a concern with most one-user-per-machine configurations, but the default configuration should be safe. It also depends a lot on what you want to do with the virtual machine. If you want to run a game or a legacy application in a different operating system on your desktop, a NATed bridge is ideal, but it does not work on a server if the guest wants to listen on a socket with its own IP address. Yes. It also depends on what the system administrator wants you to be able to do. On desktop machines you are usually the system administrator so there is no problem. But we should beware of making it easy to subvert security. There is also the problem of accidental MAC overlap - qemu uses the same MAC address for all virtual machines unless overridden, so if two users create a virtual machine without specifying MAC addresses they will trample each other. A single user could also have trouble launching two guests; that's not a security problem, but will lead to a lot of annoyance and false bug reports (networking dies as soon as I launch a second guest). -- error compiling committee.c: too many arguments to function
Re: [Qemu-devel] [PATCH 4/4] Add support for -net bridge
On Tue, 2009-11-03 at 18:28 -0600, Anthony Liguori wrote: The most common use of -net tap is to connect a tap device to a bridge. This requires the use of a script and running qemu as root in order to allocate a tap device to pass to the script. Does it? Tap devices can be created (and configured) in advance, and can be chowned so that they can be opened by an otherwise unprivileged user (or group). You don't need root privileges to use a tap device. -- dwmw2
Re: [Qemu-devel] [PATCH 4/4] Add support for -net bridge
David Woodhouse wrote: On Tue, 2009-11-03 at 18:28 -0600, Anthony Liguori wrote: The most common use of -net tap is to connect a tap device to a bridge. This requires the use of a script and running qemu as root in order to allocate a tap device to pass to the script. Does it? Tap devices can be created (and configured) in advance, and can be chowned so that they can be opened by an otherwise unprivileged user (or group). But that requires prior administrative access. You don't need root privileges to use a tap device. You can access a preconfigured tap device but you cannot allocate a tap device and connect it to a bridge without CAP_NET_ADMIN. Regards, Anthony Liguori
Re: [Qemu-devel] [PATCH 4/4] Add support for -net bridge
Anthony Liguori wrote: Avi Kivity wrote: +int net_init_bridge(QemuOpts *opts, Monitor *mon, const char *name, VLANState *vlan); + Don't we need to tear the interface down after shutdown? net_init_bridge calls net_tap_fd_init which registers tap_cleanup. That closes the fd and frees associated memory. The helper does not allocate a persistent tap device so closing the file descriptor is sufficient for cleanup. I think you should at least have the option to call a/the helper when cleaning up too. For the same reason that -net downscript= was added. (From the names I get the impression that was added later than -net script=, perhaps due to the same kind of oversight ;-) A user-supplied helper (I'm thinking of my needs) would create per-tap iptables/ebtables rules and perhaps routing table entries, in addition to creating the tap interface itself. Routing table entries are automatically deleted when the interface is, but iptables/ebtables rules are not. (Although it would be a nice little kernel addition if they could be flagged to be.) But now, thinking a bit more clearly... why is the helper separate from -net script=? Overall, I envisage this happening (sorry for making up the name tap-up-helper, as I seem to have lost your patch mails): tap-up-helper= # Sets up tap interface, adds to bridge if needed. script= # Sets up IP config QEMU runs downscript= # Removes IP config tap-down-helper=# If only for symmetry! We does tap-up-helper need to be separate from script? Does QEMU need to do something in between calling the two? If not, then the existing -net script= script could just send the tap descriptor as well as anything else it does, couldn't it? -- Jamie
RE: [Qemu-devel] [PATCH 4/4] Add support for -net bridge
Hello Anthony, Now that I have read the whole series I say again great patch. -Original Message- From: qemu-devel-bounces+chris.krumme=windriver@nongnu.org [mailto:qemu-devel-bounces+chris.krumme=windriver@nongnu.o rg] On Behalf Of Anthony Liguori Sent: Tuesday, November 03, 2009 6:28 PM To: qemu-devel@nongnu.org Cc: Mark McLoughlin; Anthony Liguori; Arnd Bergmann; Dustin Kirkland; Michael Tsirkin; Juan Quintela Subject: [Qemu-devel] [PATCH 4/4] Add support for -net bridge The most common use of -net tap is to connect a tap device to a bridge. This requires the use of a script and running qemu as root in order to allocate a tap device to pass to the script. This model is great for portability and flexibility but it's incredibly difficult to eliminate the need to run qemu as root. The only really viable mechanism is to use tunctl to create a tap device, attach it to a bridge as root, and then hand that tap device to qemu. The problem with this mechanism is that it requires administrator intervention whenever a user wants to create a guest. By essentially writing a helper that implements the most common qemu-ifup script that can be safely given cap_net_admin, we can dramatically simplify things for non-privileged users. We still support -net tap as a mechanism for advanced users and backwards compatibility. Currently, this is very Linux centric but there's really no reason why it couldn't be extended for other Unixes. A typical invocation of -net bridge would be: qemu -net bridge -net nic,model=virtio The default bridge that we attach to is qemubr0. The thinking is that a distro could preconfigure such an interface to allow out-of-the-box bridged networking. Alternatively, if a user wants to use a different bridge, they can say: qemu -net bridge,br=br0 -net nic,model=virtio Signed-off-by: Anthony Liguori aligu...@us.ibm.com --- configure |1 + net.c | 20 +++- net/tap.c | 142 +++ net/tap.h |2 + qemu-options.hx |3 + 5 files changed, 167 insertions(+), 1 deletions(-) diff --git a/configure b/configure index 7c9d3a2..55a1a4f 100755 --- a/configure +++ b/configure @@ -1896,6 +1896,7 @@ echo $config_host_mak echo CONFIG_QEMU_SHAREDIR=\$prefix$datasuffix\ $config_host_mak echo CONFIG_QEMU_CONFDIR=\/etc/qemu\ $config_host_mak +echo CONFIG_QEMU_HELPERDIR=\$prefix/libexec\ $config_host_mak case $cpu in i386|x86_64|alpha|cris|hppa|ia64|m68k|microblaze|mips|mips64|p pc|ppc64|s390|sparc|sparc64) diff --git a/net.c b/net.c index 37662c6..54a7a5b 100644 --- a/net.c +++ b/net.c @@ -2541,6 +2541,22 @@ static struct { }, { /* end of list */ } }, +}, { +.type = bridge, +.init = net_init_bridge, +.desc = { +NET_COMMON_PARAMS_DESC, +{ +.name = br, +.type = QEMU_OPT_STRING, +.help = bridge name, +}, { +.name = helper, +.type = QEMU_OPT_STRING, +.help = command to execute to configure bridge, +}, +{ /* end of list */ } +}, }, { /* end of list */ } }; @@ -2565,7 +2581,8 @@ int net_client_init(Monitor *mon, QemuOpts *opts, int is_netdev) #ifdef CONFIG_VDE strcmp(type, vde) != 0 #endif -strcmp(type, socket) != 0) { +strcmp(type, socket) != 0 +strcmp(type, bridge) != 0) { qemu_error(The '%s' network backend type is not valid with -netdev\n, type); return -1; @@ -2641,6 +2658,7 @@ static int net_host_check_device(const char *device) #ifdef CONFIG_VDE ,vde #endif + , bridge }; for (i = 0; i sizeof(valid_param_list) / sizeof(char *); i++) { if (!strncmp(valid_param_list[i], device, diff --git a/net/tap.c b/net/tap.c index bdb4a15..f5abed6 100644 --- a/net/tap.c +++ b/net/tap.c @@ -436,3 +436,145 @@ int net_init_tap(QemuOpts *opts, Monitor *mon, const char *name, VLANState *vlan return 0; } + +#define DEFAULT_BRIDGE_INTERFACE qemubr0 +#define DEFAULT_BRIDGE_HELPER CONFIG_QEMU_HELPERDIR /qemu-bridge-helper + +static int recv_fd(int c) +{ +int fd; +uint8_t msgbuf[CMSG_SPACE(sizeof(fd))]; +struct msghdr msg = { +.msg_control = msgbuf, +.msg_controllen = sizeof(msgbuf), +}; +struct cmsghdr *cmsg; +struct iovec iov; +uint8_t req[1]; +ssize_t len; + +cmsg = CMSG_FIRSTHDR(msg); +cmsg-cmsg_level = SOL_SOCKET; +cmsg-cmsg_type = SCM_RIGHTS; +cmsg-cmsg_len = CMSG_LEN(sizeof(fd)); +msg.msg_controllen =
Re: [Qemu-devel] [PATCH 4/4] Add support for -net bridge
Krumme, Chris wrote: Do you need to mention the default name qemubr0 here? Good suggestion. Regards, Anthony Liguori