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

原因:密码错误

相关推荐
小羊没烦恼!1 天前
初探性能优化——2个月到4小时的性能提升
java·开发语言·windows·算法·c#
伞伞悦读1 天前
【第38期】Python 模块与包详解:import、from、模块搜索路径、包结构和 __init__
开发语言·python
ttwuai1 天前
Go开源后台管理系统推荐:怎么按技术栈和边界比较4个官方仓库?
golang·gin
C语言小火车1 天前
C/C++ 为什么需要编译器?
开发语言·c++
codeejun1 天前
每日一Go·MySQL-5、锁机制全解析
云原生·golang
霍霍的袁2 天前
【C++】map 和 set 的使用 | 从用法到底层
开发语言·c++·学习·visual studio
孙启超2 天前
【AI开发之Rust】第 11 课:智能指针与内部可变性
开发语言·后端·rust
此生决int2 天前
深入理解C++系列(20)——C++11(下)
开发语言·c++
Achou.Wang2 天前
k8s中nginx worker process自动设置
后端·golang
CoderYanger2 天前
A.每日一题:835. 图像重叠
java·开发语言·程序人生·leetcode·面试·职场和发展·学习方法