aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSander Vrijders <sander.vrijders@ugent.be>2017-10-24 18:08:44 +0200
committerSander Vrijders <sander.vrijders@ugent.be>2017-10-24 18:08:44 +0200
commitd91a601494ba14172b6c239aa6c28e6256c62ca7 (patch)
tree2d14bc314dc10ea4e0b865305187357f0e0fefd4
parentc09a71b756ab3208ac02a006f9a4d54792b803b5 (diff)
downloadrumba-d91a601494ba14172b6c239aa6c28e6256c62ca7.tar.gz
rumba-d91a601494ba14172b6c239aa6c28e6256c62ca7.zip
ssh_support: Use native Paramiko API for Proxy
This uses the native paramiko API for proxycommands instead of invoking OpenSSH on the host after connecting to it since that gives race conditons with Paramiko.
-rw-r--r--rumba/model.py6
-rw-r--r--rumba/ssh_support.py57
-rw-r--r--rumba/testbeds/jfed.py6
3 files changed, 31 insertions, 38 deletions
diff --git a/rumba/model.py b/rumba/model.py
index 62125a6..7d7e214 100644
--- a/rumba/model.py
+++ b/rumba/model.py
@@ -192,12 +192,12 @@ class NormalDIF(DIF):
# SSH Configuration
#
class SSHConfig:
- def __init__(self, hostname, port=22, proxy_command=None):
+ def __init__(self, hostname, port=22, proxy_server=None):
self.username = None
self.password = None
self.hostname = hostname
self.port = port
- self.proxy_command = proxy_command
+ self.proxy_server = proxy_server
def set_username(self, username):
self.username = username
@@ -778,7 +778,7 @@ class Experiment:
self.testbed.username,
node.ssh_config.hostname,
node.ssh_config.port,
- node.ssh_config.proxy_command))
+ node.ssh_config.proxy_server))
f.close()
# Examine the nodes and DIFs, compute the registration and enrollment
diff --git a/rumba/ssh_support.py b/rumba/ssh_support.py
index 8ceee55..eff837d 100644
--- a/rumba/ssh_support.py
+++ b/rumba/ssh_support.py
@@ -57,16 +57,30 @@ def _print_stream(stream):
logger.debug(oi)
return o.rstrip()
-def ssh_connect(ssh_client, hostname, port, username, password, time_out,
- proxy):
+def ssh_connect(hostname, port, username, password, time_out, proxy_server):
retry = 0
max_retries = 10
while retry < max_retries:
time.sleep(retry * 5)
+
try:
+ if proxy_server is not None:
+ proxy_client = get_ssh_client()
+ # Assume port 22 for the proxy server for now
+ proxy_client.connect(proxy_server, 22, username, password,
+ look_for_keys=True, timeout=time_out)
+
+ trans = proxy_client.get_transport()
+ proxy = trans.open_channel('direct-tcpip',
+ (hostname, port), ('127.0.0.1', 0))
+ else:
+ proxy = None
+
+ ssh_client = get_ssh_client()
+
ssh_client.connect(hostname, port, username, password,
look_for_keys=True, timeout=time_out, sock=proxy)
- return
+ return ssh_client
except (paramiko.ssh_exception.SSHException, EOFError):
retry += 1
logger.error('Failed to connect to host, retrying: ' +
@@ -76,7 +90,7 @@ def ssh_connect(ssh_client, hostname, port, username, password, time_out,
logger.error(hostname + ' has a mismatching entry in ' +
'~/.ssh/known_hosts')
logger.error('If you are sure this is not a man in the ' +
- 'middle attack, edit that file to remove the' +
+ 'middle attack, edit that file to remove the ' +
'entry and then hit return to try again.')
input('Hit Enter when ready')
if retry == max_retries:
@@ -139,15 +153,10 @@ def execute_commands(testbed, ssh_config, commands, time_out=3):
no result received in given number of seconds, the value None can
be used when no timeout is needed
"""
- if ssh_config.proxy_command is not None:
- proxy = paramiko.ProxyCommand(ssh_config.proxy_command)
- else:
- proxy = None
-
- ssh_client = get_ssh_client()
- ssh_connect(ssh_client, ssh_config.hostname, ssh_config.port,
- testbed.username, testbed.password, time_out, proxy)
+ ssh_client = ssh_connect(ssh_config.hostname, ssh_config.port,
+ testbed.username, testbed.password, time_out,
+ ssh_config.proxy_server)
o = ""
for command in commands:
@@ -200,15 +209,10 @@ def write_text_to_file(testbed, ssh_config, text, file_name):
@param text: string to be written in file
@param file_name: file name (including full path) on the host
"""
- ssh_client = get_ssh_client()
- if ssh_config.proxy_command is not None:
- proxy = paramiko.ProxyCommand(ssh_config.proxy_command)
- else:
- proxy = None
-
- ssh_connect(ssh_client, ssh_config.hostname, ssh_config.port,
- testbed.username, testbed.password, None, proxy)
+ ssh_client = ssh_connect(ssh_config.hostname, ssh_config.port,
+ testbed.username, testbed.password, None,
+ ssh_config.proxy_server)
cmd = "touch " + file_name + "; chmod a+rwx " + file_name
@@ -238,19 +242,12 @@ def copy_files_to_testbed(testbed, ssh_config, paths, destination):
@param paths: source paths (local) as an iterable
@param destination: destination folder name (remote)
"""
- ssh_client = get_ssh_client()
-
- if ssh_config.proxy_command is not None:
- proxy = paramiko.ProxyCommand(ssh_config.proxy_command)
- else:
- proxy = None
-
if destination is not '' and not destination.endswith('/'):
destination = destination + '/'
-
- ssh_connect(ssh_client, ssh_config.hostname, ssh_config.port,
- testbed.username, testbed.password, None, proxy)
+ ssh_client = ssh_connect(ssh_config.hostname, ssh_config.port,
+ testbed.username, testbed.password, None,
+ ssh_config.proxy_server)
try:
sftp_client = ssh_client.open_sftp()
diff --git a/rumba/testbeds/jfed.py b/rumba/testbeds/jfed.py
index 7182143..3235ca2 100644
--- a/rumba/testbeds/jfed.py
+++ b/rumba/testbeds/jfed.py
@@ -206,11 +206,7 @@ class Testbed(mod.Testbed):
node.ssh_config.hostname = \
node.name + "." + self.exp_name + "." + \
auth_name_r + "." + self.auth_name
- node.ssh_config.proxy_command = "ssh -i '" + self.cert_file + \
- "' -o StrictHostKeyChecking=no " + \
- self.username + \
- "@bastion.test.iminds.be nc " + \
- node.ssh_config.hostname + " 22"
+ node.ssh_config.proxy_server = "bastion.test.iminds.be"
node.ssh_config.username = self.username
node.ssh_config.password = self.password