На работе мы активно используем виртуализацию на базе qemu/kvm через libvirt. Сам я давно пересел на linux и также использую qemu/kvm на своей локальной машине, при этом, часто применяю графический virt-manager для настройки различных параметров ВМ. Хотелось использовать его и для управления гипервизорами на удаленных серверах. О том как это сделать и будет статья в виде пошаговой инструкции(по факту это перевод и «сведение в едино» официальной документации).
Подготовка
Подразумевается, что все действия делаются на «ноде виртуализации» ( где стоит libvirtd, в данном случае это CentOS 6 ) и selinux отключен. Выполняем в консоли:
mkdir /tmp/certs
cd /tmp/certs
Генерируем самоподписанный корневой сертификат
mkdir ca
cd ca
Создаем шаблон с параметрами корневого сертификата (CA):
cat > certificate_authority_template.info << 'EOF'
cn = Name of your organization
ca
cert_signing_key
expiration_days = 3650
EOF
«Name of your organization» — соответственно имя вашей организации в латинице, срок действия сертификата- 10 лет.
Гененрируем секретный ключ для CA:
(umask 277 && certtool --generate-privkey > certificate_authority_key.pem)
Генерируем самоподписанный CA:
certtool --generate-self-signed
--template certificate_authority_template.info
--load-privkey certificate_authority_key.pem
--outfile certificate_authority_certificate.pem
Генерируем сертификат для «ноды виртуализации» ( где стоит libvirtd)
cd ..
mkdir kvm_host
cd kvm_host
Создаем шаблон с параметрами сертификата для «ноды виртуализации»:
cat > host_server_template.info << 'EOF'
organization = Name of your organization
cn = server.name
tls_www_server
encryption_key
signing_key
EOF
«server.name»- dns имя «ноды виртуализации», для которой генерируется сертификат,
Генерируем секретный ключ для «ноды виртуализации»:
(umask 277 && certtool --generate-privkey > host_server_key.pem)
Генерируем сертификат для нашей «ноды виртуализации»:
certtool --generate-certificate
--template host_server_template.info
--load-privkey host_server_key.pem
--load-ca-certificate ../ca/certificate_authority_certificate.pem
--load-ca-privkey ../ca/certificate_authority_key.pem
--outfile host_server_certificate.pem
Генерируем сертификат для клиентского подключения.
cd ..
mkdir client
cd client
Создаем шаблон с параметрами сертификата для клиента:
cat > client_template.info << 'EOF'
country = RU
state = State
locality = City
organization = Name of your organization
cn = client.host
tls_www_client
encryption_key
signing_key
EOF
«client.host»- dns имя клиента, state и locality заполняем по вашему усмотрению.
Генерируем секретный ключ для клиента:
(umask 277 && certtool --generate-privkey > client_key.pem)
Генерируем сертификат для клиента:
certtool --generate-certificate
--template client_template.info
--load-privkey client_key.pem
--load-ca-certificate ../ca/certificate_authority_certificate.pem
--load-ca-privkey ../ca/certificate_authority_key.pem
--outfile client_certificate.pem
Подключение сертификатов/ключей к libvirt
cd /tmp/certs
Все нижеприведенные действия необходимо делать либо через sudo, либо от имени root пользователя:
mkdir -p /etc/pki/libvirt/private
chmod 755 /etc/pki/libvirt
chmod 750 /etc/pki/libvirt/private
cp ./ca/certificate_authority_certificate.pem /etc/pki/libvirt/cacert.pem
cp ./kvm_host/host_server_certificate.pem /etc/pki/libvirt/servercert.pem
cp ./kvm_host/host_server_key.pem /etc/pki/libvirt/private/serverkey.pem
ln -s /etc/pki/libvirt/cacert.pem /etc/pki/CA/
chgrp qemu /etc/pki/libvirt
/etc/pki/libvirt/servercert.pem
/etc/pki/libvirt/private
/etc/pki/libvirt/private/serverkey.pem
chmod 440 /etc/pki/libvirt/servercert.pem
chmod 444 /etc/pki/libvirt/cacert.pem
chmod 640 /etc/pki/libvirt/private/serverkey.pem
Права 640 на на server-key.pem нужны, чтобы можно было использовать этот же ключ для vnc соединения, при это утилита virt-pki-validate будет ругаться что права должны быть 600- игнорируем.
Подключение сертификатов/ключей к vnc
Все нижеприведенные действия необходимо делать либо через sudo, либо от имени root пользователя:
mkdir /etc/pki/libvirt-vnc
ln -s /etc/pki/libvirt/cacert.pem /etc/pki/libvirt-vnc/ca-cert.pem
ln -s /etc/pki/libvirt/servercert.pem /etc/pki/libvirt-vnc/server-cert.pem
ln -s /etc/pki/libvirt/private/serverkey.pem /etc/pki/libvirt-vnc/server-key.pem
chgrp qemu /etc/pki/libvirt-vnc
chmod 750 /etc/pki/libvirt-vnc
Настройка демона libvirtd
В файле /etc/libvirt/libvirtd.conf нужно установиться следующие значения для соответствующих параметров:
listen_tls = 1
tls_port = "16514"
auth_tls = "none"
key_file = "/etc/pki/libvirt/private/serverkey.pem"
cert_file = "/etc/pki/libvirt/servercert.pem"
ca_file = "/etc/pki/libvirt/cacert.pem"
crl_file = "/etc/pki/libvirt/crl.pem"
#tls_allowed_dn_list = ["DN1", "DN2"]
log_level = 3
log_outputs="4:syslog:libvirtd 3:file:/var/log/libvirt/libvirt.log"
audit_level = 2
audit_logging = 1
keepalive_interval = 5
keepalive_count = 5
В результате мы включим tls и настроим логирование.
В tls_allowed_dn_list прописывается dn( Distinguished Name) сертификатов, которым можно будет подключаться к libvirtd
В файле /etc/sysconfig/libvirtd параметр LIBVIRTD_ARGS должен быть выставлен в «--listen»:
LIBVIRTD_ARGS="--listen"
Настройка демона qemu/kvm
В файле /etc/libvirt/qemu.conf нужно установиться следующие значения для соответствующих параметров:
vnc_tls = 1
vnc_tls_x509_verify = 1
vnc_allow_host_audio = 0
cgroup_controllers = [ "cpu", "devices", "memory", "blkio", "cpuset", "cpuacct" ]
save_image_format = "lzop"
clear_emulator_capabilities = 1
Так мы включим tls для подключения по vnc виртуальных машин, отключим передачу audio( нам оно не надо, если вам нужно- оставьте включенным), включим сжатие для снапшотов памяти(пригодится для живых бэкапов, если кому интересно, мы бэкапим так, так как раньше выложил там- привожу в виде ссылки), а также включим соответствующие группы cgroups( вообще оно включено по-умолчанию, но задал жестко)
Только после этой правки перезапускаем libvirtd:
service libvirtd restart
Для уже запущенных виртуальных машин подключение по vnc поверх tls будет возможно только после их выключения и повторного включения( virsh shutdown/start)
Настройка iptables
Для подключения к libvirtd и vnc в цепочку INPUT нужно внести следующие правила( если используете iptables):
iptables -I INPUT -m state --state NEW -m tcp -p tcp --dport 16514 -j ACCEPT
iptables -I INPUT -m state --state NEW -s 192.168.40.0/24 -m tcp -p tcp --dport 5900:6000 -j ACCEPT
Подразумевается, что vnc консоли будут вистеть на портах от 5900 до 6000. После этого сохранить действующие правила iptables командой:
iptables-save>/etc/sysconfig/iptables
Если у вас уже есть с самоподписанный корневой сертификат/клиентские сертификаты
В таком случае выполните все пункты за исключение 1. и 2., при этом указывая ваши пути до корневого сертификата и его ключа в соответствующих параметрах(--load-ca-certificat, --load-ca-privkey), по необходимости пропустите пункт 4., если для необходимых клиентов сертификаты уже сгенерированы.
Настройка клиента( Linux )
Под Linux в данном случае подразумевается Centos/Fedora
Выполняется на удаленной системе с которой будет происходить администрирование «ноды виртуализации».
Для начала надо создать папки для соответствующих сертификатов:
mkdir -m 750 -p /etc/pki/libvirt/private
mkdir -m 700 ~/.pki/libvirt-vnc
Далее положить соответствующие файлы с сервера по необходимым путям на локальной машине, с которой будет происходить подключение:
/tmp/certs/ca/certificate_authority_certificate.pem положить в /etc/pki/CA/cacert.pem
/tmp/certs/client/client_key.pem положить в /etc/pki/libvirt/private/clientkey.pem
/tmp/certs/client/client_certificate.pem положить в /etc/pki/libvirt/clientcert.pem
chmod 444 /etc/pki/CA/cacert.pem
chmod 440 /etc/pki/libvirt/clientcert.pem /etc/pki/libvirt/private/clientkey.pem
chown -R root:wheel /etc/pki/libvirt
cd ~/.pki/libvirt-vnc/
ln -s /etc/pki/libvirt/clientcert.pem clientcert.pem
ln -s /etc/pki/libvirt/private/clientkey.pem clientkey.pem
С такими настройками к libvirtd/vnc на удаленом сервере смогут подключаться локальные пользователи состоящие в группе wheel и пользователь root.
Пример:
virsh:
virsh -c qemu+tls://server.name/system,
virsh -c qemu+tls://kvm_server.local/system
ВАЖНО! server.name здесь- это именно то имя, что мы указывали при генерации сертификата для «ноды виртуализации»( поле cn сертификата), оно должно корректно определяться в ip на клиенте.
Virt-manager:
В virt-manager выбирать тип подключения- «ssl/tls с сертификатами», имя пользователя-пустое, имя хоста- server.name, о котором говорилось выше.
Virt-viewer:
virt-viewer -c qemu+tls://server.name/system имя_вм
Настройка клиента( Windows, только доступ к vnc консоли )
Выполняется на удаленной системе с которой будет происходить администрирование «ноды виртуализации».
Подключаться можно через:
virt-viewer
мне заставить работать не удалось
ssvnc
Для ssvnc ключ и сертификат клиента должны быть в одном файле, сделать это можно так(подразумевается что вы находитесь на сервере где изначально генерировали сертификаты):
cd /tmp/certs/client
cat client_certificate.pem client_key.pem >client.pem
Берем с сервера получившийся client.pem и /tmp/certs/ca/certificate_authority_certificate.pem
Запускаем ssvnc- в основном окне ставим «Use SSL», нажимаем «Certs» в «MyCerts» указываем путь к client.pem, в «ServerCert» указываем путь к certificate_authority_certificate.pem, далее жмем «Options» -> «Advanced» и ставим галочку напротив «Server uses Vencrypt ssl encryption». В основном окне в поле «Vnc Host:Display» указываем соответственно адрес сервера и номер vnc порта. Жмем «Connect».
Результат:
В итоге мы можем управлять нашими виртуальными машинами локально через virsh,virt-manager( доступны только те функции, которые поддерживает сервер). Минусы данного решения, что удаленное управление ВМ не отображается в логах ( или мне не удалось этого добиться), тоесть в логах не будет видно, что выключение/etc инициализировал такой-то пользователь с такого-то ip.
Ссылки по теме
wiki.libvirt.org/page/TLSSetup
wiki.libvirt.org/page/VNCTLSSetup
Автор: saamich