diff --git a/README.md b/README.md index 08aed55..6b8c553 100644 --- a/README.md +++ b/README.md @@ -71,9 +71,22 @@ mac windows -- 暂不支持 +1.开启telnet功能 + +控制面板->程序和功能->打开或关闭Windows功能,选择Telnet服务端和Telnet客户端 + +2.启动telnet服务 + +控制面板->管理工具->服务->Telnet->启动类型改为自动并启动 + +3.登陆授权 + +控制面板->管理工具->本地安全策略,在本地安全策略中,安全设置->本地策略->安全选项->网络访问:本地帐户的共享和安全模型->经典 + +控制面板->管理工具->本地安全策略->安全设置->本地策略->安全选项->帐户:使用空密码的本地帐户只允许进行控制台登录->已禁用 + +控制面板->管理工具->计算机管理->系统工具->本地用户和组->组->TelnetClients->添加用户 -访问方式 ---- 前台访问:http://your_host:8080 用户名:admin 密码:123456 diff --git a/controllers/common.go b/controllers/common.go index 6a6869c..c36d94a 100644 --- a/controllers/common.go +++ b/controllers/common.go @@ -13,6 +13,7 @@ import ( "github.com/george518/PPGo_Job/models" "strconv" "strings" + "github.com/axgle/mahonia" ) const ( @@ -348,3 +349,11 @@ func serverLists(authStr string, adminId int) (sls []serverList) { } return sls } + +func gbkAsUtf8(str string) string { + srcDecoder := mahonia.NewDecoder("gbk") + desDecoder := mahonia.NewDecoder("utf-8") + resStr := srcDecoder.ConvertString(str) + _, resBytes, _ := desDecoder.Translate([]byte(resStr), true) + return string(resBytes) +} \ No newline at end of file diff --git a/controllers/server.go b/controllers/server.go index 82e4268..4ab8d33 100644 --- a/controllers/server.go +++ b/controllers/server.go @@ -2,8 +2,8 @@ ** @Description: controllers ** @Author: haodaquan ** @Date: 2018-06-09 16:11 -** @Last Modified by: haodaquan -** @Last Modified time: 2018-06-09 16:11 +** @Last Modified by: Bee +** @Last Modified time: 2019-02-17 22:15:15 *************************************************************/ package controllers @@ -16,6 +16,8 @@ import ( "strconv" "strings" "time" + "github.com/morganhein/go-telnet" + "github.com/pkg/errors" ) type ServerController struct { @@ -72,6 +74,7 @@ func (self *ServerController) GetServerByGroupId() { for k, v := range result { row := make(map[string]interface{}) row["id"] = v.Id + row["connection_type"] = v.ConnectionType row["server_name"] = v.ServerName row["detail"] = v.Detail if serverGroup[v.GroupId] == "" { @@ -94,6 +97,7 @@ func (self *ServerController) Edit() { server, _ := models.TaskServerGetById(id) row := make(map[string]interface{}) row["id"] = server.Id + row["connection_type"] = server.ConnectionType row["server_name"] = server.ServerName row["group_id"] = server.GroupId row["server_ip"] = server.ServerIp @@ -113,6 +117,7 @@ func (self *ServerController) Edit() { func (self *ServerController) AjaxTestServer() { server := new(models.TaskServer) + server.ConnectionType, _ = self.GetInt("connection_type") server.ServerName = strings.TrimSpace(self.GetString("server_name")) server.ServerAccount = strings.TrimSpace(self.GetString("server_account")) server.ServerOuterIp = strings.TrimSpace(self.GetString("server_outer_ip")) @@ -126,21 +131,83 @@ func (self *ServerController) AjaxTestServer() { server.GroupId, _ = self.GetInt("group_id") var err error - if server.Type == 0 { - //密码登录 - err = RemoteCommandByPassword(server) + + if server.ConnectionType == 0 { + if server.Type == 0 { + //密码登录 + err = RemoteCommandByPassword(server) + } + + if server.Type == 1 { + //密钥登录 + err = RemoteCommandByKey(server) + } + + if err != nil { + self.ajaxMsg(err.Error(), MSG_ERR) + } + self.ajaxMsg("Success", MSG_OK) + } else if server.ConnectionType == 1 { + if server.Type == 0 { + //密码登录 + err = RemoteCommandByTelnetPassword(server) + } else { + self.ajaxMsg("Telnet方式暂不支持密钥登陆!", MSG_ERR) + } + + if err != nil { + self.ajaxMsg(err.Error(), MSG_ERR) + } + self.ajaxMsg("Success", MSG_OK) } - if server.Type == 1 { - //密钥登录 - err = RemoteCommandByKey(server) - } + self.ajaxMsg("未知连接方式", MSG_ERR) +} + +func RemoteCommandByTelnetPassword(servers *models.TaskServer) error { + + addr := fmt.Sprintf("%s:%d", servers.ServerIp, servers.Port) + conn, err := gote.Dial("tcp", addr) + + defer conn.Close() if err != nil { - self.ajaxMsg(err.Error(), MSG_ERR) + return err } - self.ajaxMsg("Success", MSG_OK) + buf := make([]byte, 4096) + _, err = conn.Read(buf) + if err != nil { + return err + } + + _, err = conn.Write([]byte(servers.ServerAccount + "\r\n")) + if err != nil { + return err + } + + _, err = conn.Read(buf) + if err != nil { + return err + } + + _, err = conn.Write([]byte(servers.Password + "\r\n")) + if err != nil { + return err + } + + _, err = conn.Read(buf) + if err != nil { + return err + } + + str := gbkAsUtf8(string(buf[:])) + + if strings.Contains(str, ">") { + return nil + } + + return errors.Errorf("连接失败!") } func RemoteCommandByPassword(servers *models.TaskServer) error { @@ -208,6 +275,7 @@ func (self *ServerController) Copy() { server, _ := models.TaskServerGetById(id) row := make(map[string]interface{}) row["id"] = server.Id + row["connection_type"] = server.ConnectionType row["server_name"] = server.ServerName row["group_id"] = server.GroupId row["server_ip"] = server.ServerIp @@ -228,6 +296,7 @@ func (self *ServerController) AjaxSave() { server_id, _ := self.GetInt("id") if server_id == 0 { server := new(models.TaskServer) + server.ConnectionType, _ = self.GetInt("connection_type") server.ServerName = strings.TrimSpace(self.GetString("server_name")) server.ServerAccount = strings.TrimSpace(self.GetString("server_account")) server.ServerOuterIp = strings.TrimSpace(self.GetString("server_outer_ip")) @@ -256,6 +325,7 @@ func (self *ServerController) AjaxSave() { server.Id = server_id server.UpdateTime = time.Now().Unix() + server.ConnectionType, _ = self.GetInt("connection_type") server.ServerName = strings.TrimSpace(self.GetString("server_name")) server.ServerAccount = strings.TrimSpace(self.GetString("server_account")) server.ServerOuterIp = strings.TrimSpace(self.GetString("server_outer_ip")) @@ -310,6 +380,11 @@ func (self *ServerController) Table() { "密钥", } + connectionType := [2]string{ + "SSH", + "Telnet", + } + serverGroup := serverGroupLists(self.serverGroups, self.userId) self.pageSize = limit @@ -334,6 +409,7 @@ func (self *ServerController) Table() { for k, v := range result { row := make(map[string]interface{}) row["id"] = v.Id + row["connection_type"] = connectionType[v.ConnectionType] row["server_name"] = v.ServerName row["detail"] = v.Detail if serverGroup[v.GroupId] == "" { diff --git a/jobs/job.go b/jobs/job.go index b5d4ead..5b4be3b 100644 --- a/jobs/job.go +++ b/jobs/job.go @@ -1,8 +1,8 @@ /* * @Author: haodaquan * @Date: 2017-06-21 12:56:08 -* @Last Modified by: haodaquan -* @Last Modified time: 2017-06-21 13:05:57 +* @Last Modified by: Bee +* @Last Modified time: 2019-02-17 22:10:15 */ package jobs @@ -25,6 +25,9 @@ import ( "github.com/george518/PPGo_Job/notify" "golang.org/x/crypto/ssh" "encoding/json" + "github.com/axgle/mahonia" + "github.com/morganhein/go-telnet" + "github.com/pkg/errors" ) type Job struct { @@ -51,19 +54,30 @@ func NewJobFromTask(task *models.Task) (*Job, error) { } server, _ := models.TaskServerGetById(task.ServerId) - if server.Type == 0 { - //密码验证登录服务器 - job := RemoteCommandJobByPassword(task.Id, task.TaskName, task.Command, server) + if server.ConnectionType == 0 { + if server.Type == 0 { + //密码验证登录服务器 + job := RemoteCommandJobByPassword(task.Id, task.TaskName, task.Command, server) + job.task = task + job.Concurrent = task.Concurrent == 1 + return job, nil + } + + job := RemoteCommandJob(task.Id, task.TaskName, task.Command, server) job.task = task job.Concurrent = task.Concurrent == 1 return job, nil + } else if server.ConnectionType == 1 { + if server.Type == 0 { + //密码验证登录服务器 + job := RemoteCommandJobByTelnetPassword(task.Id, task.TaskName, task.Command, server) + job.task = task + job.Concurrent = task.Concurrent == 1 + return job, nil + } } - job := RemoteCommandJob(task.Id, task.TaskName, task.Command, server) - job.task = task - job.Concurrent = task.Concurrent == 1 - return job, nil - + return nil, fmt.Errorf("未知ConnectionType") } func NewCommandJob(id int, name string, command string) *Job { @@ -209,6 +223,77 @@ func RemoteCommandJobByPassword(id int, name string, command string, servers *mo return job } +func RemoteCommandJobByTelnetPassword(id int, name string, command string, servers *models.TaskServer) *Job { + + job := &Job{ + id: id, + name: name, + } + job.runFunc = func(timeout time.Duration) (string, string, error, bool) { + + addr := fmt.Sprintf("%s:%d", servers.ServerIp, servers.Port) + conn, err := gote.Dial("tcp", addr) + + defer conn.Close() + + if err != nil { + return "", "", err, false + } + + buf := make([]byte, 4096) + _, err = conn.Read(buf) + if err != nil { + return "", "", err, false + } + + _, err = conn.Write([]byte(servers.ServerAccount + "\r\n")) + if err != nil { + return "", "", err, false + } + + _, err = conn.Read(buf) + if err != nil { + return "", "", err, false + } + + _, err = conn.Write([]byte(servers.Password + "\r\n")) + if err != nil { + return "", "", err, false + } + + _, err = conn.Read(buf) + if err != nil { + return "", "", err, false + } + + loginStr := gbkAsUtf8(string(buf[:])) + if !strings.Contains(loginStr, ">") { + return "", "", errors.Errorf("Login failed!"), false + } + + commandArr := strings.Split(command, "\n") + + out := "" + for _, c := range commandArr { + _, err = conn.Write([]byte(c + "\r\n")) + if err != nil { + return "", "", err, false + } + + _, err = conn.Read(buf) + if err != nil { + return "", "", err, false + } + + out = out + gbkAsUtf8(string(buf[:])) + } + + return out, "", nil, false + } + + return job +} + func (j *Job) Status() int { return j.status } @@ -429,3 +514,11 @@ func AllAdminInfo(adminIds string) []*adminInfo { return adminInfos } + +func gbkAsUtf8(str string) string { + srcDecoder := mahonia.NewDecoder("gbk") + desDecoder := mahonia.NewDecoder("utf-8") + resStr := srcDecoder.ConvertString(str) + _, resBytes, _ := desDecoder.Translate([]byte(resStr), true) + return string(resBytes) +} diff --git a/models/server.go b/models/server.go index bf10b93..3e9ea47 100644 --- a/models/server.go +++ b/models/server.go @@ -16,6 +16,7 @@ import ( type TaskServer struct { Id int GroupId int + ConnectionType int ServerName string ServerAccount string ServerOuterIp string diff --git a/ppgo_job2.sql b/ppgo_job2.sql index 2761e96..35447b3 100644 --- a/ppgo_job2.sql +++ b/ppgo_job2.sql @@ -326,4 +326,8 @@ BEGIN; ALTER TABLE `pp_uc_admin` ADD `wechat` VARCHAR(64) NULL COMMENT '微信' AFTER `dingtalk`; COMMIT; +BEGIN; +ALTER TABLE `pp_task_server` ADD `connection_type` TINYINT(1) NOT NULL DEFAULT '0' COMMENT '连接类型 0:SSH;1:Telnet;' AFTER `group_id`; +COMMIT; + SET FOREIGN_KEY_CHECKS = 1; diff --git a/views/server/add.html b/views/server/add.html index 3bab3d4..be07f4e 100644 --- a/views/server/add.html +++ b/views/server/add.html @@ -17,6 +17,16 @@
+ +