我实现了一个Twisted SSH服务器来测试使用fabric通过SSH在远程计算机上运行命令的组件。我已经找到了这个例子,但我不明白如何实现execCommand方法才能与fabric兼容。下面是我的SSH服务器的实现:
from pathlib import Path
from twisted.conch import avatar, recvline
from twisted.conch.insults import insults
from twisted.conch.interfaces import ISession
from twisted.conch.ssh import factory, keys, session
from twisted.cred import checkers, portal
from twisted.internet import reactor
from zope.interface import implementer
SSH_KEYS_FOLDER = Path(__file__).parent.parent / "resources" / "ssh_keys"
@implementer(ISession)
class SSHDemoAvatar(avatar.ConchUser):
def __init__(self, username: str):
avatar.ConchUser.__init__(self)
self.username = username
self.channelLookup.update({b"session": session.SSHSession})
def openShell(self, protocol):
pass
def getPty(self, terminal, windowSize, attrs):
return None
def execCommand(self, protocol: session.SSHSessionProcessProtocol, cmd: bytes):
protocol.write("Some text to return")
protocol.session.conn.sendEOF(protocol.session)
def eofReceived(self):
pass
def closed(self):
pass
@implementer(portal.IRealm)
class SSHDemoRealm(object):
def requestAvatar(self, avatarId, _, *interfaces):
return interfaces[0], SSHDemoAvatar(avatarId), lambda: None
def getRSAKeys():
with open(SSH_KEYS_FOLDER / "ssh_key") as private_key_file:
private_key = keys.Key.fromString(data=private_key_file.read())
with open(SSH_KEYS_FOLDER / "ssh_key.pub") as public_key_file:
public_key = keys.Key.fromString(data=public_key_file.read())
return public_key, private_key
if __name__ == "__main__":
sshFactory = factory.SSHFactory()
sshFactory.portal = portal.Portal(SSHDemoRealm())
users = {
"admin": b"aaa",
"guest": b"bbb",
}
sshFactory.portal.registerChecker(checkers.InMemoryUsernamePasswordDatabaseDontUse(**users))
pubKey, privKey = getRSAKeys()
sshFactory.publicKeys = {b"ssh-rsa": pubKey}
sshFactory.privateKeys = {b"ssh-rsa": privKey}
reactor.listenTCP(22222, sshFactory)
reactor.run()试图通过fabric执行命令会产生以下输出:
[paramiko.transport ][INFO ] Connected (version 2.0, client Twisted_22.4.0)
[paramiko.transport ][INFO ] Authentication (password) successful!
Some text to return这看起来很有希望,但是程序执行挂在这一行之后。执行命令后,是否必须从服务器端关闭连接?我如何正确地实现这一点?
发布于 2022-07-02 07:37:09
在传统的UNIX服务器中,如果被告知执行命令,则服务器仍有责任关闭连接。这取决于服务器的自由裁量权,在哪里以及如何做到这一点。
我相信你只是想把protocol.session.conn.sendEOF(protocol.session)改成protocol.loseConnection()。我很抱歉没有亲自测试这一点以确定,设置一个环境来正确地测试像这样的全尺寸的海螺设置有点繁琐(而且这个例子并不是自我包含的,需要键生成和模块等等)。
https://stackoverflow.com/questions/72686561
复制相似问题