[recovery mode] Дружим 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/TLSSetupwiki.libvirt.org/page/VNCTLSSetup