Understanding QEMU host-guest access



Requirements for illustration:

host Sidux a "standard" debian like distro with qemu ,bridge-utils ,uml-utils using apt-get (from ubuntu_archive)
guest OS is dsl.iso DamnsmallLinux for light fast experimentation


  • In a host terminal "qemu -cdrom dsl.iso" starts up a virtual dsl linux from where one can browse the net. Host is then transparent to guest ;To access host,one needs to reveals the "connection point" to guest. This allows data transfer with scp ,or secure_copy,but it is only one way access guest to host.

  • In the second part wet will setup a bridge to get bidirectional access between host guest


  • A one way access



    qemu doc says : guest IP defaults to 10.0.2.15 and gateway IP to 10.0.2.2 .
    In fact when qemu switches on,it makes use of tap0 (a virtual nic allocated by tuntap_control using tunctl ,from uml-util)
    on the host side, the virtual vlan ( 10.0.0.0 )is unknown to host routing.To access host from guest ,just use :


    ssh user@10.0.2.2


    two ways access


    The following allows valid action at bootup

  • Create a bridge
    Put /etc/init.d/local where local contains a line brctl addbr br0
    add a link to /etc/rcS.d/S40local with
    ln -s /etc/init.d/local S40local

  • Setup the bridge,by modifying /etc/network/interfaces as follows
  • auto lo
              
    iface lo inet loopback

    auto br0
    iface br0 inet static

    address 192.168.1.6

    network 192.168.1.0

    netmask 255.255.255.0

    broadcast 192.168.1.255

    gateway 192.168.1.1

    bridge_fd 9

    bridge_hello 2

    bridge_maxage 12

    bridge_stp off

    pre-up /usr/sbin/tunctl -u wangji -t tap0

    pre-up /sbin/ifconfig tap0

    pre-up /usr/sbin/brctl addif br0 tap0

    pre-up /usr/sbin/brctl addif br0 eth0

    pre-up /usr/sbin/tunctl -u wangji -t tap1

    pre-up /sbin/ifconfig/ tap1

    pre-up /usr/sbin/brctl addif br0 tap1

    pre-up /sbin/ifconfig br0 up

    auto eth0
    iface eth0 inet dhcp


    post-down /sbin/ifconfig tap0 down

    post-down /usr/sbin/tunctl -d tap0


  • The iface script invoked by qemu
  • Put into /etc/qemu-ifup
    #!/bin/sh
    #sudo -p "Password for $0:" /sbin/ifconfig $1 172.20.0.1
    #the commented line was from original qemu binary.
    echo "Executing /etc/qemu-ifup"
    echo "Bringing up $1 for bridged mode..."
    sudo /sbin/ifconfig $1 promisc up
    sleep 2

  • The sudoers :most iface controls need root permission ;/etc/sudoers needs the following
  • Cmnd_Alias QEMU=/sbin/ifconfig, \
    /sbin/modprobe,/usr/sbin/tunctl, /usr/sbin/brctl,/sbin/ifup,/sbin/ifdown
    # User privilege specification
    root ALL=(ALL) ALL
    %local ALL=NOPASSWD: SHUTDOWN
    wangji ALL=NOPASSWD: QEMU


    Usage and explanation


    At boot,the lan setup gives the bridge IP as 192.168.1.6 ,with gateway already set as 192.168.1.1 (router adsl's IP )
    ,setups 2 taps and adds tap0 as well as eth0 (the real nic connected to router ) to bridge br0. then eth0_inet_dhcp negotiates with router to obtain ist IP ;
    host can then access to web;executing ifconfig shows only br0,lo and eth0.
    When one starts a qemu session with

    "qemu -net nic,vlan=0 -net tap,vlan=0,ifname=tap0 -cdrom dsl.iso "


    qemu invokes the script "/etc/qemu-ifup $ifname" to setup the iface connection between the virtual lan with tap0
    ,its dhcp allows the local_eth0 to obtain IP ,ie in our case here eth0_IP=192.168.1.11 with gateway the router's IP namely 192.168.1.1 .
    This can be verified with ifconfig inside qemu's dsl ,once the dsl linux got up.
    Just verify one accesses the web by clicking on the opening browser . In a terminal of this virtual dsl,let's check access to host with :


    ssh wangji@192.168.1.5

    To check access to guest from host we need ssh daemon,which in turn requires certification key pairs.
    In dsl's terminal create the keys with
  • sudo ssh-keygen -t rsa1 -f /etc/ssh/ssh_host_key

  • sudo ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key

  • sudo ssh-keygen -t dsa -f /etc/ssh/ssh_host_dsa_key

  • each time answer with return when asked for paraphrase !
    launch daemon with
  • sudo /usr/sbin/sshd

  • ( if kqemu had been modprobed before invoking qemu things go smoothly,and dsa key pairs generation would take less time !!!)
    Now from a host terminal we can
    ssh dsl@192.168.1.11

    If it happens we don't know dsl's password,go back to dsl's terminal and change it with
    sudo passwd dsl

    If it happens to segment fault,redo the second time ,one gets password changed for dsl !Then redo ssh access to guest as above !

    next fun : get 2 guests with tap0 and tap1 and full host access


    Just be careful,qemu set by default either nic's macaddress or tap's name if not specified on commandline. So to startup the two guests ,do :

    qemu -net nic , -net tap,ifname=tap0 -cdrom dsl.iso

    qemu -net nic ,macaddr=52:54:00:12:34:57 -net tap,ifname=tap1 -cdrom dsl.iso


    the 2nd line macaddress needs be specified to create a different virtual nic (the 1st beeing 52:54:00:12:34:56 by default)
    It is possible then to ssh from host to guest1 ,then ssh from guest1 to guest2,and ssh from guest2 to host
    All three access to www world thru gateway 's LAN .

    troubles



    look at
    cat /proc/net/dev
    ls /proc/sys/net/ipv4/conf