qemu/virt-manager와 samba가 동일한 폴더를 읽고 쓸 수 있도록 SELinux를 구성하시겠습니까?

qemu/virt-manager와 samba가 동일한 폴더를 읽고 쓸 수 있도록 SELinux를 구성하시겠습니까?

문제의 결론

Samba 아래에 공유된 로컬 폴더가 있지만 qemu(사용자 세션을 통해)가 virtio-9p를 통해 해당 폴더에 액세스하도록 허용하려고 하면 오류(SELinux avc)가 발생합니다. SELinux가 비활성화된 상태에서도 잘 작동하지만 작동하길 원합니다.그리고SELinux. 도와주세요.

배경

Fedora 호스트에 samba와 virt-manager/qemu를 설치했습니다. 둘 다 서로 독립적으로 잘 작동합니다(예를 들어, samba 디렉토리와 vm 디렉토리는 동일한 드라이브에 있지 않더라도 완전히 다른 경로입니다).

제가 작업 중인 새 프로젝트의 경우 virt-manager/qemu 및 Samba(및 docker/podman도 가능)가 현재 Samba에서 공유하는 기존 호스트 폴더에 액세스할 수 있도록 허용하는 동시에 액세스를 제한하는 방법을 찾고 싶습니다. 가능할수록 좋습니다. 프로토콜을 통해 공유에 액세스 smb://하면 두 개가 동일한 호스트에 있더라도 네트워크 오버헤드로 인해 약간의 I/O 대기 시간이 발생한다는 것을 알고 있습니다 . 이를 위해 smb://프로토콜을 완전히 피하고 VM이 virtio-9p 또는 이와 유사한 것을 통해 공유 호스트 폴더에 로컬로 액세스하도록 하고 싶습니다 . 또한 명확히 말하면 이것은 로컬로 마운트된 원격 삼바 공유가 아니라 내 LAN의 다른 컴퓨터와 공유되는 로컬 폴더입니다.

일부Red Hat 문서, 내 가상 머신이 컨텍스트에서 파일에 액세스할 수 있도록 허용할 수 있는 부울 값을 찾았습니다 samba_share_t.

virt_use_samba 가상 머신이 CIFS 파일에 액세스하도록 허용합니다.

이전에 삼바 파일 컨텍스트를 사용하여 폴더를 구성했기 때문에:

# setsebool -P samba_export_all_ro=1;
# setsebool -P samba_export_all_rw=1;
# setsebool -P samba_share_fusefs=1;
  
# sambaShare=/media/d/shared
# semanage fcontext --add --type "samba_share_t" "${sambaShare}(/.*)?"
# sudo restorecon -R "${sambaShare}";

삼바 쪽에서는 모든 것이 잘 작동하고 아무 문제 없이 읽고 쓸 수 있습니다.

오늘 나는 VM이 ​​동일한 작업을 수행할 것이라고 생각하여 새로운 부울을 설정했습니다.

# setsebool -P virt_use_samba=1
# getsebool -a | grep -P '(smb|cifs|samba|virt_|emu).*on$'
samba_export_all_ro --> on
samba_export_all_rw --> on
samba_share_fusefs --> on
virt_sandbox_use_all_caps --> on
virt_sandbox_use_audit --> on
virt_use_nfs --> on
virt_use_samba --> on
virt_use_usb --> on
xend_run_qemu --> on

하지만 여전히 오류가 발생합니다. 이 호스트에 이미 Windows 가상 머신이 있으므로 smb://프로토콜을 통해 Samba 공유에 액세스 할 수 있습니다.이전에virt_use_samba이 변수를 설정합니다. 가상 머신이 프로토콜에 액세스하도록 허용하려는 의도인지는 확실하지 않지만 가상 머신이 samba_share_t파일 컨텍스트를 사용하여 폴더에 액세스하도록 허용하려는 경우 Windows에서는 다른 작업을 수행하지만 어떤 이유로든 그렇지 않습니다. 나를 위해 일하는 것은 잘 작동하거나 더 이상 사용되지 않거나 완전히 다른 작업을 수행하는 경우입니다. 이를 배제하기 위해 변수를 설정한 후 시스템을 다시 시작했지만 아무런 차이가 없었습니다.

임시 사용 시 설정이 작동하는지 테스트했습니다 setenforce 0. VM 설정을 통해 파일 시스템을 추가한 다음 VM에 마운트하고 문제 없이 쓸 수도 있습니다. 그러나 SELinux를 다시 켜면 더 이상 가상 머신을 부팅할 수 없습니다. 오류가 발생하고 다시 부팅하기 전에 virtio-9p 파일 시스템 항목을 삭제해야 합니다.


오류 및 구성 세부정보

체계

# inxi -Sz
System:
  Kernel: 6.6.6-100.fc38.x86_64 arch: x86_64 bits: 64 Console: pty pts/0
    Distro: Fedora release 38 (Thirty Eight)
         
# dnf list installed selinux-policy
Installed Packages
selinux-policy.noarch                   38.30-1.fc38                    @updates

qemu:///session또한 루트(예: ) 대신 사용자(예: )로 virt-manager/qemu를 실행하고 있습니다 qemu:///system(차이가 있는 경우). 나는 이것을 gsettings다음과 같이 설정했습니다.

gsettings set org.virt-manager.virt-manager.connections uris "['qemu:///session']";
gsettings set org.virt-manager.virt-manager.connections autoconnect "['qemu:///session']";

virtio-9p 구성

* 참고: 실제로는 virt-manager GUI를 통해 수동으로 구성했지만 이는 생성된 xml입니다. 제가 하고 있는 실제 프로세스는 (virt-manager에서) VM 대화 상자를 열고 세부 정보 탭으로 이동하여 왼쪽 하단에 있는 "하드웨어 추가" 버튼 > 파일 시스템 > 드라이버=virtio-9p를 선택하고 소스 및 대상 경로 > 완료 버튼. 그런 다음 가상 머신이 작동되면 다음 명령을 사용하여 이를 마운트합니다. mount -t 9p -o trans=virtio "${virtualPath}" "${guestMountPoint}"여기서 virtualPath는 아래 xml에 정의된 대상 경로이고 guestMountPoint는 게스트 OS의 경로(예: /media/shared)입니다.

<filesystem type="mount" accessmode="mapped">
  <source dir="/media/d/shared"/>
  <target dir="/virtio-9p/shared"/>
</filesystem>

virt-manager 메시지 상자에 오류가 발생했습니다:

Unable to complete install: 'internal error: qemu unexpectedly closed the monitor: 2023-12-17T04:07:05.237139Z qemu-system-x86_64: -device {"driver":"virtio-9p-pci","id":"fs1","fsdev":"fsdev-fs1","mount_tag":"/virtio-9p/shared","bus":"pci.2","addr":"0x0"}: cannot initialize fsdev 'fsdev-fs1': failed to open '/media/d/shared': Permission denied'
 
Traceback (most recent call last):
  File "/usr/share/virt-manager/virtManager/asyncjob.py", line 72, in cb_wrapper
    callback(asyncjob, *args, **kwargs)
  File "/usr/share/virt-manager/virtManager/createvm.py", line 2008, in _do_async_install
    installer.start_install(guest, meter=meter)
  File "/usr/share/virt-manager/virtinst/install/installer.py", line 695, in start_install
    domain = self._create_guest(
             ^^^^^^^^^^^^^^^^^^^
  File "/usr/share/virt-manager/virtinst/install/installer.py", line 637, in _create_guest
    domain = self.conn.createXML(initial_xml or final_xml, 0)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib64/python3.11/site-packages/libvirt.py", line 4481, in createXML
    raise libvirtError('virDomainCreateXML() failed')
libvirt.libvirtError: internal error: qemu unexpectedly closed the monitor: 2023-12-17T04:07:05.237139Z qemu-system-x86_64: -device {"driver":"virtio-9p-pci","id":"fs1","fsdev":"fsdev-fs1","mount_tag":"/virtio-9p/shared","bus":"pci.2","addr":"0x0"}: cannot initialize fsdev 'fsdev-fs1': failed to open '/media/d/shared': Permission denied

SELinux 오류:

# ausearch -m avc -ts boot
----
time->Sat Dec 16 23:07:05 2023
type=AVC msg=audit(1702786025.235:319): avc:  denied  { read } for  pid=4221 comm="qemu-system-x86" name="shared" dev="dm-4" ino=83951617 scontext=unconfined_u:unconfined_r:svirt_t:s0:c98,c936 tcontext=unconfined_u:object_r:samba_share_t:s0 tclass=dir permissive=0

질문:

문제는 내 가상 머신에 액세스 권한이 없다는 점을 이해합니다 samba_share_t. 지금까지 수행한 연구에 따르면 사용 가능한 몇 가지 옵션이 있는 것 같습니다.

  1. 규칙을 수정하는 것이 가능할 수 있다는 힌트를 온라인에서 본 적이 있지만 실제로 그렇게 하는 명령/자습서는 전혀 본 적이 없습니다(예: "기존 파일 형식에 대해 누락된 액세스 규칙 추가")이 토론).예를 들어 qemu/svirt_t/etc가 "samba_share_t" 파일 컨텍스트에 액세스하도록 허용하는 등 기존 SELinux 규칙 세트를 수정한다고 가정하면 누군가 이 작업을 수행하는 방법에 대한 간단한 예를 보여줄 수 있습니까? 아니면 생각보다 복잡하다면 간략한 10,000피트 개요와 링크라도 주시면 정말 감사하겠습니다.. 저는 아직 SELinux를 배우고 있고 정식 교육을 받은 적이 없습니다. 따라서 유료 RH 지식 포털에 액세스할 수 없으며 공개 RH 문서가 항상 가장 명확하지는 않다는 점을 명심하세요. 내가 하나 찾았어젠투 위키의 SELinux 페이지다음에 해볼 생각은 여기입니다(어느 부분에 집중해야 할지 모르겠고 읽을 내용도 많아서 먼저 여기에 물어보고 싶었습니다).

  2. 나는 디렉토리의 파일 컨텍스트를 변경 public_context_rw_t하고 액세스를 허용하도록 selinux 부울을 설정할 수 있다는 내용을 온라인에서 보았습니다. 내 생각엔 나에게 필요한 것 같아 setsebool -P smbd_anon_write=1(또는아마도 setsebool -P allow_smbd_anon_write 1? ) 삼바가 이 컨텍스트에 액세스할 수 있도록 허용합니다. 그러나 내가 찾은 모든 예는 httpd와 같은 더 널리 사용되는 서비스에 대한 것이며 qemu/virt-manager(또는 docker/podman)에 설정해야 하는 부울 이름이 무엇인지 전혀 모릅니다. getsebool -a출력에 이름과 같은 내용이 표시되지 않습니다 . 나는 또한 이 방법을 사용하는 것이 다른 서비스에서도 폴더에 액세스할 수 있도록 허용하는 것처럼 보이기 때문에 약간 주저합니다.이 접근 방식을 취한다고 가정하면 qemu 및 docker/podman에 대해 어떤 부울을 설정해야 합니까?

  3. 나는 다른 심각한 옵션에 열려 있습니다(예를 들어 솔루션으로 "SELinux 끄기"에 관심이 없음).

솔루션에 다른 관련 정보가 필요한 경우 알려주시기 바랍니다.

관련 정보