관리 메뉴

지돌이의 블로그 입니다!

Proxmox (QEMU) 에서 TPM 사용하기 본문

개발 및 운영/Proxmox

Proxmox (QEMU) 에서 TPM 사용하기

Joseph.Lee 2021. 4. 20. 10:25

Proxmox에 TPM 적용하기

qemu 에서 tpm을 사용하려면 swtpm이 필요합니다.

* 주의

swtpm은 물리적인 tpm을 사용하지 않으므로 Baremetal에 대한 보안성이 없습니다.

보안의 목적이 아닌 TPM을 이용한 개발 및 테스트에만 사용하십시오.

1. swtpm package 설치

github.com/jc-lab/vtpm-packages/releases/tag/debian10.8-r0005

github action을 이용하여 자동으로 빌드하고 Release하게 만들어 놓았습니다.

위의 deb를 받거나 직접 빌드하여 deb를 설치합니다.

apt-get install gnutls-bin trousers

dpkg -i libtpms0_0.7.7_amd64.deb
dpkg -i swtpm-libs_0.5.2_amd64.deb
dpkg -i swtpm_0.5.2_amd64.deb
dpkg -i swtpm-tools_0.5.2_amd64.deb

2. swtpm 서비스 생성

# cat <<EOF | tee /lib/systemd/system/swtpm-device@.service
[Unit]
Description=swtpm server

[Service]
Type=simple
ExecStartPre=mkdir -p /var/lib/qemu-swtpm/%i
ExecStart=swtpm socket --tpm2 --tpmstate dir=/var/lib/qemu-swtpm/%i --ctrl type=unixio,path=/var/run/qemu-server/%i.swtpm.sock --log level=20
Restart=always # VM을 끄면 swtpm도 꺼지기 때문에 Restart를 해줘야 한다.

[Install]
WantedBy=multi-user.target
EOF

# systemctl enable swtpm-device@mytpm0.service
# systemctl start swtpm-device@mytpm0.service

3. pve 설정 변경

/etc/pve/qemu-server/(VMID).conf 에 아래의 내용을 추가한다.

args: -global driver=cfi.pflash01,property=secure,value=on -chardev socket,id=chrtpm,path=/var/run/qemu-server/mytpm0.swtpm.sock -tpmdev emulator,id=tpm0,chardev=chrtpm -device tpm-tis,tpmdev=tpm0

4. 확인

Legacy (SeaBIOS) 일 때

Boot chain에 대해 PCR을 계산한다.

# tpm2_pcrread
sha1:
  0 : 0x3A3F780F11A4B49969FCAA80CD6E3957C33B2275
  1 : 0xF0741B64718FFF265CE36A051D241874891E50DE
  2 : 0x3BA5B5CA1E0F95B68675C7F62201187A0F8702D1
  3 : 0x3A3F780F11A4B49969FCAA80CD6E3957C33B2275
  4 : 0x420A9E358EBDE385400BA74903D4D745EE196280
  5 : 0x45696A1C900F18A53DABFD0375F5D9DF8518CFF8
  6 : 0x3A3F780F11A4B49969FCAA80CD6E3957C33B2275
  7 : 0x3A3F780F11A4B49969FCAA80CD6E3957C33B2275
  8 : 0x0000000000000000000000000000000000000000
  9 : 0x0000000000000000000000000000000000000000
  10: 0xECE3656576080908626F1BA2CD503736F1EBE481
  11: 0x0000000000000000000000000000000000000000
  12: 0x0000000000000000000000000000000000000000
  13: 0x0000000000000000000000000000000000000000
  14: 0x0000000000000000000000000000000000000000
  15: 0x0000000000000000000000000000000000000000
  16: 0x0000000000000000000000000000000000000000
  17: 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
  18: 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
  19: 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
  20: 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
  21: 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
  22: 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
  23: 0x0000000000000000000000000000000000000000

SeaBIOS의 PCR 업데이트 과정

https://github.com/KevinOConnor/seabios/blob/b0d61ecef66eb05bd7a4eb7ada88ec5dab06dfee/src/tcgbios.c#L1177 의 tpm_setup에서 TPM을 시작하면
tpm_smbios_measure 함수에서 첫 번째로 측정을 수행합니다.
여기서는 PCR 1번에 sep->structure_table_address 의 데이터를 SHA1으로 해시하여 추가합니다.

https://github.com/KevinOConnor/seabios/blob/b0d61ecef66eb05bd7a4eb7ada88ec5dab06dfee/src/tcgbios.c#L1259 의 tpm_option_rom 에서는 PCR 2번에 해시를 추가하고

https://github.com/KevinOConnor/seabios/blob/b0d61ecef66eb05bd7a4eb7ada88ec5dab06dfee/src/tcgbios.c#L1276 의 tpm_add_bcv 에서는 PCR 4, 5 번에 해시를 추가하고 (MBR 과 파티션 테이블)

https://github.com/KevinOConnor/seabios/blob/b0d61ecef66eb05bd7a4eb7ada88ec5dab06dfee/src/tcgbios.c#L1304 의 tpm_add_cdrom 에서는 PCR 4번에

https://github.com/KevinOConnor/seabios/blob/b0d61ecef66eb05bd7a4eb7ada88ec5dab06dfee/src/tcgbios.c#L1319 의 tpm_add_cdrom_catalog 에서는 PCR 5번에

그리고 tpm_add_action 으로 중간중간에 PCR 4번에 진행 과정을 추가함

https://github.com/KevinOConnor/seabios/blob/b0d61ecef66eb05bd7a4eb7ada88ec5dab06dfee/src/tcgbios.c#L1013 tpm_add_event_separators 에서는 PCR 0~7에 추가함

UEFI (OVMF) 일 때

Linux Kernel에서 tpm self test에 실패한다...

Boot chain에 대해 PCR을 계산하지 않는다. (Linux IMA에서 PCR8 만 사용함)

# tpm2_pcrread
sha1:
  0 : 0x0000000000000000000000000000000000000000
  1 : 0x0000000000000000000000000000000000000000
  2 : 0x0000000000000000000000000000000000000000
  3 : 0x0000000000000000000000000000000000000000
  4 : 0x0000000000000000000000000000000000000000
  5 : 0x0000000000000000000000000000000000000000
  6 : 0x0000000000000000000000000000000000000000
  7 : 0x0000000000000000000000000000000000000000
  8 : 0x0000000000000000000000000000000000000000
  9 : 0x0000000000000000000000000000000000000000
  10: 0x095D73D77E6EBF3776FE0AD2B06CB59F009EC5EE
  11: 0x0000000000000000000000000000000000000000
  12: 0x0000000000000000000000000000000000000000
  13: 0x0000000000000000000000000000000000000000
  14: 0x0000000000000000000000000000000000000000
  15: 0x0000000000000000000000000000000000000000
  16: 0x0000000000000000000000000000000000000000
  17: 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
  18: 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
  19: 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
  20: 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
  21: 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
  22: 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
  23: 0x0000000000000000000000000000000000000000
  ...

Secure Boot 관련 이슈들이 있다

아래 참고

  • Proxmox OVMF 펌웨어는 Secure Boot 꺼진 상태로 빌드되어있다.
  • Guest에 SMM을 지원하지 않는다.

참고자료

* github.com/tianocore/edk2/blob/master/OvmfPkg/README

# 그러나... Proxmox 에서 Secure Boot 안됌!

OVMF Firmware에서 Secure Boot 기능이 없이 컴파일 되었습니다.

*github.com/tianocore/tianocore.github.io/wiki/Testing-SMM-with-QEMU,-KVM-and-libvirt

참고하여 다시 컴파일(SECURE_BOOT_ENABLE, SMM_REQUIRE는 없이) 하면 되는데... secureboot가 disabled 됌... 확인 필요..ㅠㅠ PCR업데이트 안되는 것두 마찬가지..

잘 되면 github action 으로 자동 빌드할 수 있도록 올릴 예정입니다.

* SMM_REQUIRE 없으면 Secure Boot에 대한 보안성이 낮아집니다.

# 그러나... Proxmox 에서 SMM 동작 안함!

정상적인 동작을 위해 args에 아래와 같은 내용이 필요합니다. (smm=on)

-machine type=q35+pve0,smm=on

그런데 smm을 활성화하면 `kvm: System Management Mode not supported by this hypervisor.` 이런 오류가 발생합니다.

Proxmox 에 물어봤습니다: forum.proxmox.com/threads/why-ssm-is-disabled.87928/

(해당 토픽을 보시면 관련된 patch가 나와있습니다. proxmox 측에서 의도적으로 smm을 비활성화 했습니다.)

현재 SMM 이 강제적으로 비활성화 되어있기 때문에 secure boot 등의 사용이 불가합니다. (따라서 PCR도 업데이트가 안되나...?)

* access.redhat.com/discussions/3175901

* specs.openstack.org/openstack/nova-specs/specs/train/approved/allow-secure-boot-for-qemu-kvm-guests.html

---

* github.com/tianocore/tianocore.github.io/wiki/Testing-SMM-with-QEMU,-KVM-and-libvirt

반응형
2 Comments
  • 프로필사진 지나가는이 2021.05.17 15:34 저랑 비슷한 해결책을 모색하시는 군요. 페도라 코어 34의 OVMF를 가져다 UEFI 로 설정하니 secure boot는 enable되는데 TPM PCR 레지스터 값이 죄다 0입니다. -_-;;

    dmesg ...
    [ 0.000000] secureboot: Secure boot enabled
    [ 0.000000] Kernel is locked down from EFI Secure Boot mode; see man kernel_lockdown.7

    하지만..

    user@u2004:~$ sudo tpm2_pcrread
    sha1:
    0 : 0x0000000000000000000000000000000000000000
    1 : 0x0000000000000000000000000000000000000000
    2 : 0x0000000000000000000000000000000000000000
    3 : 0x0000000000000000000000000000000000000000
    ...

    UEFI말고 걍 기본 BIOS로 게스트 설치하고 QEMU에서 부팅하면 pcr이 값이 잘 들어가는 거 같아요 -_-;;
  • 프로필사진 Joseph.Lee 2021.05.22 13:40 신고 그러게요ㅠㅠ https://github.com/tianocore/edk2/blob/0ecdcb6142037dd1cdd08660a2349960bcf0270a/SecurityPkg/Tcg/Tcg2Dxe/MeasureBootPeCoff.c 보면 PE 파일을 Hash해서 extend하는 부분은 있는데 정확히 이부분으로 어떻게 진입될 수 있는진 모르겠네요..ㅠㅠ
    암튼 tpm에 관심있는 사람을 만나니 반갑습니다^^ 국내에서는 자료가 거의 없던데ㅠㅠ
댓글쓰기 폼