ssh2-HTTPAgent源码阅读
ssh2包中提供了HTTPAgent,使用该HTTP Agent是可以接管请求,底层再通过SSH建立的与目标机器连接,从而实现内网穿透。
最近需要开发自定义的HTTP Agent,因此这里研究下实现。
整个HTTPAgent实现是在项目下的lib/http-agents.js
1 | const { Agent: HttpAgent } = require('http'); |
这里可以看到for循环将nodejs下的Agent进行改造并重新导出。
nodejs下的Agent构造函数如下
1 | new Agent([options]) |
这里因为底层还需要SSH的配置,因此构造函数就是2个参数
1 | constructor(connectCfg, agentOptions) { |
第一个参数connectCfg即SSH连接需要的参数,第二个是丢给了nodejs下的Agent,因此具体配置直接查看nodejs文档即可,ssh2这里主要是丢给了父类即Agent.
agentOptions中的srcIP在nodejs下是没有的,这个参数是ssh2这里增加的,主要用于底层TCP连接。
createConnection(options, cb)
是Agent根据连接池策略动态创建。这里主要就是将TCP连接socket以回调形式返回为第二个参数cb。
这里是new了一个SSH的client,根据connectCfg建立连接,ready后,执行forwardOut,然后得到了TCP连接的socket,在cb(null, decorateStream(stream, ctor, options)); 这里的stream即socket。
之所以还走decorateStream,我理解是socket转为HTTP Agent需要的socket还需要一些属性方法,因此走空方法赋值。
针对异常部分的处理。
- 如果tcp连接通讯中出现了异常,cb的第一个参数即error返回,同时会主动断掉ssh的client连接
- 如果tcp连接关闭了,则主动断掉ssh的client连接,此时不用cb返回error.
tcp本地起服务是需要占用端口的,这里即localPort,如果没有明确指定则都0,但0不代表最终端口是0而是系统找寻空置的端口。
1 | const srcPort = (options && options.localPort) || 0; |