kvmにおいて、vm に spice tls接続するまで

# kvmにおいて、vm に spice tls接続するまで
# なにをするか
自己署名証明書(いわゆるオレオレ証明書)を作って、kvmのvmにtlsにより暗号化された状態でspiceプロトコルを使い画面に接続したい.

## おおまかな流れ
1. vmの設定を変更
1. qemu.conf を変える
1. 認証局、証明書などを準備
1. 再起動
1. remote-viewerで接続

## 環境
- Ubuntu 24.04.1 LTS
- libvirtを使用
- vmの名前はtestSpice

## vmの設定ファイルを編集
libvirtでは設定ファイルはxml形式.
[libvirt domain xml settings](https://libvirt.org/formatdomain.html)を読んでください.

例
```testSpice.xml
<graphics type='spice' autoport='yes' listen='your ip address'>
      <listen type='address' address='your ip address'/>
</graphics>
```
参考:[設定例](https://www.server-world.info/query?os=Rocky_Linux_8&p=kvm&f=6)
## qemu.confを編集
/etc/libvirt/qemu.confの`#spice_tls = 1`の部分のコメントを外す.
```qemu.conf
# Enable use of TLS encryption on the SPICE server.
#
# It is necessary to setup CA and issue a server certificate
# before enabling this.
#
spice_tls = 1
```
証明書などを置くディレクトリを`spice_tls_x509_cert_dir`に代入する. 設定しなかったらデフォルトで決まる.
```qemu.conf
# In order to override the default TLS certificate location for
# spice certificates, supply a valid path to the certificate directory.
# If the provided path does not exist, libvirtd will fail to start.
# If the path is not provided, but spice_tls = 1, then the
# default_tls_x509_cert_dir path will be used.
spice_tls_x509_cert_dir = "/etc/pki/libvirt-spice"
```
参考:[qemu.confの設定](https://people.freedesktop.org/~teuf/spice-doc/html/ch02s08.html)
## 証明書など
[スクリプト](https://people.freedesktop.org/~teuf/spice-doc/html/ch02s08.html)を参考にした. 証明書もろもろを生成するスクリプト. このままだと、動かなかったので少し変更した.

変更点
- keyを生成するときのbitサイズを1024から2048に変更(creating a key for our ca と create server key)
- csrを作成するときにホスト名を変更(create a certificate signing request (csr))
```
#!/bin/bash

SERVER_KEY=server-key.pem

# creating a key for our ca
if [ ! -e ca-key.pem ]; then
    openssl genrsa -des3 -out ca-key.pem 2048
fi
# creating a ca
if [ ! -e ca-cert.pem ]; then
    openssl req -new -x509 -days 1095 -key ca-key.pem -out ca-cert.pem -utf8 -subj "/C=IL/L=Raanana/O=Red Hat/CN=my CA"
fi
# create server key
if [ ! -e $SERVER_KEY ]; then
    openssl genrsa -out $SERVER_KEY 2048
fi
# create a certificate signing request (csr)
if [ ! -e server-key.csr ]; then
    openssl req -new -key $SERVER_KEY -out server-key.csr -utf8 -subj "/C=IL/L=Raanana/O=Red Hat/CN=yourhostname"
fi
# signing our server certificate with this ca
if [ ! -e server-cert.pem ]; then
    openssl x509 -req -days 1095 -in server-key.csr -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 -out server-cert.pem
fi

# now create a key that doesn't require a passphrase
openssl rsa -in $SERVER_KEY -out $SERVER_KEY.insecure
mv $SERVER_KEY $SERVER_KEY.secure
mv $SERVER_KEY.insecure $SERVER_KEY

# show the results (no other effect)
openssl rsa -noout -text -in $SERVER_KEY
openssl rsa -noout -text -in ca-key.pem
openssl req -noout -text -in server-key.csr
openssl x509 -noout -text -in server-cert.pem
openssl x509 -noout -text -in ca-cert.pem
```
これをqemu.confの`spice_tls_x509_cert_dir`で設定されたディレクトリの下で実行する. 
参考:[証明書生成スクリプト](https://people.freedesktop.org/~teuf/spice-doc/html/ch02s08.html)
## 再起動
libvirtとvmを再起動.
```
$ virsh shutdown spiceTest
$ systemctl restart spiceTest
$ virsh start spiceTest
```
`virsh restart spiceTest`ではlibvirtの設定が読み込まれない. 

## remote-viewer
[スクリプト](https://people.freedesktop.org/~teuf/spice-doc/html/ch02s08.html)で作った`ca-cert.pem`をclient側にコピーする.
```
remote-viewer spice://yourhostname?tls-port=5901  --spice-ca-file=/path/to/ca-cert.pem
```

## 参考になったサイト
### tls
- https://wiki.libvirt.org/TLSCreateServerCerts.html
- https://libvirt.org/kbase/tlscerts.html#troubleshooting-tls-certificate-problems
### spice
- https://libvirt.org/formatdomain.html
- https://wiki.archlinux.org/title/QEMU
- https://www.spice-space.org/spice-user-manual.html
- https://people.freedesktop.org/~teuf/spice-doc/html/ch02s08.html
- https://www.server-world.info/query?os=Rocky_Linux_8&p=kvm&f=6

## 最後に
間違いなどがあったら教えてほしいです.