Bug 1001773
Summary: | [RFE] virt-manager: Add ability to pull system entropy from host | ||||||
---|---|---|---|---|---|---|---|
Product: | Red Hat Enterprise Linux 7 | Reporter: | Amit Shah <amit.shah> | ||||
Component: | virt-manager | Assignee: | Giuseppe Scrivano <gscrivan> | ||||
Status: | CLOSED CURRENTRELEASE | QA Contact: | Virtualization Bugs <virt-bugs> | ||||
Severity: | medium | Docs Contact: | |||||
Priority: | high | ||||||
Version: | 7.0 | CC: | acathrow, akong, amit.shah, areis, bcao, bsarathy, crobinso, dallan, dayleparker, dyuan, juzhang, kseifried, lagarcia, laine, lcui, lnovich, mazhang, mhomolov, michen, mkenneth, mkletzan, mzhan, pkrempa, qzhang, sgrubb, shu, sradvan, tburke, trichard, tzheng, virt-maint | ||||
Target Milestone: | rc | Keywords: | FutureFeature | ||||
Target Release: | --- | ||||||
Hardware: | Unspecified | ||||||
OS: | Unspecified | ||||||
Whiteboard: | |||||||
Fixed In Version: | virt-manager-0.10.0-5.el7 | Doc Type: | Enhancement | ||||
Doc Text: | Story Points: | --- | |||||
Clone Of: | 1001770 | Environment: | |||||
Last Closed: | 2014-06-13 11:00:37 UTC | Type: | --- | ||||
Regression: | --- | Mount Type: | --- | ||||
Documentation: | --- | CRM: | |||||
Verified Versions: | Category: | --- | |||||
oVirt Team: | --- | RHEL 7.3 requirements from Atomic Host: | |||||
Cloudforms Team: | --- | Target Upstream Version: | |||||
Embargoed: | |||||||
Bug Depends On: | 786407, 1001770 | ||||||
Bug Blocks: | 896690, 786408, 883503, 969788, 973003, 973416, 973871, 989636, 989641 | ||||||
Attachments: |
|
the error at point "6" is generated by libvirt. I am not sure whether mode="bind" is supposed to work with UDP or not, but in both cases I would prefer to not check for it in virt-manager and let libvirt generates the error, if any. If libvirt doesn't support mode="bind" with UDP, then probably the error string should be improved. (I've set NEEDINFO to Peter, please change it if not correct) UDP socket chardev is just a data channel. If qemu set a connect UDP socket(client), you should create a listen UDP socket(server), and write the random data to remote socket when client connects the server. If qemu set a listen UDP socket, you should create a connect UDP socket, and try to connect the server socket, and write data to remote socket. It's same with TCP socket, or unix socket. ---- For point 5: you can server the UDP server first # cat /dev/random | nc -U -l 1025 then launch qemu guest. I'd say TCP mode bind is supported, but you used "nc -l" to feed it, but mode bind means qemu is listening as well, so you need to connect there. That means running the guest and then sending is something (to "nc localhost 1024"). Could you re-check that? Other than that the UDP option sould be changed. In case UDP is selected, both bind and connect sources need to be defined to know where to send requests and where to get the responses from. (In reply to Martin Kletzander from comment #9) > I'd say TCP mode bind is supported, but you used "nc -l" to feed it, but > mode bind means qemu is listening as well, so you need to connect there. > That means running the guest and then sending is something (to "nc localhost > 1024"). Could you re-check that? > > Other than that the UDP option sould be changed. In case UDP is selected, > both bind and connect sources need to be defined to know where to send > requests and where to get the responses from. the TCP mode bind, I run the guest and then use # cat /dev/urandom | nc localhost 1024. I can get the random number in the guest by # cat /dev/hwrng this is the XML I get on my machine, trough virt-manager, when I try to set up an EGD device over UDP: --- Original XML +++ New XML @@ -75,5 +75,10 @@ <memballoon model="virtio"> <address type="pci" domain="0x0000" bus="0x00" slot="0x07" function="0x0"/> </memballoon> + <rng model="virtio"> + <backend model="egd" type="udp"> + <source mode="bind" host="localhost" service="708"/> + </backend> + </rng> </devices> </domain> and I get the same error (as described at point 6): internal error: Missing source service attribute for char device Can you confirm this behaviour? If this is the case, the problem seems to be in libvirt. I have also tried manually in virsh dropping the additional "host" attribute, and I get the same error. (In reply to Giuseppe Scrivano from comment #11) The thing is, that EGD works both ways (one way request, second way response) and with UDP you need to know where to send the request and where to wait for the response, so you need both source mode='bind' and mode='connect' elements. The only problem is that if you don't supply bind, but supply connect (with UDP), there will be no error produced. The reason behind this is that qemu is happy when it has somewhere to send the request and doesn't care if there is no way for incoming data to get in. That's why we should remove the "bind/connect" option when UDP is selected in that dialog and force user to fill in both addresses (one for listening to data and one for sending requests). This is not needed for TCP, of course. Test with the latest packages below:
# rpm -qa libvirt qemu-kvm virt-manager
virt-manager-0.10.0-5.el7.noarch
libvirt-1.1.1-10.el7.x86_64
qemu-kvm-1.5.3-11.el7.x86_64
1.Add udp backend rng device as below:
# virsh dumpxml T | grep rng -A 5
<rng model='virtio'>
<backend model='egd' type='udp'>
<source mode='bind' host='localhost' service='1024'/>
<source mode='connect' host='localhost' service='1708'/>
</backend>
</rng>
</devices>
</domain>
Feed the VM rng device by python script
# python
Python 2.7.4 (default, May 6 2013, 07:26:49)
[GCC 4.8.0 20130419 (Red Hat 4.8.0-3)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import socket
>>> UDP_IP = "127.0.0.1"
>>> UDP_PORT = 1708
>>> sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
>>> sock.bind((UDP_IP, UDP_PORT))
>>> while True:
... data, addr = sock.recvfrom(1024)
... print "SEND DATA"
... sock.sendto ("AB" * 1024, addr)
Start the VM, and try to get random data by
#dd if=/dev/hwrng of=/tmp/udp_test
Can't get the random data.
2. I can get random data for random type rng device and TCP backend device(both bind and connect).
Based on the above mentioned steps, I assign the bug.
can you please post the command line arguments to qemu? Could you also run a packet sniffer, such as wireshark, to debug your local UDP traffic and check if qemu is requesting any data (I've found useful to set this filter in wireshark to avoid noise: "udp.dstport==1708 or udp.srcport==1708")? This is the configuration I am using here: libvirt XML configuration (obtained trough virt-manager): <rng model='virtio'> <backend model='egd' type='udp'> <source mode='bind' host='127.0.0.1' service='1710'/> <source mode='connect' host='127.0.0.1' service='1708'/> </backend> </rng> arguments to qemu I get: "-chardev udp,id=charrng0,host=127.0.0.1,port=1708,localaddr=127.0.0.1,localport=1710 -object rng-egd,chardev=charrng0,id=rng0 -device virtio-rng-pci,rng=rng0,bus=pci.0,addr=0x8" I am using this python script to feed data to the rng virtio device: #################################################################### import socket UDP_IP = "127.0.0.1" UDP_PORT = 1708 sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) sock.bind((UDP_IP, UDP_PORT)) while True: data, addr = sock.recvfrom(1024) print "SEND DATA" sock.sendto ("AB" * 1024, addr) #################################################################### and on the guest machine, that is running Fedora 19 (kernel: 3.11.6-200.fc19.i686 #1 SMP Fri Oct 18 23:00:01 UTC 2013 i686 i686 i386 GNU/Linux), I can do: [root@localhost giuseppe]# head -c2 /dev/hwrng; echo AB [root@localhost giuseppe]# head -c2 /dev/hwrng; echo AB Noteworthy, I am using the development version of qemu: v1.4.0-4479-gec426ff Created attachment 820191 [details]
udp by wireshark
Hi, Giuseppe Scrivano
# rpm -qa libvirt virt-manager qemu-kvm kernel
virt-manager-0.10.0-5.el7.noarch
qemu-kvm-1.5.3-10.el7.x86_64
libvirt-1.1.1-11.el7.x86_64
# virsh dumpxml r65 | grep rng -A 10
<rng model='virtio'>
<backend model='egd' type='udp'>
<source mode='bind' host='127.0.0.1' service='1710'/>
<source mode='connect' host='127.0.0.1' service='1708'/>
</backend>
</rng>
the arguments sent to qemu:
..-chardev udp,id=charrng0,host=127.0.0.1,port=1708,localaddr=127.0.0.1,localport=1710 -object rng-egd,chardev=charrng0,id=rng0 -device virtio-rng-pci,rng=rng0,bus=pci.0,addr=0x8
Use the script to feed rng device
####################################################################
import socket
UDP_IP = "127.0.0.1"
UDP_PORT = 1708
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind((UDP_IP, UDP_PORT))
while True:
data, addr = sock.recvfrom(1024)
print "SEND DATA"
sock.sendto ("AB" * 1024, addr)
####################################################################
I export the package dissection as plain txt and attach it in the bug.
Also I use tcpdump to dump the traffic on port 1708
# tcpdump -n -vv "dst host 127.0.0.1 and (dst port 1708 or src port 1708)"
tcpdump: WARNING: macvtap0: no IPv4 address assigned
tcpdump: listening on macvtap0, link-type EN10MB (Ethernet), capture size 65535 bytes
^C
0 packets captured
0 packets received by filter
0 packets dropped by kernel
3 packets dropped by interface
In the guest, no random data is generated:
[root@localhost ~]# head -c2 /dev/hwrng; echo
^C
I was able to get it to work on RHEL-7. I have used a Fedora 19 live CD as guest OS. # rpm -qa libvirt virt-manager qemu-kvm kernel kernel-3.10.0-29.el7.x86_64 virt-manager-0.10.0-5.el7.noarch qemu-kvm-1.5.3-13.el7.x86_64 kernel-3.10.0-33.el7.x86_64 this is the complete "virsh dumpxml test" output for the virtual machine I have used: <domain type='qemu' id='5'> <name>test</name> <uuid>3bc753b7-1580-4b52-98d7-1fe60d3114ee</uuid> <memory unit='KiB'>1536000</memory> <currentMemory unit='KiB'>1536000</currentMemory> <vcpu placement='static'>1</vcpu> <resource> <partition>/machine</partition> </resource> <os> <type arch='x86_64' machine='pc-i440fx-rhel7.0.0'>hvm</type> <boot dev='cdrom'/> </os> <features> <acpi/> <apic/> <pae/> </features> <clock offset='utc'/> <on_poweroff>destroy</on_poweroff> <on_reboot>restart</on_reboot> <on_crash>restart</on_crash> <devices> <emulator>/usr/libexec/qemu-kvm</emulator> <disk type='file' device='cdrom'> <driver name='qemu' type='raw'/> <source file='/home/giuseppe/Fedora-19.iso'/> <target dev='hdc' bus='ide'/> <readonly/> <alias name='ide0-1-0'/> <address type='drive' controller='0' bus='1' target='0' unit='0'/> </disk> <controller type='usb' index='0'> <alias name='usb0'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/> </controller> <controller type='pci' index='0' model='pci-root'> <alias name='pci.0'/> </controller> <controller type='ide' index='0'> <alias name='ide0'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/> </controller> <controller type='virtio-serial' index='0'> <alias name='virtio-serial0'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/> </controller> <interface type='network'> <mac address='52:54:00:4d:ff:22'/> <source network='default'/> <target dev='vnet0'/> <model type='virtio'/> <alias name='net0'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> </interface> <serial type='pty'> <source path='/dev/pts/1'/> <target port='0'/> <alias name='serial0'/> </serial> <console type='pty' tty='/dev/pts/1'> <source path='/dev/pts/1'/> <target type='serial' port='0'/> <alias name='serial0'/> </console> <channel type='spicevmc'> <target type='virtio' name='com.redhat.spice.0'/> <alias name='channel0'/> <address type='virtio-serial' controller='0' bus='0' port='1'/> </channel> <input type='mouse' bus='ps2'/> <graphics type='spice' port='5900' autoport='yes' listen='127.0.0.1'> <listen type='address' address='127.0.0.1'/> </graphics> <sound model='ich6'> <alias name='sound0'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/> </sound> <video> <model type='qxl' ram='65536' vram='65536' heads='1'/> <alias name='video0'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/> </video> <memballoon model='virtio'> <alias name='balloon0'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/> </memballoon> <rng model='virtio'> <backend model='egd' type='udp'> <source mode='bind' host='127.0.0.1' service='1710'/> <source mode='connect' host='127.0.0.1' service='1708'/> </backend> </rng> </devices> <seclabel type='dynamic' model='selinux' relabel='yes'> <label>system_u:system_r:svirt_tcg_t:s0:c243,c472</label> <imagelabel>system_u:object_r:svirt_image_t:s0:c243,c472</imagelabel> </seclabel> </domain> Can you please share the network configuration you have used for the VM? # rpm -qa libvirt virt-manager qemu-kvm kernel kernel-3.10.0-33.el7.x86_64 qemu-kvm-1.5.3-10.el7.x86_64 libvirt-1.1.1-11.el7.x86_64 virt-manager-0.10.0-5.el7.noarch Set up a fedora and rhel guest on the host installed by latest tree: Add the rng device like below: with Type: Entropy Gathering Daemon, Backend type: UDP, Host: 127.0.0.1 port 1708, Bind Host: 127.0.0.1 port 1710. # virsh dumpxml rhel | grep rng -A 10 <rng model='virtio'> <backend model='egd' type='udp'> <source mode='bind' host='127.0.0.1' service='1710'/> <source mode='connect' host='127.0.0.1' service='1708'/> </backend> </rng> Use the script to feed rng device #################################################################### import socket UDP_IP = "127.0.0.1" UDP_PORT = 1708 sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) sock.bind((UDP_IP, UDP_PORT)) while True: data, addr = sock.recvfrom(1024) print "SEND DATA" sock.sendto ("AB" * 1024, addr) #################################################################### Check the access to the server by netcat # echo hello | nc -u 127.0.0.1 1708 ABABABABABABABABABABABABABABABABABABABAB... Start the guest rhel/fedora, and check if the random data are generated by /dev/hwrng: #head -c 2 /dev/hwrng AB Based on the previous comment 16 and the steps, I verified this bug. This request was resolved in Red Hat Enterprise Linux 7.0. Contact your manager or support representative in case you have further questions about the request. |
# rpm -qa libvirt virt-manager libvirt-1.1.1-8.el7.x86_64 virt-manager-0.10.0-4.el7.noarch For virt-manager GUI testing on virtio-rng, I tested the following scenario : 1. Add a rng device as type:random device:/dev/random. there's a /dev/hwrng device in the rhel 6.4 guest, and I could get the random number from the following python. python import os f = os.open('/dev/hwrng', os.O_RDONLY) os.read(f, 10) '\x01\xa5\x8a\xad\x9a\xc6\x8f\xc2\xe1\x9b' 2. Add a rng device as type:random device:/dev/random, rate(period):2000, rate(byte):1024. there's a /dev/hwrng device in the rhel 6.4 guest, and I could get the random number from the following python too. # python Python 2.6.6 (r266:84292, Oct 12 2012, 14:23:48) [GCC 4.4.6 20120305 (Red Hat 4.4.6-4)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import os >>> f = os.open('/dev/hwrng',os.O_RDONLY) >>> os.read(f,10) 'P\xcf\x7f\x95=\xb2\xd3\xe9#\xe5' 3. a, Add the rng device as type:Entropy Gathering Daemon, Host:localhost, Service: 1024, Backendtype: TCP,Mode: connect, rate(period):2000, rate(byte):1024. b. #cat /dev/urandom | nc -l localhost 1024 c. Start the guest. d. # ps aux | grep qemu ...-chardev socket,id=charrng0,host=localhost,port=1024 -object rng-egd,chardev=charrng0,id=rng0 -device virtio-rng-pci,rng=rng0,max-bytes=1024,period=2000,bus=pci.0,addr=0x6 e. there's a /dev/hwrng device. I could get the random number # dd if=/dev/hwrng of=/tmp/hello ^C90+1 records in 90+0 records out 46080 bytes (46 kB) copied, 89.8489 s, 0.5 kB/s 4. a. Add the rng device as type:Entropy Gathering Daemon, Host:localhost, Service: 1024, Backendtype: TCP,Mode: Bind b. #cat /dev/urandom | nc -l localhost 1024 c. Start the guest. d. # ps aux | grep qemu ...--chardev socket,id=charrng0,host=localhost,port=1024,server,nowait -object rng-egd,chardev=charrng0,id=rng0 -device virtio-rng-pci,rng=rng0,bus=pci.0,addr=0x6 there's a /dev/hwrng device. but i could not get random number from # dd if=/dev/hwrng of=/tmp/hello or # cat /dev/hwrng Seems this scenario failed. 5. a, Add the rng device as type:Entropy Gathering Daemon, Host:localhost, Service: 1024, Backendtype: UDP,Mode: connect, b. Start the guest. c. # ps aux | grep qemu ... -chardev udp,id=charrng0,host=localhost,port=1025,localaddr=,localport=0 -object rng-egd,chardev=charrng0,id=rng0 -device virtio-rng-pci,rng=rng0,bus=pci.0,addr=0x6 there's a /dev/hwrng device. I could get the random number # dd if=/dev/hwrng of=/tmp/hello or # cat /dev/hwrng 6. a, Add the rng device as type:Entropy Gathering Daemon, Host:localhost, Service: 1024, Backendtype: UDP,Mode: bind, Get the following error message: Error adding device: internal error: Missing source service attribute for char device For virt-install, 1. # virt-install -n demo -r 1024 -f /var/lib/libvirt/images/rhel6.4.img --import --rng /dev/random # ps aux | grep qemu ....-object rng-random,id=rng0,filename=/dev/random -device virtio-rng-pci,rng=rng0,bus=pci.0,addr=0x6 Could get random number in the guest. 2.#virt-install -n demo -r 1024 -f /var/lib/libvirt/images/rhel6.4.img --import --rng egd,backend_host=localhost,backend_service=8000,backend_type=tcp # ps aux | grep qemu ...-chardev socket,id=charrng0,host=localhost,port=8000 -object rng-egd,chardev=charrng0,id=rng0 -device virtio-rng-pci,rng=rng0,bus=pci.0,addr=0x6 Could get random number in the guest.