Configure TLS for OVN

This patch configures TLS for OVN to use the local CA cert on the
controller. The compute nodes request certificates to be provided by the
CA cert and will use those certificates to configure local controller
connections to the OVN SB database via TLS. The client certificates are
validated against the control nodes CA.

Local connections on the control node continue to use the local unix
socket, which should be considered to be secure since it does not egress
the node.

Change-Id: Iacf5d5637c3a093bd80879c2ebb58efb16b52e66
This commit is contained in:
Billy Olsen 2021-10-15 15:30:58 -07:00
parent ba1fd62508
commit 2385344b11
2 changed files with 57 additions and 18 deletions

View File

@ -177,12 +177,12 @@ def init() -> None:
question_list = [
questions.DnsServers(),
questions.DnsDomain(),
questions.TlsCertificates(),
questions.NetworkSettings(),
questions.OsPassword(), # TODO: turn this off if COMPUTE.
# The following are not yet implemented:
# questions.VmSwappiness(),
# questions.FileHandleLimits(),
questions.TlsCertificates(),
questions.DashboardAccess(),
questions.RabbitMq(),
questions.DatabaseSetup(),

View File

@ -26,6 +26,7 @@ limitations under the License.
import json
import platform
import os
import socket
import stat
from time import sleep
@ -210,30 +211,72 @@ class NetworkSettings(Question):
network.ExtGateway().ask()
network.ExtCidr().ask()
control_ip = check_output('snapctl', 'get',
'config.network.control-ip')
# The cacert will always be the same, regardless of the current
# node's role (control or compute)
ssl_cacert = shell.config_get('config.tls.cacert-path')
system_id = socket.getfqdn()
if role == 'control':
nb_conn = 'unix:{SNAP_COMMON}/run/ovn/ovnnb_db.sock'.format(**_env)
sb_conn = 'unix:{SNAP_COMMON}/run/ovn/ovnsb_db.sock'.format(**_env)
check_output('ovs-vsctl', 'set', 'open', '.',
f'external-ids:ovn-encap-ip={control_ip}')
ssl_key = shell.config_get('config.tls.key-path')
ssl_cert = shell.config_get('config.tls.cert-path')
ovn_encap_ip = control_ip
elif role == 'compute':
sb_conn = f'tcp:{control_ip}:6642'
# Use the local compute node's ssl_key and ssl_cert for OVN
# configuration.
ssl_key = shell.config_get('config.tls.compute.key-path')
ssl_cert = shell.config_get('config.tls.compute.cert-path')
sb_conn = f'ssl:{control_ip}:6642'
# Not used by any compute node services.
nb_conn = ''
compute_ip = check_output('snapctl', 'get',
'config.network.compute-ip')
# Set the IP address to be used for a tunnel endpoint.
check_output('ovs-vsctl', 'set', 'open', '.',
f'external-ids:ovn-encap-ip={compute_ip}')
ovn_encap_ip = compute_ip
else:
raise Exception(f'Unexpected node role: {role}')
# ovn-controller does not start unless both the ovn-encap-ip and the
# ovn-encap-type are set.
check_output('ovs-vsctl', 'set', 'open', '.',
'external-ids:ovn-encap-type=geneve')
log.debug('Configuring Open vSwitch geneve tunnels and system id. '
f'ovn-encap-ip = {ovn_encap_ip}, system-id = {system_id}')
check_output(
'ovs-vsctl',
'set', 'open', '.', 'external-ids:ovn-encap-type=geneve',
'--',
'set', 'open', '.', f'external-ids:ovn-encap-ip={ovn_encap_ip}',
'--',
'set', 'open', '.', f'external-ids:system-id={system_id}'
)
# Configure the TLS settings for Open vSwitch and OVN. Note, the
# ovn-wrapper is used as it has the necessary configuration to use
# socket connections.
log.debug('Configuring TLS for Open vSwitch and OVN')
check_output(
'ovs-vsctl', 'set-ssl', ssl_key, ssl_cert, ssl_cacert
)
if role == 'control':
check_output(
'ovn-wrapper', 'ovn-sbctl', 'set-ssl', ssl_key, ssl_cert,
ssl_cacert
)
check_output(
'ovn-wrapper', 'ovn-sbctl', 'set-connection', 'pssl:6642'
)
# Note: by default, the control node will serve as a gateway node
# for the cluster. Only set the enable-chassis-as-gw for the
# control node.
check_output(
'ovs-vsctl', 'set', 'open', '.',
'external-ids:ovn-cms-options=enable-chassis-as-gw'
)
restart('ovn-ovsdb-server-sb')
# Configure OVN SB and NB sockets based on the role node. For
# single-node deployments there is no need to use a TCP socket.
@ -244,22 +287,17 @@ class NetworkSettings(Question):
# Set SB database connection details for ovn-controller to pick up.
check_output(
'ovs-vsctl', 'set', 'open', '.',
f'external-ids:ovn-remote={sb_conn}'
)
check_output(
'ovs-vsctl', 'set', 'open', '.',
'external-ids:ovn-cms-options=enable-chassis-as-gw'
'ovs-vsctl', 'set', 'open', '.',
f'external-ids:ovn-remote={sb_conn}'
)
# Now that we have default or overriden values, setup the
# Now that we have default or overridden values, setup the
# bridge and write all the proper values into our config
# files.
check('setup-br-ex')
check('snap-openstack', 'setup')
if role == 'control':
enable('ovn-northd')
enable('ovn-controller')
@ -321,8 +359,9 @@ class TlsCertificates(Question):
Path(shell.config_get('config.tls.cert-path')),
Path(shell.config_get('config.tls.key-path')),
)
control_ip = shell.config_get('config.network.control-ip')
tls.generate_self_signed(cert_path, key_path,
ip=_env['control_ip'])
ip=control_ip)
copyfile(Path(shell.config_get('config.tls.cert-path')),
Path(shell.config_get('config.tls.cacert-path')))
restart('nginx')