我正在尝试在Twisted中编写SSH代理,它拦截SSH流量并将其转发到后端ssh服务器。
在前端我使用的是修改过的Conch,下面的代码子类为SSHSession:
def request_exec(self, data):
cmd,data = common.getNS(data)
log.msg('executing command "%s"' % cmd)
prot = session.SSHSessionClient()
prot.transport = self
pf = _ProtocolFactory(prot)
ep = endpoints.SSHCommandClientEndpoint.newConnection(reactor, cmd,
USER, HOST, port=PORT, password=PASSWORD)
ep.connect(pf)
self.client = prot
return 1
_ProtocolFactory类如下所示:
class _ProtocolFactory():
"""
Factory to return the (existing) ssh session to pass to ssh command endpoint
It does not actually function as a factory
"""
def __init__(self, protocol):
self.protocol = protocol
def buildProtocol(self, addr):
return self.protocol
整个事物接受来自用户的连接,我可以看到它成功登录到后端。
我遇到的问题是将stdout / stdin频道相互连接。 后端连接上的SSHSession需要连接到前端的SSHSession。我试图将协议作为中间人,但我不认为这是正确的。
更新:单向数据传输正在使用自定义协议来转换客户端/服务器函数(因此dataReceived映射到写入,反之亦然:
class InBetween(protocol.Protocol):
"""
This is the glue between the SSH server one one side and the
SSH client on the other side
"""
transport = None # Transport is the back-end the ssh-server
client = None # Client is the front-end, the ssh-client
buf = "" # buffer to send to back-end
def write(self, bytes):
# This is data going from the end-user to the back-end
if not self.transport:
self.buf += bytes
return
elif len(self.buf) and self.transport != None:
self.transport.dataReceived(self.buf)
self.buf = None
self.transport.dataReceived(bytes)
def dataReceived(self, data):
# This is data going from the back-end to the end-user
self.client.write(data)