Дружим virt-manager с удаленной системой поверх tls

от автора

На работе мы активно используем виртуализацию на базе 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

ссылка на оригинал статьи http://habrahabr.ru/post/221693/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *