Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Execute ssh command inside a "for of" #1361

Closed
rfsilvagyn opened this issue Jan 26, 2024 · 7 comments
Closed

Execute ssh command inside a "for of" #1361

rfsilvagyn opened this issue Jan 26, 2024 · 7 comments

Comments

@rfsilvagyn
Copy link

rfsilvagyn commented Jan 26, 2024

I have an array where I have "hosts/nas" as main and "logins" as secondary, what I'm trying to do is go through the array connect to "host/nas" go through the "logins" array and for each "login" execute the command, but I have the error:

Client :: Ready
node:events:496
      throw er; // Unhandled 'error' event
      ^

Error: (SSH) Channel open failure: 
    at onChannelOpenFailure (/Users/raphael/Documents/Projeto Tiger/TigerServer/node_modules/ssh2/lib/utils.js:16:11)
    at CHANNEL_OPEN_FAILURE (/Users/raphael/Documents/Projeto Tiger/TigerServer/node_modules/ssh2/lib/client.js:572:11)
    at 92 (/Users/raphael/Documents/Projeto Tiger/TigerServer/node_modules/ssh2/lib/protocol/handlers.misc.js:881:16)
    at Protocol.onPayload (/Users/raphael/Documents/Projeto Tiger/TigerServer/node_modules/ssh2/lib/protocol/Protocol.js:2059:10)
    at GenericDecipherBinding.decrypt (/Users/raphael/Documents/Projeto Tiger/TigerServer/node_modules/ssh2/lib/protocol/crypto.js:1418:26)
    at Protocol.parsePacket [as _parse] (/Users/raphael/Documents/Projeto Tiger/TigerServer/node_modules/ssh2/lib/protocol/Protocol.js:2028:25)
    at Protocol.parse (/Users/raphael/Documents/Projeto Tiger/TigerServer/node_modules/ssh2/lib/protocol/Protocol.js:313:16)
    at Socket.<anonymous> (/Users/raphael/Documents/Projeto Tiger/TigerServer/node_modules/ssh2/lib/client.js:775:21)
    at Socket.emit (node:events:518:28)
    at addChunk (node:internal/streams/readable:559:12)
Emitted 'error' event on Client instance at:
    at Socket.<anonymous> (/Users/raphael/Documents/Projeto Tiger/TigerServer/node_modules/ssh2/lib/client.js:777:20)
    at Socket.emit (node:events:518:28)
    at addChunk (node:internal/streams/readable:559:12)
    at readableAddChunkPushByteMode (node:internal/streams/readable:510:3)
    at Readable.push (node:internal/streams/readable:390:5)
    at TCP.onStreamRead (node:internal/stream_base_commons:190:23) {
  reason: 4
}

Node.js v20.11.0

My function code:

const disconnectMultiUserSSH = async (value) => {
  try {
    for (const nas of value) {
      const dataNas = await prisma.nas.findUnique({
        where: { id: nas.NaId },
        select: {
          host: true,
          port_ssh: true,
          username: true,
          password: true,
          type: true,
        },
      })

      const bytes_password = CryptoJS.AES.decrypt(dataNas.password, process.env.SECRET_API)
      const decrypted_password = bytes_password.toString(CryptoJS.enc.Utf8)

      const conn = new Client()

      conn
        .on("ready", () => {
          console.log("Client :: Ready")

          for (const login of nas.logins) {
            conn.exec(`show subscriber session username ${login}`, (err, stream) => {
              if (err) throw err
              stream
                .on("close", (code, signal) => {
                  console.log("Stream :: close :: code: " + code + ", signal: " + signal)
                  conn.end()
                })
                .on("data", (data) => {
                  console.log("STDOUT: " + data)
                })
                .stderr.on("data", (data) => {
                  console.log("STDERR: " + data)
                })
            })
          }
        })
        .connect({
          host: dataNas.host,
          port: dataNas.port_ssh,
          username: dataNas.username,
          password: decrypted_password,
          algorithms: {
            kex: ["diffie-hellman-group1-sha1"],
          },
        })
    }
  } catch (error) {
    console.error(error)
  }
}
@mscdex
Copy link
Owner

mscdex commented Jan 26, 2024

Be aware that almost all SSH servers have limits on the number of concurrent "channels" you can have open per connection. Channels include things like .shell(), .exec(), local or remote connection forwards, X11 sessions, etc. This could be what you're running into. IIRC the default channel limit for OpenSSH is 10.

@rfsilvagyn
Copy link
Author

I need to access the equipment and disconnect users, how can I solve this?

@mscdex
Copy link
Owner

mscdex commented Jan 26, 2024

Perhaps only perform one .exec() at a time using whichever means you wish.

@rfsilvagyn
Copy link
Author

If I repeat the command manually, for example 3 times, it does not show the error.

but inside the "for" it may be 1 time that it presents the error.

I wanted to solve the "for" problem so that I could later solve the ssh limit.

@theophilusx
Copy link

theophilusx commented Jan 26, 2024 via email

@rfsilvagyn
Copy link
Author

I'm thinking about dividing it into blocks of 5 and configuring the Cisco router parameters to work like this.

However, my main problem is that when adding the connection command ".on("ready", () => {" inside the first "for" and the execution command "conn.exec" inside the second "for" already displays the error.

I believe it is not an error with the limitations of ssh, so I need help at the moment.

command structure:

  • first "for"
    -- data/connection
    --- second "for"
    ---- data/command

@mscdex
Copy link
Owner

mscdex commented Jan 27, 2024

@rfsilvagyn Without seeing the new code that you're attempting to use, it's difficult to make a suggestion.

If you want to keep your for loop, you're better off writing a helper function that returns a Promise that gets resolved when the command finishes. That way you can just await the helper function calls inside your loop. This will also ensure there is only one command executing at a time.

@mscdex mscdex closed this as completed Sep 16, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants