diff --git a/defaults/main.yml b/defaults/main.yml index 4ed393fe..4b0ba19c 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -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: #nova_user_ssl_key: #nova_user_ssl_ca_cert: + +# 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" diff --git a/handlers/main.yml b/handlers/main.yml index 01b9aa61..f4106935 100644 --- a/handlers/main.yml +++ b/handlers/main.yml @@ -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 diff --git a/releasenotes/notes/VNC-proxy-security-520e6dac6bad0018.yaml b/releasenotes/notes/VNC-proxy-security-520e6dac6bad0018.yaml new file mode 100644 index 00000000..1f842545 --- /dev/null +++ b/releasenotes/notes/VNC-proxy-security-520e6dac6bad0018.yaml @@ -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. diff --git a/tasks/main.yml b/tasks/main.yml index 49840d0a..8c538f32 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -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 diff --git a/templates/nova.conf.j2 b/templates/nova.conf.j2 index bc6fd83b..fa645801 100644 --- a/templates/nova.conf.j2 +++ b/templates/nova.conf.j2 @@ -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 diff --git a/templates/qemu.conf.j2 b/templates/qemu.conf.j2 index e5092a7b..ba79ec8d 100644 --- a/templates/qemu.conf.j2 +++ b/templates/qemu.conf.j2 @@ -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 %}