具有转发SOAP请求的Node.js socks5代理

时间:2019-06-13 12:55:11

标签: node.js soap ssh socks ssh-tunnel

我正在尝试使用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)

关于缺少什么的任何想法?谢谢!

0 个答案:

没有答案