handle SSL connection in l2gateway agent

ovsdb server will initiate SSL connection to l2gateway agent, whenever
ovsdb manager table is populated with l2gateway agent IP with SSL.
This patch set will handle the ssl connection in the l2gw agent side.

Change-Id: I63f1f0465fdcbdc9ed6be0d98fb8e5b59e882eb0
Closes-Bug: 1585901
changes/71/322071/6
vikas 7 years ago
parent 4cb660909f
commit 3b5da5cf00

@ -14,6 +14,7 @@
# under the License.
import copy
import os.path
import socket
import ssl
import time
@ -46,6 +47,7 @@ class BaseConnection(object):
if self.enable_manager:
self.manager_table_listening_port = (
cfg.CONF.ovsdb.manager_table_listening_port)
self.ip_ovsdb_mapping = self._get_ovsdb_ip_mapping()
self.s = None
self.check_c_sock = None
self.check_sock_rcv = False
@ -89,6 +91,71 @@ class BaseConnection(object):
LOG.debug(OVSDB_CONNECTED_MSG, gw_config.ovsdb_ip)
self.connected = True
def _get_ovsdb_ip_mapping(self):
ovsdb_ip_mapping = {}
ovsdb_hosts = cfg.CONF.ovsdb.ovsdb_hosts
if ovsdb_hosts != '':
ovsdb_hosts = ovsdb_hosts.split(',')
for host in ovsdb_hosts:
host_splits = str(host).split(':')
ovsdb_identifier = str(host_splits[0]).strip()
ovsdb_ip = str(host_splits[1]).strip()
ovsdb_ip_mapping[ovsdb_ip] = ovsdb_identifier
return ovsdb_ip_mapping
def _is_ssl_configured(self, addr, client_sock):
priv_key_path = cfg.CONF.ovsdb.l2_gw_agent_priv_key_base_path
cert_path = cfg.CONF.ovsdb.l2_gw_agent_cert_base_path
ca_cert_path = cfg.CONF.ovsdb.l2_gw_agent_ca_cert_base_path
LOG.debug("ssl is enabled with priv_key_path %s, cert_path %s, "
"ca_cert_path %s", priv_key_path, cert_path, ca_cert_path)
use_ssl = priv_key_path and cert_path and ca_cert_path
if use_ssl:
if addr in self.ip_ovsdb_mapping.keys():
ovsdb_id = self.ip_ovsdb_mapping.get(addr)
priv_key_file = priv_key_path + "/" + ovsdb_id + ".key"
cert_file = cert_path + "/" + ovsdb_id + ".cert"
ca_cert_file = ca_cert_path + "/" + ovsdb_id + ".ca_cert"
is_priv_key = os.path.isfile(priv_key_file)
is_cert_file = os.path.isfile(cert_file)
is_ca_cert_file = os.path.isfile(ca_cert_file)
if not is_priv_key:
LOG.error(_LE("Could not find private key in"
" %(path)s dir, expecting in the "
"file name %(file)s "),
{'path': priv_key_path,
'file': ovsdb_id + ".key"})
return client_sock
if not is_cert_file:
LOG.error(_LE("Could not find cert in %(path)s dir, "
"expecting in the file name %(file)s"),
{'path': cert_path,
'file': ovsdb_id + ".cert"})
return client_sock
if not is_ca_cert_file:
LOG.error(_LE("Could not find cacert in %(path)s "
"dir, expecting in the file name "
"%(file)s"),
{'path': ca_cert_path,
'file': ovsdb_id + ".ca_cert"})
return client_sock
if (is_priv_key and is_cert_file and is_ca_cert_file):
ssl_conn_stream = ssl.wrap_socket(
client_sock,
server_side=True,
keyfile=priv_key_file,
certfile=cert_file,
ssl_version=ssl.PROTOCOL_SSLv23,
ca_certs=ca_cert_file)
client_sock = ssl_conn_stream
return client_sock
else:
LOG.error(_LE("you have enabled SSL for ovsdb %s, "
"expecting the ovsdb identifier and ovdb IP "
"entry in ovsdb_hosts in l2gateway_agent.ini"),
addr)
return client_sock
def _rcv_socket(self):
# Create a socket object.
self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
@ -103,6 +170,7 @@ class BaseConnection(object):
c_sock, ip_addr = self.s.accept()
addr = ip_addr[0]
c_sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
c_sock = self._is_ssl_configured(addr, c_sock)
LOG.debug("Got connection from %s ", addr)
self.connected = True
if addr in self.ovsdb_fd_states.keys():
@ -110,7 +178,8 @@ class BaseConnection(object):
if addr in self.ovsdb_conn_list:
self.ovsdb_conn_list.remove(addr)
if addr in self.ovsdb_dicts.keys():
self.ovsdb_dicts.get(addr).close()
if self.ovsdb_dicts.get(addr):
self.ovsdb_dicts.get(addr).close()
del self.ovsdb_dicts[addr]
self.ovsdb_dicts[addr] = c_sock
eventlet.greenthread.spawn(self._common_sock_rcv_thread, addr)

@ -16,6 +16,7 @@
import eventlet
import contextlib
import os.path
import socket
import ssl
import time
@ -291,3 +292,62 @@ class TestBaseConnection_with_enable_manager(base.BaseTestCase):
self.assertTrue(mock_close.called)
self.assertNotIn(fake_ip, self.l2gw_ovsdb_conn.ovsdb_fd_states)
self.assertNotIn(fake_ip, self.l2gw_ovsdb_conn.ovsdb_conn_list)
def test_get_ovsdb_ip_mapping(self):
expected_ovsdb_ip_mapping = {'10.10.10.10': 'ovsdb1'}
cfg.CONF.set_override('ovsdb_hosts',
'ovsdb1:10.10.10.10:6632',
'ovsdb')
return_mapping = self.l2gw_ovsdb_conn._get_ovsdb_ip_mapping()
self.assertEqual(expected_ovsdb_ip_mapping, return_mapping)
def test_is_ssl_configured(self):
self.l2gw_ovsdb_conn.ip_ovsdb_mapping = {'10.10.10.10': 'ovsdb1'}
cfg.CONF.set_override('l2_gw_agent_priv_key_base_path',
'/home',
'ovsdb')
cfg.CONF.set_override('l2_gw_agent_cert_base_path',
'/home',
'ovsdb')
cfg.CONF.set_override('l2_gw_agent_ca_cert_base_path',
'/home',
'ovsdb')
with contextlib.nested(
mock.patch.object(os.path, 'isfile', return_value=True),
mock.patch.object(base_connection.LOG, 'error'),
mock.patch.object(ssl, 'wrap_socket')
) as (mock_isfile, mock_error, mock_wrap_sock):
self.l2gw_ovsdb_conn._is_ssl_configured('10.10.10.10',
self.mock_sock)
self.assertTrue(mock_isfile.called)
self.assertTrue(mock_wrap_sock.called)
self.assertFalse(mock_error.called)
mock_wrap_sock.assert_called_with(
self.mock_sock,
server_side=True,
keyfile='/home/ovsdb1.key',
certfile='/home/ovsdb1.cert',
ssl_version=ssl.PROTOCOL_SSLv23,
ca_certs='/home/ovsdb1.ca_cert')
def test_is_ssl_configured_for_certs_not_found(self):
self.l2gw_ovsdb_conn.ip_ovsdb_mapping = {'10.10.10.10': 'ovsdb1'}
cfg.CONF.set_override('l2_gw_agent_priv_key_base_path',
'/home/',
'ovsdb')
cfg.CONF.set_override('l2_gw_agent_cert_base_path',
'/home/',
'ovsdb')
cfg.CONF.set_override('l2_gw_agent_ca_cert_base_path',
'/home/',
'ovsdb')
with contextlib.nested(
mock.patch.object(os.path, 'isfile', return_value=False),
mock.patch.object(base_connection.LOG, 'error'),
mock.patch.object(ssl, 'wrap_socket')
) as (mock_isfile, mock_error, mock_wrap_sock):
self.l2gw_ovsdb_conn._is_ssl_configured('10.10.10.10',
self.mock_sock)
self.assertTrue(mock_isfile.called)
self.assertFalse(mock_wrap_sock.called)
self.assertTrue(mock_error.called)

Loading…
Cancel
Save