StackStorm / st2

StackStorm (aka "IFTTT for Ops") is event-driven automation for auto-remediation, incident responses, troubleshooting, deployments, and more for DevOps and SREs. Includes rules engine, workflow, 160 integration packs with 6000+ actions (see https://exchange.stackstorm.org) and ChatOps. Installer at https://docs.stackstorm.com/install/index.html
https://stackstorm.com/
Apache License 2.0
6.06k stars 745 forks source link

ssh_config and proxycommands throw a traceback #3527

Open eedgar opened 7 years ago

eedgar commented 7 years ago
[ssh_runner]
remote_dir = /tmp
use_ssh_config = true
ssh_config_file_path = /home/eedgar/.ssh/config

config contains

Host na01_useast1
HostName bastion.test.com
ForwardAgent yes
Host 10.12.*
UserKnownHostsFile=/dev/null
StrictHostKeyChecking no
ProxyCommand ssh -q -W %h:%p na01_useast1
st2 run core.remote cmd=whoami hosts=10.12.29.240
2017-06-28 13:48:51,304 DEBUG [-] Runner dispatch produced result: {'traceback': ' File "/home/eedgar/st2/st2actions/st2actions/container/base.py", line 91, in _do_run\n runner.pre_run()\n File "/home/eedgar/st2/st2common/st2common/runners/paramiko_ssh_runner.py", line 145, in pre_run\n self._parallel_ssh_client = ParallelSSHClient(**client_kwargs)\n File "/home/eedgar/st2/st2common/st2common/runners/parallel_ssh.py", line 66, in init\n connect_results = self.connect(raise_on_any_error=raise_on_any_error)\n File "/home/eedgar/st2/st2common/st2common/runners/parallel_ssh.py", line 96, in connect\n raise NoHostsConnectedToException(msg)\n', 'error': 'Unable to connect to any one of the hosts: [u\'10.12.X.X\'].\n\n connect_errors={\n "10.12.X.X": {\n "failed": true, \n "traceback": "Traceback (most recent call last):\n File \"/home/eedgar/st2/st2common/st2common/runners/parallel_ssh.py\", line 248, in _connect\n client.connect()\n File \"/home/eedgar/st2/st2common/st2common/runners/paramiko_ssh.py\", line 138, in connect\n self.client = self._connect(host=self.hostname, socket=self.bastion_socket)\n File \"/home/eedgar/st2/st2common/st2common/runners/paramiko_ssh.py\", line 634, in _connect\n raise SSHException(msg)\nSSHException: Error connecting to host 10.12.X.X with connection parameters {\'username\': \'eedgar\', \'key_filename\': \'/home/eedgar/.ssh/id_rsa\', \'allow_agent\': False, \'hostname\': u\'10.12.X.X\', \'sock\': <paramiko.proxy.ProxyCommand object at 0x7f27b454be50>, \'look_for_keys\': False, \'timeout\': 60, \'port\': 22}.Paramiko error: \"ProxyCommand (ssh -q -W 10.12.X.X:22 na01_useast1)\" returned non-zero exit status: Broken pipe.\n", \n "timeout": false, \n "succeeded": false, \n "stdout": "", \n "stderr": "", \n "error": "Connection error. Error connecting to host 10.12.X.X with connection parameters {\'username\': \'eedgar\', \'key_filename\': \'/home/eedgar/.ssh/id_rsa\', \'allow_agent\': False, \'hostname\': u\'10.12.X.X\', \'sock\': <paramiko.proxy.ProxyCommand object at 0x7f27b454be50>, \'look_for_keys\': False, \'timeout\': 60, \'port\': 22}.Paramiko error: \"ProxyCommand (ssh -q -W 10.12.X.X:22 na01_useast1)\" returned non-zero exit status: Broken pipe.", \n "return_code": 255\n }\n}'}

we are just trying to setup a ssh jumphost and reuse the ssh_config for that.

eedgar commented 7 years ago

https://github.com/paramiko/paramiko/issues/337 https://github.com/paramiko/paramiko/issues/389

eedgar commented 7 years ago

Workaround

diff --git a/st2common/st2common/runners/paramiko_ssh.py b/st2common/st2common/runners/paramiko_ssh.py
index 599d0af..6038619 100644
--- a/st2common/st2common/runners/paramiko_ssh.py
+++ b/st2common/st2common/runners/paramiko_ssh.py
@@ -125,6 +125,13 @@ class ParamikoSSHClient(object):
                  False otherwise.
         :rtype: ``bool``
         """
+        ssh_config_file_info = {}
+        if cfg.CONF.ssh_runner.use_ssh_config:
+            ssh_config_file_info = self._get_ssh_config_for_host(self.hostname)
+
+            if 'bastion_host' in ssh_config_file_info:
+                self.bastion_host = ssh_config_file_info['bastion_host']
+
         if self.bastion_host:
             self.logger.debug('Bastion host specified, connecting')
             self.bastion_client = self._connect(host=self.bastion_host)
@@ -661,7 +668,13 @@ class ParamikoSSHClient(object):
                 ssh_config_info['identityfile'] = key_file

             if 'proxycommand' in ssh_config:
-                ssh_config_info['sock'] = paramiko.ProxyCommand(ssh_config['proxycommand'])
+                # This is an ugly hack as paramiko.ProxyCommand isnt working :/
+                # Assumes proxy command of ssh -W %h %p bastion
+                proxy_command_split = ssh_config['proxycommand'].split()
+                if proxy_command_split[0] == 'ssh':
+                    ssh_config_info['bastion_host'] = ssh_config_parser.lookup(proxy_command_split[-1])['hostname']
+
+                #ssh_config_info['sock'] = paramiko.ProxyCommand(ssh_config['proxycommand'])

         return ssh_config_info
stale[bot] commented 5 years ago

Thanks for contributing to this issue. As it has been 90 days since the last activity, we are automatically marking is as stale. If this issue is not relevant or applicable anymore (problem has been fixed in a new version or similar), please close the issue or let us know so we can close it. On the contrary, if the issue is still relevant, there is nothing you need to do, but if you have any additional details or context which would help us when working on this issue, please include it as a comment to this issue.