steelbrain / node-ssh

SSH2 with Promises
MIT License
947 stars 94 forks source link

dispatch_protocol_error: type 90 seq 5 [preauth] #407

Closed ltinerary closed 3 years ago

ltinerary commented 3 years ago

I had a host A,the info of host A was:

here is host B‘s info:

Sometimes,we can conected host B through host A, But Sometimes we can't.

When failed, we have not received any information of failure through node-ssh, But,in host B,we found dispatch_protocol_error: type 90 seq 5 [preauth] error in ssh's log file.

we tried set up an SSH connection directly in host A by ssh user@hostB, Repeated attempts,this error didn't appear . So we wondered if it was the problem of the node-ssh? But we don't know for sure. So I opened this issue for help.

Thank s lot.

Here was the code for a major SSH service in HostA:


function initConnect(host,username,password){
   const ssh = new NodeSSH();
   ssh.connect({
     host,
     username,
     password,
     //tryKeyboard:true,
     //onKeyboardInteractive(name, instructions, instructionsLang, prompts, finish) {
    //console.log('prompts===>',prompts)
     //if (prompts.length > 0 && prompts[0].prompt.toLowerCase().includes('password')) {
      //finish([password])
   // }
 // }
   });
  const uid =  uuidv1(); //the identifier of the connection
  sshMap.set(uid,ssh);
  return uid
}
//init a ssh connect
app.post("/init/connect",(req,res)=>{
   const {host,user,password} = req.body;
   const uid = initConnect(host,user,password);
  console.log('uid===========>',uid)
   res.send({
   data:uid,
   status:10200,
  message:'success'
  })
 res.end();
});

app.ws("/exec/ssh/:uid",(ws,req)=>{
         const uid = req.params.uid;    //the uid was the identifier of the connection
        console.log('uid=====>',uid)
        const ssh = sshMap.get(uid);   // we use map to store different ssh connection
        console.log('is ssh connectSuccess?',ssh.isConnected());
        ws.on("message",(data)=>{
          console.log("command====>",data);//excute command like 'ls -al'
          ssh.execCommand(data,{
           cwd:'/home/',
           onChannel(clientChannel){
            console.log('clientChannel',clientChannel);
           },
           onStdout(chunk){
             console.log('stdout=================>',chunk.toString('utf8'))
                   ws.send(chunk.toString('utf8'))
           },
           onStderr(chunk){
                   console.log('stderr=====>',chunk.toString('utf8'))
            ws.send(chunk.toString('utf8'))
           }
          }).then(res=>{
            ws.send(`code:${res.code}`);
            ws.send(`signal:${res.signal}`)
           if(res.code === 0){
             ws.send('Command executed successful')
           }else{
            ws.send('Command executed fail')
           }
           // ws.send('Command executed')
          }).catch(e=>{
          ws.send(e.toString('utf-8'));
          ws.close();
          ssh.dispose();
          sshMap.delete(uid);
         console.log('delete uid====>',uid)
          })
        })

        ws.on('close',(e)=>{
          if(sshMap.has(uid)){
             ssh.dispose();
             sshMap.delete(uid);
             console.log('close delete uid====>',uid)
          }
          console.log('end webscoket connect')
        })
steelbrain commented 3 years ago

Hello! Thanks for the detailed post.

I think one misunderstanding here might be that isConnected means it is in fact connected, It's a misleading name and what it actually means is isConnectingOrConnected instead. I think you should try storing the connection promise somewhere and awaiting on it before trying to execute a command.

It's also entirely possible that my speculation is false, my knowledge in the underlying works of ssh2 is very limited. Please consult with the excellent mscdex over at https://github.com/mscdex/ssh2 for an indepth conversation

Thank you

ltinerary commented 3 years ago

Thanks very much!!!

I think one misunderstanding here might be that isConnected means it is in fact connected, It's a misleading name and what it actually means is isConnectingOrConnected instead. I think you should try storing the connection promise somewhere and awaiting on it before trying to execute a command.

you were right!

I always thought it was the SSH configuration and never realized I had a bug with my code.

Thank you for taking the time to reply!