写一个稍微冷门的东西,termux上ssh用代理连服务器

1,937 阅读2分钟

众所周知,ssh用代理连服务器的方式是使用ProxyCommand ,把流量通过代理软件去转发代理端口,从而连接目标机。而termux官方源提供的代理软件也就一个netcat,这个软件7.80及以下版本都是没毛病的,但目前升级后就出问题了,不仅socks5协议不支持,连socks4,http也是不支持。

由于socks5协议比较简单,我就单独测socks5的流量有没有问题了。它建立socks5连接的流量如下:

<Buffer 05 01 00> nc查询是否支持socks5
<Buffer 05 00> 代理响应支持
<Buffer 05 01 00 03 0b 31 39 32 2e 31 36 38 2e 31 2e 34 08 ac> nc告诉代理目标机ip和端口
<Buffer 05 00 00 01 00 00 00 00 00 00> 代理响应连接成功

然而之后就是固定报错: kex_exchange_identification: connection closed by remote host connection closed by unknown port 65535

这个报错是说链接建立失败,其实我这个代理工具用putty和mac上的nc都试过一直是可以用的,而且从流量看响应的数据也没毛病,而且另一个手机曾经装的老版nc也是可以连上的,所以就google了一把是不是nc版本的问题。

链接不贴了,当时看的时候没保存,但内容大致就是说他也是遇到nc升级7.91之后代理挂了,降回7.80就可以用了。

既然别人都确定了问题,那我也没必要再去细究,当前应该尝试termux降级nc版本。但google了以后发现termux官方并不支持降级操作:

www.reddit.com/r/termux/co…

兜了一大圈就给我看这?得了,自己搞一个ssh代理转发的轮子也没多少代码。。。

const [ , , proxy, host, port]=process.argv // 时间仓促,不做容错和提醒了
const net=require('net')
const [phost, pport]=proxy.split(':')
const pipe=net.createConnection(pport, phost)

async function getdata() {
  return new Promise(done=>{
    pipe.once('data', done)
  })
}

const b_open=Buffer.from([0x05, 0x01, 0x00]) // 请求建立socks5连接
const b_connect=Buffer.from([0x05, 0x01, 0x00, 0x03, 0x0b, ...(
  host.split('').map(a=>a.charCodeAt(0))
), port>>8, port&0xff]) // 统一用域名:端口方式请求

; (async _=>{
  process.stdin.pause() // 等socks5连上再转发ssh流量
  pipe.write(b_open) // 询问是否支持socks5
  await getdata() // 就当你支持
  pipe.write(b_connect) // 告诉代理需要连接的目标机host和port
  await getdata() // 就当你连上了
  pipe.on('data', c=>process.stdout.write(c)) // 绑定双向转发
  process.stdin.on('data', c=>pipe.write(c))
  process.stdin.resume() // 开始转发
})()

已发布npm www.npmjs.com/package/nc7…