Go语言实现telnet远程登录

1、目前的linux服务器默认都未安装telnet服务,如需在linux服务器(如CentOS7)上安装telnet服务,可参考:

http://www.centoscn.com/image-text/install/2015/0101/4402.html

2、telnet-server默认监听的端口号为23

3、默认情况下,linux不允许root用户以telnet方式登录linux主机

使用Go语言模拟telnet客户端远程登录的代码如下:

package main

import (
	"fmt"
	"infrastructure/log"
	"net"
	"strconv"
	"strings"
	"time"
)

type TelnetClient struct {
	IP               string
	Port             string
	IsAuthentication bool
	UserName         string
	Password         string
}

const (
	//经过测试,linux下,延时需要大于100ms
	TIME_DELAY_AFTER_WRITE = 500 //500ms
)

func main() {
	telnetClientObj := new(TelnetClient)
	telnetClientObj.IP = "17.61.30.111"
	telnetClientObj.Port = "23"
	telnetClientObj.IsAuthentication = true
	telnetClientObj.UserName = "userOne"
	telnetClientObj.Password = "123456"
	//	fmt.Println(telnetClientObj.PortIsOpen(5))
	action := []string{"w_cd /", "r_1024", "w_ls", "r_1024"}
	telnetClientObj.Telnet(action, 20)
}

func (this *TelnetClient) PortIsOpen(timeout int) bool {
	raddr := this.IP + ":" + this.Port
	conn, err := net.DialTimeout("tcp", raddr, time.Duration(timeout)*time.Second)
	if nil != err {
		log.Error("pkg: model, func: PortIsOpen, method: net.DialTimeout, errInfo:", err)
		return false
	}
	defer conn.Close()
	return true
}

func (this *TelnetClient) Telnet(action []string, timeout int) (buf []byte, err error) {
	raddr := this.IP + ":" + this.Port
	conn, err := net.DialTimeout("tcp", raddr, time.Duration(timeout)*time.Second)
	if nil != err {
		log.Error("pkg: model, func: Telnet, method: net.DialTimeout, errInfo:", err)
		return
	}
	defer conn.Close()
	if false == this.telnetProtocolHandshake(conn) {
		log.Error("pkg: model, func: Telnet, method: this.telnetProtocolHandshake, errInfo: telnet protocol handshake failed!!!")
		return
	}
	//	conn.SetReadDeadline(time.Now().Add(time.Second * 30))
	for _, v := range action {
		actSlice := strings.SplitN(v, "_", 2)
		if 2 > len(actSlice) {
			log.Error("pkg: model, func: Telnet, method: strings.SplitN, errInfo: Invalid command\n", v)
			return
		}
		switch actSlice[0] {
		case "r":
			var n int
			n, err = strconv.Atoi(actSlice[1])
			if nil != err {
				log.Error("pkg: model, func: Telnet, method: strconv.Atoi, errInfo:", err)
				return
			}
			p := make([]byte, n)
			//	p := make([]byte, 0, n)
			n, err = conn.Read(p[0:])
			if nil != err {
				log.Error("pkg: model, func: Telnet, method: conn.Read, errInfo:", err)
				return
			}
			buf = append(buf, p[0:n]...)
			fmt.Println("read data length:", n)
			fmt.Println(string(p[0:n]) + "\n\n")
			//	fmt.Println(buf)
		case "w":
			_, err = conn.Write([]byte(actSlice[1] + "\n"))
			if nil != err {
				log.Error("pkg: model, func: Telnet, method: conn.Write, errInfo:", err)
				return
			}
			//	fmt.Println("wirte:", actSlice[1])
			time.Sleep(time.Millisecond * TIME_DELAY_AFTER_WRITE)
		}
	}
	return
}

func (this *TelnetClient) telnetProtocolHandshake(conn net.Conn) bool {
	var buf [4096]byte
	n, err := conn.Read(buf[0:])
	if nil != err {
		log.Error("pkg: model, func: telnetProtocolHandshake, method: conn.Read, errInfo:", err)
		return false
	}
	fmt.Println(string(buf[0:n]))
	fmt.Println((buf[0:n]))

	buf[1] = 252
	buf[4] = 252
	buf[7] = 252
	buf[10] = 252
	fmt.Println((buf[0:n]))
	n, err = conn.Write(buf[0:n])
	if nil != err {
		log.Error("pkg: model, func: telnetProtocolHandshake, method: conn.Write, errInfo:", err)
		return false
	}

	n, err = conn.Read(buf[0:])
	if nil != err {
		log.Error("pkg: model, func: telnetProtocolHandshake, method: conn.Read, errInfo:", err)
		return false
	}
	fmt.Println(string(buf[0:n]))
	fmt.Println((buf[0:n]))

	buf[1] = 252
	buf[4] = 251
	buf[7] = 252
	buf[10] = 254
	buf[13] = 252
	fmt.Println((buf[0:n]))
	n, err = conn.Write(buf[0:n])
	if nil != err {
		log.Error("pkg: model, func: telnetProtocolHandshake, method: conn.Write, errInfo:", err)
		return false
	}

	n, err = conn.Read(buf[0:])
	if nil != err {
		log.Error("pkg: model, func: telnetProtocolHandshake, method: conn.Read, errInfo:", err)
		return false
	}
	fmt.Println(string(buf[0:n]))
	fmt.Println((buf[0:n]))

	buf[1] = 252
	buf[4] = 252
	fmt.Println((buf[0:n]))
	n, err = conn.Write(buf[0:n])
	if nil != err {
		log.Error("pkg: model, func: telnetProtocolHandshake, method: conn.Write, errInfo:", err)
		return false
	}

	n, err = conn.Read(buf[0:])
	if nil != err {
		log.Error("pkg: model, func: telnetProtocolHandshake, method: conn.Read, errInfo:", err)
		return false
	}
	fmt.Println(string(buf[0:n]))
	fmt.Println((buf[0:n]))

	if false == this.IsAuthentication {
		return true
	}

	n, err = conn.Write([]byte(this.UserName + "\n"))
	if nil != err {
		log.Error("pkg: model, func: telnetProtocolHandshake, method: conn.Write, errInfo:", err)
		return false
	}
	time.Sleep(time.Millisecond * TIME_DELAY_AFTER_WRITE)

	n, err = conn.Read(buf[0:])
	if nil != err {
		log.Error("pkg: model, func: telnetProtocolHandshake, method: conn.Read, errInfo:", err)
		return false
	}
	fmt.Println(string(buf[0:n]))

	n, err = conn.Write([]byte(this.Password + "\n"))
	if nil != err {
		log.Error("pkg: model, func: telnetProtocolHandshake, method: conn.Write, errInfo:", err)
		return false
	}
	time.Sleep(time.Millisecond * TIME_DELAY_AFTER_WRITE)

	n, err = conn.Read(buf[0:])
	if nil != err {
		log.Error("pkg: model, func: telnetProtocolHandshake, method: conn.Read, errInfo:", err)
		return false
	}
	fmt.Println(string(buf[0:n]))
	return true
}

对于一些嵌入式设备上telnet-server,如果使用以上方法登录不成功,可考虑采用以下代码实现远程登录:

package main

import (
	"fmt"
	"infrastructure/log"
	"net"
	"strconv"
	"strings"
	"time"
)

type TelnetClient struct {
	IP               string
	Port             string
	IsAuthentication bool
	UserName         string
	Password         string
}

const (
	//经过测试,嵌入式设备下,延时大概需要大于300ms
	TIME_DELAY_AFTER_WRITE = 300 //300ms
)

func main() {
	telnetClientObj := new(TelnetClient)
	telnetClientObj.IP = "192.168.5.1"
	telnetClientObj.Port = "23"
	telnetClientObj.IsAuthentication = false
	//	telnetClientObj.UserName = "userOne"
	//	telnetClientObj.Password = "xhw888"
	//	fmt.Println(telnetClientObj.PortIsOpen(5))
	action := []string{"w_/ushell", "r_4096", "w_zte", "r_4096"}
	telnetClientObj.Telnet(action, 20)
}

func (this *TelnetClient) PortIsOpen(timeout int) bool {
	raddr := this.IP + ":" + this.Port
	conn, err := net.DialTimeout("tcp", raddr, time.Duration(timeout)*time.Second)
	if nil != err {
		log.Error("pkg: model, func: PortIsOpen, method: net.DialTimeout, errInfo:", err)
		return false
	}
	defer conn.Close()
	return true
}

func (this *TelnetClient) Telnet(action []string, timeout int) (buf []byte, err error) {
	raddr := this.IP + ":" + this.Port
	conn, err := net.DialTimeout("tcp", raddr, time.Duration(timeout)*time.Second)
	if nil != err {
		log.Error("pkg: model, func: Telnet, method: net.DialTimeout, errInfo:", err)
		return
	}
	defer conn.Close()
	if false == this.telnetProtocolHandshake(conn) {
		log.Error("pkg: model, func: Telnet, method: this.telnetProtocolHandshake, errInfo: telnet protocol handshake failed!!!")
		return
	}
	//	conn.SetReadDeadline(time.Now().Add(time.Second * 30))
	for _, v := range action {
		actSlice := strings.SplitN(v, "_", 2)
		if 2 > len(actSlice) {
			log.Error("pkg: model, func: Telnet, method: strings.SplitN, errInfo: Invalid command\n", v)
			return
		}
		switch actSlice[0] {
		case "r":
			var n int
			n, err = strconv.Atoi(actSlice[1])
			if nil != err {
				log.Error("pkg: model, func: Telnet, method: strconv.Atoi, errInfo:", err)
				return
			}
			p := make([]byte, n)
			//	p := make([]byte, 0, n)
			n, err = conn.Read(p[0:])
			if nil != err {
				log.Error("pkg: model, func: Telnet, method: conn.Read, errInfo:", err)
				return
			}
			buf = append(buf, p[0:n]...)
			fmt.Println("read data length:", n)
			fmt.Println(string(p[0:n]) + "\n\n")
			//	fmt.Println(buf)
		case "w":
			_, err = conn.Write([]byte(actSlice[1] + "\n"))
			if nil != err {
				log.Error("pkg: model, func: Telnet, method: conn.Write, errInfo:", err)
				return
			}
			fmt.Println("wirte:", actSlice[1])
			time.Sleep(time.Millisecond * TIME_DELAY_AFTER_WRITE)
		}
	}
	return
}

func (this *TelnetClient) telnetProtocolHandshake(conn net.Conn) bool {
	var buf [4096]byte
	n, err := conn.Read(buf[0:])
	if nil != err {
		log.Error("pkg: model, func: telnetProtocolHandshake, method: conn.Read, errInfo:", err)
		return false
	}
	fmt.Println(string(buf[0:n]))
	fmt.Println((buf[0:n]))

	buf[1] = 252
	buf[4] = 252
	buf[7] = 252
	buf[10] = 252
	fmt.Println((buf[0:n]))
	n, err = conn.Write(buf[0:n])
	if nil != err {
		log.Error("pkg: model, func: telnetProtocolHandshake, method: conn.Write, errInfo:", err)
		return false
	}
	time.Sleep(time.Millisecond * TIME_DELAY_AFTER_WRITE)

	n, err = conn.Read(buf[0:])
	if nil != err {
		log.Error("pkg: model, func: telnetProtocolHandshake, method: conn.Read, errInfo:", err)
		return false
	}
	fmt.Println(string(buf[0:n]))
	fmt.Println((buf[0:n]))

	buf[1] = 252
	buf[4] = 251
	buf[7] = 252
	buf[10] = 254
	buf[13] = 252
	fmt.Println((buf[0:n]))
	n, err = conn.Write(buf[0:n])
	if nil != err {
		log.Error("pkg: model, func: telnetProtocolHandshake, method: conn.Write, errInfo:", err)
		return false
	}
	time.Sleep(time.Millisecond * TIME_DELAY_AFTER_WRITE)

	n, err = conn.Read(buf[0:])
	if nil != err {
		log.Error("pkg: model, func: telnetProtocolHandshake, method: conn.Read, errInfo:", err)
		return false
	}
	fmt.Println(string(buf[0:n]))
	fmt.Println((buf[0:n]))

	if false == this.IsAuthentication {
		return true
	}

	n, err = conn.Write([]byte(this.UserName + "\n"))
	if nil != err {
		log.Error("pkg: model, func: telnetProtocolHandshake, method: conn.Write, errInfo:", err)
		return false
	}
	time.Sleep(time.Millisecond * TIME_DELAY_AFTER_WRITE)

	n, err = conn.Read(buf[0:])
	if nil != err {
		log.Error("pkg: model, func: telnetProtocolHandshake, method: conn.Read, errInfo:", err)
		return false
	}
	fmt.Println(string(buf[0:n]))

	n, err = conn.Write([]byte(this.Password + "\n"))
	if nil != err {
		log.Error("pkg: model, func: telnetProtocolHandshake, method: conn.Write, errInfo:", err)
		return false
	}
	time.Sleep(time.Millisecond * TIME_DELAY_AFTER_WRITE)

	n, err = conn.Read(buf[0:])
	if nil != err {
		log.Error("pkg: model, func: telnetProtocolHandshake, method: conn.Read, errInfo:", err)
		return false
	}
	fmt.Println(string(buf[0:n]))
	return true
}


  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值