我正在尝试使用node.js再现此ssh命令:ssh -D 1080 -N user@host -i key.pem
,以使用此隧道执行SOAP请求。
我的使用端口1080的SOAP API的node.js实现如下(并与ssh命令一起使用):
const
Agent = require('socks5-https-client/lib/Agent'),
request = require('request'),
soap = require('strong-soap').soap,
url = 'https://example.com/wsdl', //path to wsdl
options = {};
const req = request.defaults({
agentClass: Agent,
agentOptions: {
socksPort: 1080
}
})
options.request = req
const payload = {
field1: 'value1',
field2: 'value2',
fieldn: 'valuen'
}
soap.createClient(url, options, function (err, client) {
if (err) console.log(err)
let description = client.describe()
console.log(JSON.stringify(description.ExampleService.ExamplePort.example_method))
client.example_method(payload, function (err, result, envelope, soapHeader) {
if (err) console.log(err)
else console.log(JSON.stringify(result))
})
})
无论client.describe()
和client.example_method()
,一切都按预期工作。
尝试使用节点创建袜子代理时出现问题。下面的完整(经审查)代码:
const
Agent = require('socks5-https-client/lib/Agent'),
socks = require('socksv5'),
Client = require('ssh2').Client,
request = require('request'),
config = {
localProxy: {
host: '127.0.0.1',
port: 1080
},
sshConfig: {
host: 'hostIP',
port: 22,
username: 'user',
privateKey: require('fs').readFileSync('./key.pem')
}
},
soap = require('strong-soap').soap,
url = 'https://example.com/wsdl', //path to wsdl
options = {};
const req = request.defaults({
agentClass: Agent,
agentOptions: {
socksPort: 1080
}
})
options.request = req
const payload = {
field1: 'value1',
field2: 'value2',
fieldn: 'valuen'
}
let conn = new Client()
let server = socks.createServer(function (info, accept, deny) {
conn.on('ready', function () {
conn.forwardOut(info.srcAddr,
info.srcPort,
info.dstAddr,
info.dstPort,
function (err, stream) {
if (err) {
conn.end()
return deny()
}
let clientSocket
if (clientSocket = accept(true)) {
stream.pipe(clientSocket).pipe(stream).on('close', function () {
conn.end()
})
} else {
conn.end()
}
})
}).on('error', function (err) {
deny()
}).connect(config.sshConfig)
}).listen(config.localProxy.port, config.localProxy.host, function () {
console.log('SOCKSv5 proxy server started on ' + config.localProxy.host + ':' + config.localProxy.port)
soap.createClient(url, options, function (err, client) {
if (err) console.log(err)
let description = client.describe()
console.log(JSON.stringify(description.ExampleService.ExamplePort.example_method)) // works : print the json response
client.example_method(payload, function (err, result, envelope, soapHeader) {
if (err) console.log(err)
else console.log(JSON.stringify(result))
})
}) // get an error
}).useAuth(socks.auth.None())
方法example_method
的描述印刷得很好,所以我确信隧道工作正常(因为没有它,方法就无法工作,因为IP限制仅接受来自主机服务器的请求) 。调用client.example_method()时出现错误。
输出为:
Error: SOCKS connection failed. Connection not allowed by ruleset.
at Socket.<anonymous> (xxxxx/node_modules/socks5-client/lib/Socket.js:246:25)
at Object.onceWrapper (events.js:285:13)
at Socket.emit (events.js:197:13)
at addChunk (_stream_readable.js:288:12)
at readableAddChunk (_stream_readable.js:269:11)
at Socket.Readable.push (_stream_readable.js:224:10)
at TCP.onStreamRead (internal/stream_base_commons.js:145:17)
关于缺少什么的任何想法?谢谢!