限制对特定用户的KVM虚拟机访问

在我的服务器上,我有一个名为“cards2”的KVM虚拟机。 它是通过执行(以root身份)创build的:

# virt-install --connect qemu:///system --virt-type kvm --name cards2 --ram 2048 --disk /var/kvm/cards2.qcow,size=3 --vcpus=8 --cdrom /var/kvm/debian-8.5.0-amd64-netinst.iso --vnc --os-type linux --network network=default 

该图片拥有权限

 # ls -l /var/kvm/cards2.qcow -rwxr-xr-x 1 libvirt-qemu libvirt-qemu 3221225472 Aug 17 18:49 /var/kvm/cards2.qcow 

但是我注意到, 任何使用SSH访问的用户都可以通过执行以下命令来访问虚拟机:

 virt-viewer --connect qemu+ssh://[email protected]/system vmname 

(注意,这个命令是远程执行的,而不是在服务器上执行的,它通过SSH隧道连接到连接URI为qemu+ssh://[email protected]的pipe理程序)

用户username只是username组的一个成员。 使用username帐户进行SSH连接时,虚拟机列表显示为空:

 $ virsh list --all Id Name State ---------------------------------------------------- 

在通过SSH执行以下操作时,我也无法使用套接字进行连接:

 $ virsh --connect qemu:///system list --all error: Failed to connect socket to '/var/run/libvirt/libvirt-sock': Permission denied 

我也尝试将所有/usr/bin/vir*文件的权限移除到不在kvm组中的用户:

 # chown root:kvm /usr/bin/vir* # chmod o-rx /usr/bin/vir* # ls /usr/bin/vir* -l -rwxr-x--- 1 root kvm 321120 Jul 1 04:46 /usr/bin/virsh -rwxr-x--- 1 root kvm 32184 Dec 7 2013 /usr/bin/virt-alignment-scan -rwxr-x--- 1 root kvm 28128 Dec 7 2013 /usr/bin/virt-cat -rwxr-x--- 1 root kvm 9774 Sep 29 2014 /usr/bin/virt-clone -rwxr-x--- 1 root kvm 10277 Sep 29 2014 /usr/bin/virt-convert -rwxr-x--- 1 root kvm 806 Dec 7 2013 /usr/bin/virt-copy-in -rwxr-x--- 1 root kvm 808 Dec 7 2013 /usr/bin/virt-copy-out -rwxr-x--- 1 root kvm 54584 Dec 7 2013 /usr/bin/virt-df -rwxr-x--- 1 root kvm 33312 Dec 7 2013 /usr/bin/virt-edit -rwxr-x--- 1 root kvm 54536 Dec 7 2013 /usr/bin/virt-filesystems -rwxr-x--- 1 root kvm 30112 Dec 7 2013 /usr/bin/virt-format -rwxr-x--- 1 root kvm 14656 Jul 1 04:46 /usr/bin/virt-host-validate -rwxr-x--- 1 root kvm 7944 Sep 29 2014 /usr/bin/virt-image -rwxr-x--- 1 root kvm 44696 Dec 7 2013 /usr/bin/virt-inspector -rwxr-x--- 1 root kvm 36992 Sep 29 2014 /usr/bin/virt-install -rwxr-x--- 1 root kvm 5338 Dec 7 2013 /usr/bin/virt-list-filesystems -rwxr-x--- 1 root kvm 6686 Dec 7 2013 /usr/bin/virt-list-partitions -rwxr-x--- 1 root kvm 53816 Dec 7 2013 /usr/bin/virt-ls -rwxr-x--- 1 root kvm 18641 Dec 7 2013 /usr/bin/virt-make-fs -rwxr-x--- 1 root kvm 9600 Jul 1 04:46 /usr/bin/virt-pki-validate -rwxr-x--- 1 root kvm 36264 Dec 7 2013 /usr/bin/virt-rescue -rwxr-x--- 1 root kvm 1322488 Dec 7 2013 /usr/bin/virt-resize -rwxr-x--- 1 root kvm 1231256 Dec 7 2013 /usr/bin/virt-sparsify -rwxr-x--- 1 root kvm 1289592 Dec 7 2013 /usr/bin/virt-sysprep -rwxr-x--- 1 root kvm 8949 Dec 7 2013 /usr/bin/virt-tar -rwxr-x--- 1 root kvm 804 Dec 7 2013 /usr/bin/virt-tar-in -rwxr-x--- 1 root kvm 806 Dec 7 2013 /usr/bin/virt-tar-out -rwxr-x--- 1 root kvm 55 Jul 12 2012 /usr/bin/virtualenv -rwxr-x--- 1 root kvm 132400 May 28 2012 /usr/bin/virt-viewer -rwxr-x--- 1 root kvm 23886 Dec 7 2013 /usr/bin/virt-win-reg -rwxr-x--- 1 root kvm 3531 Jul 1 04:46 /usr/bin/virt-xml-validate 

尽pipe现在我无法通过常规的SSH连接访问这些命令,但我仍然可以通过SSH隧道远程执行virt-viewer (如上所述)来启动VM。

那么,我怎样才能做到这一点,只有特定的用户帐户才能访问虚拟机?

编辑:

以下是启动虚拟机时出现在我的/var/log/libvirt/qemu/cards2.log中的情况,以便提供任何指示:

LC_ALL = C PATH = / usr / local / sbin:/ usr / local / bin:/ sbin:/ bin:/ usr / sbin:/ usr / bin QEMU_AUDIO_DRV = none / usr / bin / kvm -S -M pc-1.1 -enable-kvm -m 2048 -smp 8,sockets = 8,cores = 1,threads = 1 -name cards2 -uuid 70905b35-9df3-71c9-d5e9-f804a2826055 -no-user-config -nodefaults -chardev socket,id = charmonitor,path = / var / lib / libvirt / qemu / cards2.monitor,server,nowait -mon chardev = charmonitor,id = monitor,mode = control -rtc base = utc -no-shutdown -device piix3-usb-uhci, id = usb,bus = pci.0,addr = 0x1.0x2 -drive file = / var / kvm / cards2.qcow,if = none,id = drive-ide0-0-0,format = raw -device ide-hd ,bus = ide.0,unit = 0,drive = drive-ide0-0-0,id = ide0-0-0,bootindex = 1 -drive if = none,id = drive-ide0-1-0,readonly = on,format = raw -device ide-cd,bus = ide.1,unit = 0,drive = drive-ide0-1-0,id = ide0-1-0 -netdev tap,fd = 23,id = hostnet0 – 设备rtl8139,netdev = hostnet0,id = net0,mac = 52:54:00:c6:14:68,bus = pci.0,addr = 0x3 -chardev pty,id = charserial0 -device isa-serial,chardev = charserial0 ,id = serial0 -vnc 127.0.0.1:3 -vga cirrus -device virtio-balloon-pci,id = balloon0 ,总线= pci.0,ADDR =为0x4

编辑2:

另一方面,这似乎只是一个virt-viewer的问题,而不是virsh

例如,这里是一些在远程客户端上执行的命令:

 $ virsh --connect qemu+ssh://[email protected]/system error: failed to connect to the hypervisor error: End of file while reading data: nc: unix connect failed: Permission denied: Input/output error $ virsh --connect qemu+ssh://[email protected]/system Welcome to virsh, the virtualization interactive terminal. Type: 'help' for help with commands 'quit' to quit 

我知道了 virt-viewer不与libvirtd交互 – 它通过ssh连接到主机,并build立一个隧道,允许访问基于VNC的虚拟机(我的情况是127.0.0.1:5903)。 在127.0.0.1上很难解决防火墙VNC的问题。 否则,普通用户通常可以自由地build立到本地主机的TCP连接。 我不知道如何才能允许根,也许有一种方法。

也许selinux呢?

Linux:允许/限制用户的IP绑定权限

所以最简单的事情就是设置一个VNC密码。 您可以在SSH中执行限制转发和X11转发等操作,但这可能不是100%安全的,也可能会导致root问题。 用户login后仍然可以访问127.0.0.1/vnc。

更新

根据迈克(其他答案)和迈克尔汉普顿(评论),你可以使用TLS与VNC沟通,而不是密码,所以如果密码不够好,你会得到一些相当不错的安全性。 道具他们两个,我不知道。

http://wiki.libvirt.org/page/VNCTLSSetup

https://www.suse.com/documentation/sles11/book_kvm/data/sec_l​​ibvirt_connect_remote.html#sec_l​​ibvirt_connect_remote_tls

Ryan的回答如上所述,“virt-viewer不与libvirtd交互”。 libvirtd和VNC(virt-viewer所连接的)有完全独立的authentication方法 。 VNC可以用

  • 单一密码authentication
  • SASLauthentication
  • x509证书
  • 组合证书和前两个之一

单个密码

如果使用单个密码,则可以是存储在/etc/libvirt/qemu.conf文件中的全局密码,也可以在VMconfiguration中添加VM特定的密码:

 <graphics type='vnc' port='-1' autoport='yes' passwd='PASSWORD'/> 

请注意,这些密码必须以纯文本格式保存。

SASLauthentication

这允许每个虚拟机有多个用户名和密码组合。 密码也是散列的,而不是以纯文本存储的单个密码。 有关说明, 请看这里 。

x509证书

这实际上是我相信直接回答这个问题的部分(但是我没有testing过)。 通过这种方式,您可以通过使用存储在服务器上的证书进行身份validation来限制哪个用户可以连接到VNC实例。 要撤销特定用户或组的权限,只需将系统范围的客户端证书文件的权限设置为不可由该用户读取。 您也可以生成每个用户的证书并撤消访问权限。

不幸的是build立起来相对困难。 它首先在服务器上创build一个根CA , 生成x509客户端/服务器证书 , configuration服务器 , configuration客户端并testing设置 ,然后限制访问 。

你有没有尝试使用polkit来限制用户访问? 我也想这样做,所以我结束了这个结果:

  1. 将vm命名为用户名* vmname
  2. 现在在polkit规则文件中编辑规则如下

     function myFunction(username, virtualmachine) { var arr = virtualmachine.split("*"); if(arr[0]==username){ return true; } else{ return false; } } // Allow passwordless connection to qemu:///system polkit.addRule(function(action, subject) { if (action.id == "org.libvirt.unix.manage") { return polkit.Result.YES; } }); // Give full access to 'vm' polkit.addRule(function(action, subject) { if (action.id.indexOf("org.libvirt.api.domain.") == 0 ) { if (action.lookup("connect_driver") == 'QEMU' && myFunction(subject.user, action.lookup("domain_name"))) { polkit.log("vm=" + action.lookup("domain_name") + "action =>"+myFunction(subject.user, action.lookup("domain_name"))); polkit.log("subject=" + subject); polkit.log("ok"); return polkit.Result.YES; } else { return polkit.Result.NO; } } }); 
  3. 现在只有相应的用户才能看到vm本身。

请享用