-1

I need to execute a command in a remote server using paramiko Channel.

Code:

def handler(title, instructions, fields):
    if len(fields) > 1:
        raise sftp.SSHException("Expecting one field only.")
    return [password]


def create_sftp_client():
    #from transport object

    sftp.util.log_to_file("paramiko", level="DEBUG")

    transport = sftp.Transport(('myhost', 2222),
    default_max_packet_size=10000, default_window_size=10000)
    transport.connect(username='myuser', password='mypassword')
    transport.auth_interactive(username, handler)
    channel = transport.open_channel("session")
    channel.invoke_shell()
    channel.send('ls\n')

    return channel

Stacktrace:

Traceback (most recent call last):
  File "sftp.py", line 120, in <module>
    sftp_client = create_sftp_client()
  File "sftp.py", line 75, in create_sftp_client
    channel.invoke_shell()
  File "...\Python\Python37\Lib\site-packages\paramiko\channel.py", line 72, in _check
    return func(self, *args, **kwds)
  File "...Python\Python37\Lib\site-packages\paramiko\channel.py", line 230, in invoke_shell
    self._wait_for_event()
  File "...Python\Python37\Lib\site-packages\paramiko\channel.py", line 1208, in _wait_for_event
    raise e
paramiko.ssh_exception.SSHException: Channel closed.

Paramiko log:

DEB [20190404-09:16:14.653] thr=1   paramiko.transport: starting thread (client mode): 0x433b44e0
DEB [20190404-09:16:14.653] thr=1   paramiko.transport: Local version/idstring: SSH-2.0-paramiko_2.4.2
DEB [20190404-09:16:14.708] thr=1   paramiko.transport: Remote version/idstring: SSH-2.0-Server
INF [20190404-09:16:14.708] thr=1   paramiko.transport: Connected (version 2.0, client Server)
DEB [20190404-09:16:14.709] thr=1   paramiko.transport: kex algos:['ecdh-sha2-nistp521', 'ecdh-sha2-nistp384', 'ecdh-sha2-nistp256', 'diffie-hellman-group-exchange-sha256', 'diffie-hellman-group-exchange-sha1', 'diffie-hellman-group18-sha512', 'diffie-hellman-group17-sha512', 'diffie-hellman-group16-sha512', 'diffie-hellman-group15-sha512', 'diffie-hellman-group14-sha256', 'diffie-hellman-group14-sha1', 'diffie-hellman-group1-sha1'] server key:['ssh-rsa'] client encrypt:['aes128-ctr', 'aes192-ctr', 'aes256-ctr', 'arcfour256', 'arcfour128', 'aes128-cbc', '3des-cbc', 'blowfish-cbc', 'aes192-cbc', 'aes256-cbc'] server encrypt:['aes128-ctr', 'aes192-ctr', 'aes256-ctr', 'arcfour256', 'arcfour128', 'aes128-cbc', '3des-cbc', 'blowfish-cbc', 'aes192-cbc', 'aes256-cbc'] client mac:['hmac-md5', 'hmac-sha1', 'hmac-sha2-256', 'hmac-sha2-512', 'hmac-sha1-96', 'hmac-md5-96'] server mac:['hmac-md5', 'hmac-sha1', 'hmac-sha2-256', 'hmac-sha2-512', 'hmac-sha1-96', 'hmac-md5-96'] client compress:['none', 'zlib', 'zlib@openssh.com'] server compress:['none', 'zlib', 'zlib@openssh.com'] client lang:[''] server lang:[''] kex follows?False
DEB [20190404-09:16:14.709] thr=1   paramiko.transport: Kex agreed: ecdh-sha2-nistp256
DEB [20190404-09:16:14.709] thr=1   paramiko.transport: HostKey agreed: ssh-rsa
DEB [20190404-09:16:14.709] thr=1   paramiko.transport: Cipher agreed: aes128-ctr
DEB [20190404-09:16:14.709] thr=1   paramiko.transport: MAC agreed: hmac-sha2-256
DEB [20190404-09:16:14.709] thr=1   paramiko.transport: Compression agreed: none
DEB [20190404-09:16:15.004] thr=1   paramiko.transport: kex engine KexNistp256 specified hash_algo <built-in function openssl_sha256>
DEB [20190404-09:16:15.004] thr=1   paramiko.transport: Switch to new keys ...
DEB [20190404-09:16:15.004] thr=2   paramiko.transport: Attempting password auth...
DEB [20190404-09:16:15.155] thr=1   paramiko.transport: userauth is OK
INF [20190404-09:16:15.728] thr=1   paramiko.transport: Authentication continues...
DEB [20190404-09:16:15.728] thr=1   paramiko.transport: Methods: ['keyboard-interactive']
DEB [20190404-09:16:15.786] thr=1   paramiko.transport: userauth is OK
INF [20190404-09:16:16.213] thr=1   paramiko.transport: Authentication (keyboard-interactive) successful!
DEB [20190404-09:16:16.214] thr=2   paramiko.transport: [chan 0] Max packet in: 10000 bytes
DEB [20190404-09:16:16.268] thr=1   paramiko.transport: [chan 0] Max packet out: 32768 bytes
DEB [20190404-09:16:16.268] thr=1   paramiko.transport: Secsh channel 0 opened.
DEB [20190404-09:16:16.323] thr=1   paramiko.transport: [chan 0] EOF sent (0)
DEB [20190404-09:16:16.350] thr=1   paramiko.transport: EOF in transport thread

I tried solution below but did not help: https://github.com/paramiko/paramiko/issues/513#issuecomment-450426574

Any thoughts please?

ds_enth
  • 49
  • 3
  • 9
  • Why did you tag the question [tag:sftp]? – Martin Prikryl Apr 04 '19 at 14:04
  • Do you wish to send files, or just execute a command? In case of the later, you should rather use the SSHClient object. At least in this case you don't need to invoke a shell - you can directly execute the command after connecting. – Lucas Apr 04 '19 at 14:10
  • ideally I would need to download, upload and execute commands (dir list, etc) – ds_enth Apr 04 '19 at 15:15
  • To upload/upload, use SFTP. You cannot use "shell" or any command whatsoever to transfer files. --- To execute a (shell) command, see my answer. --- Your question is becoming way too broad. – Martin Prikryl Apr 04 '19 at 15:36

2 Answers2

1

There's no session SSH channel. There's shell channel.

Though for automating a command execution, you should actually use exec channel.
See Python Paramiko - Run command.

The shell channel is intended for implementing an interactive session (like if you are implementing your own SSH terminal, what you rarely want to do actually).

Martin Prikryl
  • 188,800
  • 56
  • 490
  • 992
  • Unless I'm reading the doc wrong, a `channel` could be opened from a `transport` using `kind="session"`: http://docs.paramiko.org/en/2.4/api/transport.html#paramiko.transport.Transport.open_channel – ds_enth Apr 04 '19 at 19:30
  • Sorry, you are right! I misinterpreted the parameter purpose. `Transport.open_channel` is not a method you actually want to call directly. You should call `Transport.open_session` or `Transport.open_sftp_client`. --- Anyway, your code works just fine for me. --- Can you open a shell session to that server using regular SSH client? --- Does opening SFTP channel work? `sftp = SFTPClient.from_transport(transport)` --- It's bit confusing that your function is called `create_sftp_client`, yet you are opening a shell session. – Martin Prikryl Apr 05 '19 at 05:18
  • What do you actually want to do? What is `ls`? Is that a shell command or "SFTP command"? If the latter, read [my answer](https://stackoverflow.com/q/54761747/850848#54763508) to [Executing SFTP commands using Paramiko in Python](https://stackoverflow.com/q/54761747/850848). – Martin Prikryl Apr 05 '19 at 05:23
  • The final goal is to be able to connect an get/put files. Now I switched to use `SSHClient()`: https://pastebin.com/TE3CUthc Stacktrace: https://pastebin.com/MNvMu57Q Paramiko log: https://pastebin.com/79tRZjiA I think that the server does not accept password auth, my guess is: `# /etc/ssh/sshd_config PasswordAuthentication no ChallengeResponseAuthentication yes` Is it possible to handle interactive auth when the sftp client is not created from a `transport`? – ds_enth Apr 05 '19 at 15:46
  • I'm very likely in this case where Amazon disables ssh password auth by default: https://serverpilot.io/docs/how-to-enable-ssh-password-authentication I have no access to confirm though. Have to wait for my devops to do so.... – ds_enth Apr 05 '19 at 16:01
  • OK, so did you follow the links in my previous comment? Your are **on a completely wrong track**. Your code has **nothing to do with file uploads and downloads**. It looks like you think you will send `put` and `get` commands to the "shell". That's not how SFTP works. Your `create_**sftp**_client` function has nothing to do with SFTP. Please read the answers to the linked questions carefully again! – Martin Prikryl Apr 06 '19 at 07:07
  • As you can authenticate with the `Transport` class, you need this code: https://stackoverflow.com/q/3635131/850848#3635163 (`sftp = SFTPClient.from_transport(transport)` followed by `sftp.get` or `sftp.put`) – Martin Prikryl Apr 06 '19 at 07:09
-1

I decided to not use paramiko for that specific case. I will go with another library (ssh2 may be).

The amount of time invested and the plethora of errors just to guess why a channel gets closed immediately after being opened or authentication failing makes it hard to continue that way.

ds_enth
  • 49
  • 3
  • 9
  • 1
    1) This does not answer the question. 2) No matter what library you will use, you will have to understand what the `shell`, `exec` and `sftp` channels are good for and when to use them. This is how SSH works. That's nothing Paramiko-specific. If you switch to another library, you will just have to start from the scratch, dealing with the same stuff you are now. Paramiko is by far the most widely used Python SSH library and you will find way more examples on using it than for others. – Martin Prikryl Apr 04 '19 at 18:08
  • Got you point. As I explained before, ideally I would have to execute and download/upload data, this is why I'm testing both use cases. I'm hitting a wall no matter I use a `client` or `transport`. I'm not used to network programming so I suppose that's another slowing stone. The answers seem not to care about the logs/info I posted (true question here is why the channel gets closed?). It's true that educating newbies is important. But, trying to answer the real questions is the most urgent priority. Senior people tend to forget about that. Having that said, thanks for all the hints! – ds_enth Apr 04 '19 at 18:52