Подтвердить что ты не робот

Как сделать ssh-соединение с python?

Может ли кто-нибудь порекомендовать что-то для создания ssh-соединения в python? Мне нужно, чтобы он был совместим с любой ОС.

Я уже пробовал pyssh только для получения ошибки с SIGCHLD, которую я прочитал, потому что Windows этого не хватает. Я попытался заставить paramiko работать, но у меня были ошибки между paramiko и Crypto до такой степени, что последние версии каждого из них не будут работать вместе.

Python 2.6.1 в настоящее время на компьютере под управлением Windows.

4b9b3361

Ответ 1

Модуль pxssh выполняет именно то, что вы хотите.
Например, чтобы запустить 'ls -l' и распечатать вывод, вам нужно сделать что-то вроде этого:

from pexpect import pxssh
s = pxssh.pxssh()
if not s.login ('localhost', 'myusername', 'mypassword'):
    print "SSH session failed on login."
    print str(s)
else:
    print "SSH session login successful"
    s.sendline ('ls -l')
    s.prompt()         # match the prompt
    print s.before     # print everything before the prompt.
    s.logout()

Некоторые ссылки:
Pxssh docs: http://dsnra.jpl.nasa.gov/software/Python/site-packages/Contrib/pxssh.html
Pexpect (pxssh основан на pexpect): http://www.noah.org/wiki/pexpect

Ответ 2

У Twisted есть поддержка SSH: http://www.devshed.com/c/a/Python/SSH-with-Twisted/

В пакете twisted.conch добавлена ​​поддержка SSH для Twisted. В этой главе показано, как вы можете использовать модули в twisted.conch для сборки серверов и клиентов SSH.

Настройка настраиваемого SSH-сервера

Командная строка - это невероятно эффективный интерфейс для определенных задач. Системным администраторам нравится управлять приложениями, введя команды без необходимости щелчка по графическому интерфейсу пользователя. Оболочка SSH еще лучше, так как она доступна из любого места в Интернете.

Вы можете использовать twisted.conch для создания SSH-сервера, который обеспечивает доступ к пользовательской оболочке с помощью команд, которые вы определяете. Эта оболочка будет поддерживать некоторые дополнительные функции, такие как история команд, чтобы вы могли прокручивать уже введенные команды.

Как мне это сделать? Напишите подкласс twisted.conch.recvline.HistoricRecvLine, который реализует ваш протокол оболочки. HistoricRecvLine похож на twisted.protocols.basic.LineReceiver, но с функциями более высокого уровня для управления терминалом.

Напишите подкласс twisted.conch.recvline.HistoricRecvLine, который реализует ваш протокол оболочки. HistoricRecvLine похож на twisted.protocols.basic.LineReceiver, но с функциями более высокого уровня для управления терминалом.

Чтобы сделать вашу оболочку доступной через SSH, вам нужно реализовать несколько разных классов, для которых twisted.conch необходимо построить SSH-сервер. Во-первых, вам нужны классы проверки подлинности twisted.cred: портал, учетные данные и область, возвращающая аватары. Используйте twisted.conch.avatar.ConchUser как базовый класс для вашего аватара. Ваш класс аватара также должен реализовать twisted.conch.interfaces.ISession, который включает метод openShell, в котором вы создаете протокол для управления интерактивным сеансом пользователей. Наконец, создайте объект twisted.conch.ssh.factory.SSHFactory и установите его атрибут портала в экземпляр вашего портала.

В примере 10-1 показан пользовательский SSH-сервер, который аутентифицирует пользователей по их имени и паролю. Он дает каждому пользователю оболочку, которая предоставляет несколько команд.

Пример 10-1. sshserver.py

from twisted.cred import portal, checkers, credentials
from twisted.conch import error, avatar, recvline, interfaces as conchinterfaces
from twisted.conch.ssh import factory, userauth, connection, keys, session, common from twisted.conch.insults import insults from twisted.application import service, internet
from zope.interface import implements
import os

class SSHDemoProtocol(recvline.HistoricRecvLine):
    def __init__(self, user):
        self.user = user

    def connectionMade(self) : 
     recvline.HistoricRecvLine.connectionMade(self)
        self.terminal.write("Welcome to my test SSH server.")
        self.terminal.nextLine() 
        self.do_help()
        self.showPrompt()

    def showPrompt(self): 
        self.terminal.write("$ ")

    def getCommandFunc(self, cmd):
        return getattr(self, ‘do_’ + cmd, None)

    def lineReceived(self, line):
        line = line.strip()
        if line: 
            cmdAndArgs = line.split()
            cmd = cmdAndArgs[0]
            args = cmdAndArgs[1:]
            func = self.getCommandFunc(cmd)
            if func: 
               try:
                   func(*args)
               except Exception, e: 
                   self.terminal.write("Error: %s" % e)
                   self.terminal.nextLine()
            else:
               self.terminal.write("No such command.")
               self.terminal.nextLine()
        self.showPrompt()

    def do_help(self, cmd="):
        "Get help on a command. Usage: help command"
        if cmd: 
            func = self.getCommandFunc(cmd)
            if func:
                self.terminal.write(func.__doc__)
                self.terminal.nextLine()
                return

        publicMethods = filter(
            lambda funcname: funcname.startswith(‘do_’), dir(self)) 
        commands = [cmd.replace(‘do_’, ", 1) for cmd in publicMethods] 
        self.terminal.write("Commands: " + " ".join(commands))
        self.terminal.nextLine()

    def do_echo(self, *args):
        "Echo a string. Usage: echo my line of text"
        self.terminal.write(" ".join(args)) 
        self.terminal.nextLine()

    def do_whoami(self):
        "Prints your user name. Usage: whoami"
        self.terminal.write(self.user.username)
        self.terminal.nextLine()

    def do_quit(self):
        "Ends your session. Usage: quit" 
        self.terminal.write("Thanks for playing!")
        self.terminal.nextLine() 
        self.terminal.loseConnection()

    def do_clear(self):
        "Clears the screen. Usage: clear" 
        self.terminal.reset()

class SSHDemoAvatar(avatar.ConchUser): 
    implements(conchinterfaces.ISession)

    def __init__(self, username): 
        avatar.ConchUser.__init__(self) 
        self.username = username 
        self.channelLookup.update({‘session’:session.SSHSession})

    def openShell(self, protocol): 
        serverProtocol = insults.ServerProtocol(SSHDemoProtocol, self)
        serverProtocol.makeConnection(protocol)
        protocol.makeConnection(session.wrapProtocol(serverProtocol))

    def getPty(self, terminal, windowSize, attrs):
        return None

    def execCommand(self, protocol, cmd): 
        raise NotImplementedError

    def closed(self):
        pass

class SSHDemoRealm:
    implements(portal.IRealm)

    def requestAvatar(self, avatarId, mind, *interfaces):
        if conchinterfaces.IConchUser in interfaces:
            return interfaces[0], SSHDemoAvatar(avatarId), lambda: None
        else:
            raise Exception, "No supported interfaces found."

def getRSAKeys():
    if not (os.path.exists(‘public.key’) and os.path.exists(‘private.key’)):
        # generate a RSA keypair
        print "Generating RSA keypair…" 
        from Crypto.PublicKey import RSA 
        KEY_LENGTH = 1024
        rsaKey = RSA.generate(KEY_LENGTH, common.entropy.get_bytes)
        publicKeyString = keys.makePublicKeyString(rsaKey) 
        privateKeyString = keys.makePrivateKeyString(rsaKey)
        # save keys for next time
        file(‘public.key’, ‘w+b’).write(publicKeyString)
        file(‘private.key’, ‘w+b’).write(privateKeyString)
        print "done."
    else:
        publicKeyString = file(‘public.key’).read()
        privateKeyString = file(‘private.key’).read() 
    return publicKeyString, privateKeyString

if __name__ == "__main__":
    sshFactory = factory.SSHFactory() 
    sshFactory.portal = portal.Portal(SSHDemoRealm())
    users = {‘admin’: ‘aaa’, ‘guest’: ‘bbb’}
    sshFactory.portal.registerChecker(
 checkers.InMemoryUsernamePasswordDatabaseDontUse(**users))

    pubKeyString, privKeyString =
getRSAKeys()
    sshFactory.publicKeys = {
        ‘ssh-rsa’: keys.getPublicKeyString(data=pubKeyString)}
    sshFactory.privateKeys = {
        ‘ssh-rsa’: keys.getPrivateKeyObject(data=privKeyString)}

    from twisted.internet import reactor 
    reactor.listenTCP(2222, sshFactory) 
    reactor.run()

{mospagebreak title=Setting Up a Custom SSH Server continued}

sshserver.py запустит SSH-сервер на порту 2222. Подключитесь к этому серверу с помощью SSH-клиента, используя имя пользователя admin и пароль aaa, и попробуйте ввести несколько команд:

$ ssh [email protected] -p 2222 
[email protected]’s password: aaa

>>> Welcome to my test SSH server.  
Commands: clear echo help quit whoami
$ whoami
admin
$ help echo
Echo a string. Usage: echo my line of text
$ echo hello SSH world!
hello SSH world!
$ quit

Connection to localhost closed.