Enable TLS for VNC from novncproxy to compute hosts

To secure communications from the proxy server to the compute
nodes using VeNCrypt authentication scheme.

In a previous patch a TLS server certificate was deployed to
compute nodes, this patch makes use of this same server cert for
securing VNC sessions on compute nodes. It is recommended that
this certificate be issued by a dedicated certificate authority
solely for the VNC service, as libvirt does not currently have a
mechanism to restrict what certificates can be presented by the
proxy server. This has not been implemented to reduce complexity.

In addition the noVNC proxy needs to present a client certificate
so only approved VNC proxy servers can connect to the Compute nodes.
The PKI role has been used to create a client certificate for the
nova console nodes.

Related Nova docs:
https://docs.openstack.org/nova/latest/admin/remote-console-access.html

To help with the transition from from unencrypted VNC to VeNCrypt,
initially compute nodes auth scheme allows for both encrypted and
unencrypted sessions using the variable `nova_vencrypt_auth_scheme`, this
will be removed in future releases.

Change-Id: Iafb788f80fd401c6ce6e4576bafd06c92431bd65
This commit is contained in:
James Gibson 2021-11-08 15:40:27 +00:00
parent ad8bda5f64
commit 2b8d5a0b88
6 changed files with 110 additions and 9 deletions

View File

@ -276,6 +276,18 @@ nova_console_ssl_dir: "/etc/nova/ssl"
nova_console_ssl_cert: "{{ nova_console_ssl_dir }}/nova-console.pem"
nova_console_ssl_key: "{{ nova_console_ssl_dir }}/nova-console.key"
# Enable TLS on VNC connection from novnc to compute hosts
nova_qemu_vnc_tls: 1
nova_vencrypt_client_key: "/etc/pki/nova-novncproxy/client-key.pem"
nova_vencrypt_client_cert: "/etc/pki/nova-novncproxy/client-cert.pem"
nova_vencrypt_ca_certs: "/etc/pki/nova-novncproxy/ca-cert.pem"
# The auth_schemes values should be listed in order of preference.
# If enabling VeNCrypt on an existing deployment which already has instances running,
# the noVNC proxy server must initially be allowed to use vencrypt and none.
# Once it is confirmed that all Compute nodes have VeNCrypt enabled for VNC,
# it is possible to remove the none option from the list
nova_vencrypt_auth_scheme: "vencrypt,none"
# Set to true when terminating SSL/TLS at a load balancer
nova_external_ssl: "{{ openstack_external_ssl | default(False) }}"
@ -548,8 +560,8 @@ nova_pki_intermediate_cert_name: "{{ openstack_pki_service_intermediate_cert_nam
nova_pki_intermediate_chain_path: "{{ nova_pki_dir ~ '/roots/' ~ nova_pki_intermediate_cert_name ~ '/certs/' ~ nova_pki_intermediate_cert_name ~ '-chain.crt' }}"
nova_pki_regen_cert: ''
# Create client and server cert for compute hosts
# This certiticate is used during TLS live migrations
nova_pki_certificates:
# This certiticate is used to secure TLS live migrations and VNC sessions
nova_pki_compute_certificates:
- name: "nova_{{ ansible_facts['hostname'] }}"
provider: ownca
cn: "{{ ansible_facts['nodename'] }}"
@ -568,9 +580,8 @@ nova_libvirt_ssl_dir: /etc/pki/libvirt
# QEMU default destination files for SSL certificates
nova_qemu_ssl_dir: /etc/pki/qemu
# Installation details for SSL certificates for TLS live migration
nova_pki_install_certificates:
# Server certificate used by libvirt for live migrations
# Installation details for SSL certificates for compute hosts TLS live migration
nova_pki_compute_install_certificates:
- src: "{{ nova_user_ssl_cert | default(nova_pki_certs_path ~ 'nova_' ~ ansible_facts['hostname'] ~ '-chain.crt') }}"
dest: "{{ nova_libvirt_ssl_dir }}/servercert.pem"
owner: "root"
@ -640,3 +651,36 @@ nova_pki_install_certificates:
#nova_user_ssl_cert: <path to cert on ansible deployment host>
#nova_user_ssl_key: <path to cert on ansible deployment host>
#nova_user_ssl_ca_cert: <path to cert on ansible deployment host>
# TLS certficates for console hosts
nova_pki_console_certificates:
# Client certificate used by novnv proxy to authenticate with compute hosts using vencrypt
- name: "nova_{{ ansible_facts['hostname'] }}-client"
provider: ownca
cn: "{{ ansible_facts['nodename'] }}"
san: "{{ 'DNS:' ~ ansible_facts['hostname'] ~ ',DNS:' ~ ansible_facts['nodename'] ~ ',IP:' ~ (nova_management_address == 'localhost') | ternary('127.0.0.1', nova_management_address) }}"
signed_by: "{{ nova_pki_intermediate_cert_name }}"
key_usage:
- digitalSignature
- keyAgreement
- keyEncipherment
extended_key_usage:
- clientAuth
# Installation details for SSL certificates for console hosts
nova_pki_console_install_certificates:
- src: "{{ nova_user_ssl_cert | default(nova_pki_certs_path ~ 'nova_' ~ ansible_facts['hostname'] ~ '-client-chain.crt') }}"
dest: "{{ nova_vencrypt_client_cert }}"
owner: "root"
group: "{{ nova_system_group_name }}"
mode: "0640"
- src: "{{ nova_user_ssl_key | default(nova_pki_keys_path ~ 'nova_' ~ ansible_facts['hostname'] ~ '-client.key.pem') }}"
dest: "{{ nova_vencrypt_client_key }}"
owner: "root"
group: "{{ nova_system_group_name }}"
mode: "0640"
- src: "{{ nova_user_ssl_ca_cert | default(nova_pki_intermediate_chain_path) }}"
dest: "{{ nova_vencrypt_ca_certs }}"
owner: "root"
group: "{{ nova_system_group_name }}"
mode: "0640"

View File

@ -21,6 +21,9 @@
listen:
- Restart libvirt-bin
- "cert installed"
when:
- "'nova_compute' in group_names"
- nova_virt_type != 'ironic'
- name: Enable sockets when needed
service:
@ -37,7 +40,6 @@
condition: "{{ nova_libvirtd_listen_tcp | bool }}"
listen:
- Restart libvirt-bin
- "cert installed"
- name: Start libvirt-bin
service:
@ -47,6 +49,9 @@
listen:
- Restart libvirt-bin
- "cert installed"
when:
- "'nova_compute' in group_names"
- nova_virt_type != 'ironic'
- name: Stop services
service:
@ -62,6 +67,7 @@
listen:
- "Restart nova services"
- "venv changed"
- "cert installed"
# NOTE (noonedeadpunk): Remove this task after Xena release
- name: Remove obsoleted policy.json
@ -86,6 +92,7 @@
listen:
- "Restart nova services"
- "venv changed"
- "cert installed"
- meta: noop
listen: Manage LB

View File

@ -0,0 +1,16 @@
---
features:
- |
Enable VeNCrypt authentication scheme from noVNC proxy to compute nodes.
When using HTTPS, the TLS encryption only applies to data between the
tenant user and proxy server. To provide protection from the noVNC proxy
to the Compute Nodes, it is necessary to enable the VeNCrypt
authentication scheme for VNC.
A pre-existing PKI (Public Key Infrastructure) setup is
required.
Initially to help with the transition from unencrypted VNC to
VeNCrypt, compute nodes auth scheme allows for both encrypted and
unencrypted sessions using the variable `nova_vencrypt_auth_scheme`,
this will be removed in future releases.

View File

@ -120,7 +120,7 @@
- nova-config
# Create certs after libvirt groups have been created but before handlers
- name: Create and install SSL certificates
- name: Create and install SSL certificates for compute hosts
include_role:
name: pki
tasks_from: main_certs.yml
@ -129,12 +129,29 @@
pki_dir: "{{ nova_pki_dir }}"
pki_create_certificates: "{{ nova_user_ssl_cert is not defined and nova_user_ssl_key is not defined }}"
pki_regen_certificates: "{{ nova_pki_regen_cert }}"
pki_certificates: "{{ nova_pki_certificates }}"
pki_install_certificates: "{{ nova_pki_install_certificates }}"
pki_certificates: "{{ nova_pki_compute_certificates }}"
pki_install_certificates: "{{ nova_pki_compute_install_certificates }}"
when:
- nova_libvirtd_listen_tls == 1
- "'nova_compute' in group_names"
# Create certs after nova groups have been created but before handlers
- name: Create and install SSL certificates for console hosts
include_role:
name: pki
tasks_from: main_certs.yml
vars:
pki_setup_host: "{{ nova_pki_setup_host }}"
pki_dir: "{{ nova_pki_dir }}"
pki_create_certificates: "{{ nova_user_ssl_cert is not defined and nova_user_ssl_key is not defined }}"
pki_regen_certificates: "{{ nova_pki_regen_cert }}"
pki_certificates: "{{ nova_pki_console_certificates }}"
pki_install_certificates: "{{ nova_pki_console_install_certificates }}"
when:
- nova_qemu_vnc_tls == 1
- nova_console_type == 'novnc'
- "'nova_console' in group_names"
- import_tasks: nova_post_install.yml
tags:
- nova-config

View File

@ -98,6 +98,13 @@ novncproxy_port = {{ nova_novncproxy_port }}
server_listen = {{ nova_novncproxy_vncserver_listen }}
server_proxyclient_address = {{ nova_novncproxy_vncserver_proxyclient_address }}
{% if nova_qemu_vnc_tls == 1 %}
auth_schemes={{ nova_vencrypt_auth_scheme }}
vencrypt_client_key={{ nova_vencrypt_client_key }}
vencrypt_client_cert={{ nova_vencrypt_client_cert }}
vencrypt_ca_certs={{ nova_vencrypt_ca_certs }}
{% endif %}
{% elif nova_console_type == 'serialconsole' %}
[serial_console]
enabled = True

View File

@ -62,6 +62,16 @@ default_tls_x509_cert_dir = "{{ nova_qemu_ssl_dir }}"
default_tls_x509_verify = 1
{% endif %}
# Enable use of TLS encryption on the VNC server. This requires
# a VNC client which supports the VeNCrypt protocol extension.
# Examples include vinagre, virt-viewer, virt-manager and vencrypt
# itself. UltraVNC, RealVNC, TightVNC do not support this
#
# It is necessary to setup CA and issue a server certificate
# before enabling this.
#
vnc_tls = {{ nova_qemu_vnc_tls }}
{% for key, value in _nova_qemu_conf.items() %}
{{ key }} = {{ value }}
{% endfor %}