DSA-Schlüsselweiterleitung mit Paramiko?

Ich verwende Paramiko, um Bash-Skripte auf einem Remote-Server auszuführen. In einigen dieser Skripte gibt es SSH-Verbindungen zu anderen Servern. Wenn ich nur bash und kein Python verwende, wird mein DSA-Schlüssel weitergeleitet und vom bash-Skript auf dem ersten Remoteserver verwendet, um eine Verbindung zum zweiten Remoteserver herzustellen. Wenn ich Paramiko benutze, ist das nicht der Fall.

Bash-Beispiel:

Jean@mydesktop:~ & ssh root@firstserver
root@firstserver:~ # ssh root@secondserver hostname
secondserver.mydomain.org

Verwendung von Paramiko:

#!/usr/bin/python3
# -*- coding: utf-8 -*-

import paramiko

class SSHSession:


    def __init__(self, server_address, user='root', port=22):
        self.connected = False
        self.server_address = server_address
        self.user           = user
        self.port           = port


    def connect(self, clear_channel=True):
        try:
            if self.server_address == None:
                raise ValueError('No hostname')
        except:
            raise ValueError('No hostname')
        else:
            try:
                self.ssh_client = paramiko.SSHClient()
                self.ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
                self.ssh_client.connect(self.server_address, username=self.user)
                #self.transport = self.ssh_client.get_transport()
                #self.channel   = self.transport.open_forward_agent_channel()
                self.channel   = self.ssh_client.invoke_shell()
            except:
                self.connected = False
                return False
            else:
                self.connected = True
                return True

    def exec_command(self, command, newline='\r'):
        if not self.connected:
            raise Exception('Not connected')
        else:
            timeout = 31536000 # 365 days in seconds
            self.channel.settimeout(timeout)
            line_buffer    = ''
            channel_buffer = ''
            end_string     = 'CLIENT_EXPECT_CMD_OK'
            print('[SEND   ] >>', command)
            self.channel.send(command + ' ; echo ' + end_string + newline)
            while True:
                channel_buffer = self.channel.recv(1).decode('UTF-8')
                if len(channel_buffer) == 0:
                    raise Exception('connection lost with server: ' + self.server_address)
                    break 
                channel_buffer  = channel_buffer.replace('\r', '')
                if channel_buffer != '\n':
                    line_buffer += channel_buffer
                else:
                    if line_buffer == end_string:
                        break
                    print('[RECEIVE] <<', line_buffer)
                    line_buffer   = ''


    def disconnect(self):
        self.ssh_client.close()


    def __enter__(self):
        self.connect()
        return self


    def __exit__(self, _type, value, traceback):
        self.disconnect()


if __name__ == "__main__":
    server_address = 'firstserver'
    ssh_user       = 'root'
    with SSHSession(server_address) as ssh_session:
        ssh_session.exec_command('hostname')
        ssh_session.exec_command('ssh root@secondserver hostname')

Ausgabe ist:

[SEND   ] >> hostname
[RECEIVE] << [root@firstserver ~]# hostname ; echo CLIENT_EXPECT_CMD_OK
[RECEIVE] << firstserver.mydomain.fr
[SEND   ] >> ssh root@secondserver hostname
[RECEIVE] << [root@firstserver ~]# ssh root@secondserver hostname ; echo CLIENT_EXPECT_CMD_OK
[RECEIVE] << Permission denied (publickey,gssapi-keyex,gssapi-with-mic).

Ich habe es versucht:

self.transport = self.ssh_client.get_transport()
self.channel   = self.transport.open_forward_agent_channel()

anstatt :

self.channel   = self.ssh_client.invoke_shell()

aber dann bekomme ich einen fehler:

paramiko.ssh_exception.ChannelException: Administratively prohibited

Weiß jemand, ob das möglich ist? Ich fand Diskussionen, die darauf hindeuten, dass es das ist, aber ich finde noch nicht, wie ich das machen soll.

Antworten auf die Frage(2)

Ihre Antwort auf die Frage