go客户端ssh交换机

连接交换机代码

使用库golang.org/x/crypto/ssh

go 复制代码
func (s *SwitchConf) switchNewSession() error {
	config := &ssh.ClientConfig{
		User: s.User,
		Auth: []ssh.AuthMethod{
			ssh.Password(s.Password),
		},
		HostKeyCallback: ssh.InsecureIgnoreHostKey(),
		Timeout:         30 * time.Second, 
		Config: ssh.Config{			
			Ciphers: []string{"aes128-ctr", "aes192-ctr", "aes256-ctr", "aes128-gcm@openssh.com", "aes256-gcm@openssh.com", "chacha20-poly1305@openssh.com"},
		}, 
	}

	address := fmt.Sprintf("%s:22", s.Ip)

	client, err := ssh.Dial("tcp", address, config)
	if err != nil {
		log.Fatalf("Failed to dial: %v", err)
		return nil
	}
	go s.waitConnectClosed(client)

	session, err := client.NewSession()
	if err != nil {
		fmt.Println("Failed to create session:", err)
		return nil
	}

	s.Session = session
	modes := ssh.TerminalModes{
		ssh.ECHO:          0,     // disable echoing
		ssh.TTY_OP_ISPEED: 14400, // input speed = 14.4kbaud
		ssh.TTY_OP_OSPEED: 14400, // output speed = 14.4kbaud
	}

	err := s.Session.RequestPty("xterm", 80, 80, modes)
	if err != nil {
		fmt.Println("创建requestpty出错", err)
		return err
	}

	// 使用 io.MultiWriter 同时写入 os.Stdout 和缓冲区
	//multiWriter := io.MultiWriter(os.Stdout, &buf)
	s.input, err = s.Session.StdinPipe()
	if err != nil {
		fmt.Println("StdinPipe错误: ", err)
		return err

	}

	s.output, err = s.Session.StdoutPipe()
	if err != nil {
		fmt.Println("StdoutPipe: ", err)
		return err
	}
	s.errput, err = s.Session.StderrPipe()
	if err != nil {
		fmt.Println("StderrPipe: ", err)
		return err
	}

	err = s.Session.Shell()
	if err != nil {
		fmt.Println("创建shell出错: ", err)
		return err
	}

	go s.getErrorRealTime()
	return nil
}

执行命令

// 如果不判断什么时候结束,结束后就会一直卡在output.Read

go 复制代码
func (s *DeviceConf) getOutputRealTime(expect string, unExpect string) {
	lenBuf := 128 * 1024
	var n int

	s.outBuf = make([]byte, lenBuf)
	s.bufLen = 0

	for {
		if s.output == nil {
			return
		}
		lenr, err := s.output.Read(s.outBuf[n:])
		if err != nil {
			log.Errorf("read err: %s", err)
			s.bufLen = n - 1
			return
		}
		if lenr == 0 {
			log.Errorf("read len 0")
			s.bufLen = n - 1
			return
		}
		if strings.Contains(string(s.outBuf[n:n+lenr-1]), expect) || strings.Contains(string(s.outBuf[n:n+lenr-1]), unExpect) {			
			s.bufLen = n + lenr - 1
			return
		}

		n += lenr
		//留1024给下次读取
		if n >= lenBuf+1024 {
			log.Errorf("BUFF is too short")
			s.bufLen = n - 1
			return
		}
	}
}
func (s *DeviceConf) runCmd(cmd string, expectSub string, unExpect string) string {
	if s.Session == nil {
		err := s.switchNewSession()
		if err != nil {
			log.Errorf("switchNewSession error: %s", err)
			return ""
		}
		err = s.getShell()
		if err != nil {
			log.Errorf("getShell error: %s", err)
			return ""
		}
	}

	go s.getOutputRealTime(expectSub, unExpect)
	go s.getErrorRealTime()

	_, err := s.input.Write(nputil.Str2bytes("\n " + cmd + "\n"))
	if err != nil {
		log.Errorf("写入stdin出错111: %s", err)
		return ""
	}

	timeoutChan := time.After(defaultTimeout)
	for {
		select {
		case <-timeoutChan:
			log.Errorf("超时了,退出循环: %s", time.Now())
			return ""
		default:
			if s.bufLen != 0 {
				out := s.outBuf[:s.bufLen]
				s.bufLen = 0
				log.Errorf("default return: %s", time.Now())
				return string(out)
			}
		}
	}

}

问题

提示unable to authenticate, attempted methods none password, no supported methods remain

原因:密码错误

相关推荐
apocelipes20 小时前
常用编程语言和库的正则表达式性能对比
c语言·c++·python·性能优化·golang·开发工具和环境
Web3探索者9 天前
可视化服务器管理和传统命令行区别是什么?新手教程:Linux 运维到底该用图形界面还是 SSH 命令行?
linux·ssh
LDR00616 天前
Type-C 快充全面升级!LDR6601 赋能个人护理便携电机,重塑剃须刀 / 理发器新体验
c语言·开发语言
雪碧聊技术16 天前
Tree.js是什么?一文讲透
开发语言·javascript·ecmascript
码云数智-园园16 天前
C++20 Modules 模块详解
java·开发语言·spring
开发者联盟league16 天前
安装pnpm
ssh
swordbob16 天前
NIO的channel中什么是 fd(File Descriptor,文件描述符)
java·开发语言·nio
源分享16 天前
Java线程同步的多种实现方法(非常详细)
java·开发语言·jvm
Luminous.16 天前
C语言--day30
c语言·开发语言
何以解忧,唯有..16 天前
Go语言循环语句详解:for、range与循环控制
开发语言·算法·golang