2011-05-31 132 views
13

任何人都可以推薦一些在python中進行SSH連接嗎? 我需要它與任何操作系統兼容。如何使用python建立ssh連接?

我已經試過pyssh只是爲了得到與SIGCHLD,我讀過的錯誤是因爲Windows缺乏這個。 我試過讓paramiko工作,但我之間paramiko和加密之間的錯誤,其中每個最新版本不會在一起工作的地步。

Python 2.6.1目前在Windows機器上。

回答

29

模塊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文檔:http://dsnra.jpl.nasa.gov/software/Python/site-packages/Contrib/pxssh.html
Pexpect的(pxssh基於pexpect):http://www.noah.org/wiki/pexpect

+1

給出跨平臺要求的注意事項:「[pexpect]應該在任何支持標準Python pty模塊的平臺上工作。」 pty模塊平臺列表:linux。另外:「Pexpect目前不在標準Windows Python上工作(請參閱pty需求);但是,使用Cygwin似乎可以正常工作。」 – jtniehof 2011-05-31 15:28:21

+1

感謝您的回覆。我設法讓paramiko連接,但是我還沒有在多個平臺上進行測試。我一定會記住這些其他選項。 – Takkun 2011-05-31 15:56:50

+0

它在我看來像pxssh已被集成到pexpect在這裏找到:https://github.com/pexpect/pexpect – AlanObject 2015-06-12 20:59:12

3

扭曲了SSH支持:http://www.devshed.com/c/a/Python/SSH-with-Twisted/

的twisted.conch包添加SSH支持扭曲。本章介紹如何使用twisted.conch中的模塊構建SSH服務器和客戶端。

設置自定義SSH服務器

的命令行是對某些任務令人難以置信的高效的接口。系統管理員喜歡通過輸入命令來管理應用程序的功能,而無需點擊圖形用戶界面。 SSH shell甚至更好,因爲它可以從互聯網上的任何地方訪問。

您可以使用twisted.conch創建一個SSH服務器,該服務器使用您定義的命令提供對定製shell的訪問。這個shell甚至會支持一些額外的功能,比如命令歷史記錄,這樣你就可以滾動你已經輸入的命令。

我該怎麼做? 編寫一個twisted.conch.recvline.HistoricRecvLine的子類,實現您的shell協議。 HistoricRecvLine類似於twisted.protocols.basic.LineReceiver,但具有控制終端的更高級功能。

編寫twisted.conch.recvline.HistoricRecvLine的一個子類,實現您的shell協議。 HistoricRecvLine類似於twisted.protocols.basic.LineReceiver,但具有控制終端的更高級功能。

要使您的shell可以通過SSH獲得,您需要實現twisted.conch需要構建SSH服務器的幾個不同的類。首先,您需要twisted.cred認證類:門戶,憑證檢查器和返回頭像的領域。使用twisted.conch.avatar.ConchUser作爲頭像的基類。你的頭像類還應該實現twisted.conch.interfaces.ISession,其中包括一個openShell方法,在該方法中創建一個協議來管理用戶的交互式會話。最後,創建一個twisted.conch.ssh.factory.SSHFactory對象並將其門戶屬性設置爲您的門戶實例。

示例10-1演示了一個定製的SSH服務器,它通過用戶名和密碼對用戶進行身份驗證。它爲每個用戶提供一個提供多個命令的shell。

例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將在端口2222上運行SSH服務器。連接到該服務器使用的用戶名admin和密碼AAA SSH客戶端,並嘗試輸入一些命令:

$ 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.