Skip to content

Commit 0c7f61b

Browse files
committed
Add ngs_ssh_disabled_algorithms setting
This requires netmiko >= 4.0.0 and paramiko >= 2.6.0 so that the following change is available: ktbyers/netmiko#2646 Change-Id: I6f5d520a1ce5750e2feda9119edfcda9471a1fad
1 parent 39cb7f0 commit 0c7f61b

File tree

5 files changed

+67
-0
lines changed

5 files changed

+67
-0
lines changed

doc/source/configuration.rst

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -386,3 +386,26 @@ If no physical network is declared in a switch configuration, then VLANs for
386386
all physical networks will be created on this switch.
387387

388388
Note that this option is only used if ``ngs_manage_vlans = True``.
389+
390+
SSH algorithm configuration
391+
===========================
392+
393+
You may need to tune the SSH negotiation process for some devices. Reasons
394+
include using a faster key exchange algorithm, disabling an algorithm that
395+
has a buggy implementation on the target device, or working around limitations
396+
related to FIPS requirements.
397+
398+
The ``ngs_ssh_disabled_algorithms`` configuration parameter allows to selectively
399+
disable algorithms of a given type (key exchange, cipher, MAC, etc). It is based
400+
on `Paramiko's disabled_algorithms setting
401+
<https://docs.paramiko.org/en/stable/api/transport.html#paramiko.transport.Transport.__init__>`__.
402+
403+
The format is a list of ``<type>:<algorithm>`` entries to disable. The same type
404+
can be repeated several times with different algorithms. Here is an example configuration::
405+
406+
[genericswitch:device-hostname]
407+
ngs_ssh_disabled_algorithms = kex:diffie-hellman-group-exchange-sha1, ciphers:blowfish-cbc, ciphers:3des-cbc
408+
409+
As of Paramiko 2.9.1, the valid types are ``ciphers``, ``macs``, ``keys``, ``pubkeys``,
410+
``kex``, ``gsskex``. However, this might change depending on the version of Paramiko.
411+
Check Paramiko source code or documentation to determine the accepted algorithm types.

networking_generic_switch/devices/__init__.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
import abc
1616

17+
from neutron_lib.utils.helpers import parse_mappings
1718
from oslo_log import log as logging
1819
from oslo_utils import strutils
1920
import stevedore
@@ -31,6 +32,9 @@
3132
{'name': 'ngs_port_default_vlan'},
3233
# Comma-separated list of physical networks to which this switch is mapped.
3334
{'name': 'ngs_physical_networks'},
35+
# Comma-separated list of entries formatted as "<type>:<algorithm>",
36+
# specifying SSH algorithms to disable.
37+
{'name': 'ngs_ssh_disabled_algorithms'},
3438
{'name': 'ngs_ssh_connect_timeout', 'default': 60},
3539
{'name': 'ngs_ssh_connect_interval', 'default': 10},
3640
{'name': 'ngs_max_connections', 'default': 1},
@@ -139,6 +143,18 @@ def _get_network_name(self, network_id, segmentation_id):
139143
return network_name_format.format(network_id=network_id,
140144
segmentation_id=segmentation_id)
141145

146+
def _get_ssh_disabled_algorithms(self):
147+
"""Return a dict of SSH algorithms to disable.
148+
149+
The dict is in a suitable format for feeding to Netmiko/Paramiko.
150+
"""
151+
algorithms = self.ngs_config.get('ngs_ssh_disabled_algorithms')
152+
if not algorithms:
153+
return {}
154+
# Builds a dict: keys are types, values are list of algorithms
155+
return parse_mappings(algorithms.split(','), unique_keys=False,
156+
unique_values=False)
157+
142158
def _do_vlan_management(self):
143159
"""Check if drivers should add and remove VLANs from switches."""
144160
return strutils.bool_from_string(self.ngs_config['ngs_manage_vlans'])

networking_generic_switch/devices/netmiko_devices/__init__.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,11 @@ def __init__(self, device_cfg):
108108
raise exc.GenericSwitchNetmikoNotSupported(
109109
device_type=device_type)
110110
self.config['device_type'] = device_type
111+
# Don't pass disabled_algorithms by default to keep compatibility
112+
# with older versions of Netmiko.
113+
disabled_algorithms = self._get_ssh_disabled_algorithms()
114+
if disabled_algorithms:
115+
self.config['disabled_algorithms'] = disabled_algorithms
111116
if CONF.ngs.session_log_file:
112117
self.config['session_log'] = CONF.ngs.session_log_file
113118
self.config['session_log_record_writes'] = True

networking_generic_switch/tests/unit/test_devices.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,3 +202,19 @@ def test__get_network_name_both(self):
202202
device = FakeDevice(device_cfg)
203203
name = device._get_network_name('fake-id', 22)
204204
self.assertEqual('fake-id_net_22', name)
205+
206+
def test__get_ssh_disabled_algorithms(self):
207+
algos = (
208+
"kex:diffie-hellman-group-exchange-sha1, "
209+
"ciphers:blowfish-cbc, ciphers:3des-cbc"
210+
)
211+
device_cfg = {
212+
"ngs_ssh_disabled_algorithms": algos
213+
}
214+
device = FakeDevice(device_cfg)
215+
algos = device._get_ssh_disabled_algorithms()
216+
expected = {
217+
"kex": ["diffie-hellman-group-exchange-sha1"],
218+
"ciphers": ["blowfish-cbc", "3des-cbc"],
219+
}
220+
self.assertEqual(expected, algos)
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
features:
3+
- |
4+
Add new device setting ``ngs_ssh_disabled_algorithms``. This allows to
5+
selectively disable SSH algorithms of various types, which may help to
6+
speed up SSH connection (faster key exchange algorithm) or to workaround
7+
buggy SSH implementations found on some devices.

0 commit comments

Comments
 (0)