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

原因:密码错误

相关推荐
1024奇点6 小时前
【仓颉语言入门 · 第二篇 第 22 课】
开发语言·ide·开源
Warren2Lynch7 小时前
C4 模型详解:利用 Visual Paradigm 可视化软件架构的综合指南
开发语言·uml
Knight_AL8 小时前
Java 文件下载时文件名中的 `#` 被转换成 `%23`?一次 URL 编码与解码问题排查
java·开发语言
利威尔xu8 小时前
Go IM 源码实战(14):本地缓存快 3000 倍,失效却难 10 倍
后端·缓存·微服务·面试·golang
FRing038 小时前
vue2干货总结2(v-bind、v-for、v-model、指令修饰符、v-bind操作class和style)
开发语言·前端·vue.js·vue2
by209999 小时前
C++ 智能指针的所有权与使用
开发语言·c++·经验分享
砚底藏山河9 小时前
python量化自定义周期 K 线合成
java·开发语言·数据库·python·金融
利威尔xu9 小时前
Go IM 源码实战(13):30 个会话只有 2 个红点,未读数错在三条路径
redis·后端·微服务·面试·golang
IT召唤狮9 小时前
开源企业级零信任项目Pangolin,零信任能挡住PHP核弹漏洞吗?
开发语言·开源·php
知已难寻9 小时前
03 · OpenStack的计算管理 Nova
运维·服务器·开发语言·云原生·云计算·openstack·开源软件