一般命令
我们注重客户提出的每个要求,我们充分考虑每一个细节,我们积极的做好网站制作、做网站服务,我们努力开拓更好的视野,通过不懈的努力,成都创新互联公司赢得了业内的良好声誉,这一切,也不断的激励着我们更好的服务客户。 主要业务:网站建设,网站制作,网站设计,重庆小程序开发,网站开发,技术开发实力,DIV+CSS,PHP及ASP,ASP.Net,SQL数据库的技术开发工程师。
所谓一般命令,就是在一定时间内会执行完的命令。比如 grep, cat 等等。 执行命令的步骤是:连接,执行,获取结果
连接
连接包含了认证,可以使用 password 或者 sshkey 2种方式来认证。下面的示例为了简单,使用了密码认证的方式来完成连接。
import (
"fmt"
"time"
"golang.org/x/crypto/ssh"
)
func connect(user, password, host string, port int) (*ssh.Session, error) {
var (
auth []ssh.AuthMethod
addr string
clientConfig *ssh.ClientConfig
client *ssh.Client
session *ssh.Session
err error
)
// get auth method
auth = make([]ssh.AuthMethod, 0)
auth = append(auth, ssh.Password(password))
clientConfig = ssh.ClientConfig{
User: user,
Auth: auth,
Timeout: 30 * time.Second,
}
// connet to ssh
addr = fmt.Sprintf("%s:%d", host, port)
if client, err = ssh.Dial("tcp", addr, clientConfig); err != nil {
return nil, err
}
// create session
if session, err = client.NewSession(); err != nil {
return nil, err
}
return session, nil
}
连接的方法很简单,只要提供登录主机的 用户*, *密码*, *主机名或者IP*, *SSH端口
执行,命令获取结果
连接成功后,执行命令很简单
import (
"fmt"
"log"
"os"
"time"
"golang.org/x/crypto/ssh"
)
func main() {
session, err := connect("root", "xxxxx", "127.0.0.1", 22)
if err != nil {
log.Fatal(err)
}
defer session.Close()
session.Run("ls /; ls /abc")
}
上面代码运行之后,虽然命令正常执行了,但是没有正常输出的结果,也没有异常输出的结果。 要想显示结果,需要将 session 的 Stdout 和 Stderr 重定向 修改 func main 为如下:
func main() {
session, err := connect("root", "xxxxx", "127.0.0.1", 22)
if err != nil {
log.Fatal(err)
}
defer session.Close()
session.Stdout = os.Stdout
session.Stderr = os.Stderr
session.Run("ls /; ls /abc")
}
这样就能在屏幕上显示正常,异常的信息了。
交互式命令
上面的方式无法远程执行交互式命令,比如 top , 远程编辑一个文件,比如 vi /etc/nginx/nginx.conf 如果要支持交互式的命令,需要当前的terminal来接管远程的 PTY。
func main() {
session, err := connect("root", "olordjesus", "dockers.iotalabs.io", 2210)
if err != nil {
log.Fatal(err)
}
defer session.Close()
fd := int(os.Stdin.Fd())
oldState, err := terminal.MakeRaw(fd)
if err != nil {
panic(err)
}
defer terminal.Restore(fd, oldState)
// excute command
session.Stdout = os.Stdout
session.Stderr = os.Stderr
session.Stdin = os.Stdin
termWidth, termHeight, err := terminal.GetSize(fd)
if err != nil {
panic(err)
}
// Set up terminal modes
modes := ssh.TerminalModes{
ssh.ECHO: 1, // enable echoing
ssh.TTY_OP_ISPEED: 14400, // input speed = 14.4kbaud
ssh.TTY_OP_OSPEED: 14400, // output speed = 14.4kbaud
}
// Request pseudo terminal
if err := session.RequestPty("xterm-256color", termHeight, termWidth, modes); err != nil {
log.Fatal(err)
}
session.Run("top")
}
总结
好了,这样就可以执行交互式命令了,比如上面的 top 也可以通过 vi /etc/nginx/nignx.conf 之类的命令来远程编辑文件。
实际业务:go 二进制文件在私有化部署中,需要对客户的服务器mac和ip进行绑定,系统只能运行在绑定的服务器上。把mac和ip地址配置到config中。
运行效果:系统可正常编译,正常访问,在用户Auth接口进行核对。
//检验Mac和内网IP,测试环境不做校验
func (c *CommonBase)CheckMacAndIp()error {
ipCfg :=g.Cfg().GetString("machine.Ipaddr")
macCfg :=g.Cfg().GetString("machine.Macip")
if ipCfg =="127.0.0.1" {
return nil
}
macArray,_ :=gipv4.GetMacArray()
if len(macArray) ==0 {
return gerror.New("mac地址获取失败")
}
if garray.NewStrArrayFrom(macArray).Contains(macCfg) ==false {
return gerror.New("示授权的应用MAC,请联系")
}
ipArray,_ :=gipv4.GetIpArray()
ipIntranetArray,_ :=gipv4.GetIntranetIpArray()
if len(ipArray) ==0 len(ipIntranetArray) ==0 {
return gerror.New("ip地址获取失败")
}
if garray.NewStrArrayFrom(ipArray).Merge(ipIntranetArray).Contains(ipCfg) ==false {
return gerror.New("示授权的应用IP,请联系")
}
return nil
}
项目使用GoFrame框架1.6。考虑到客户可能会对内存数据做分析破解,可以把mac和ip地址做AES加密。
上一章节介绍了使用echo启动一个http服务器并提供一个简单的GET接口,这一章对请求与响应做一下详细的讲解。
了解请求与响应之前首先要知道ehco框架提供了一个Context接口,Context 表示当前 HTTP 请求的上下文,我们需要知道的是Context的实现结构体context,context中包含了请求(request)、响应(response)以及参数等结构体,context是一个内部结构体,但是对外提供了访问的方法,我们可以在开发中使用context提供的方法做很多事情,比如获取请求路径、客户端ip、请求参数等等。
request是包含了当前请求信息的结构体,我们从中可以获取到前后端约定好的参数来作出相应的业务逻辑,这下面开始模拟请求
首先模拟一个添加用户的POST请求,这里使用了c.bind()这个方法,这个方法起到的作用是把表单参数或者JSON参数绑定至对应的结构体(这里必须是指针类型),字段需要一一对应,也就是说前端需要传递的表单或JSON参数名为name、age、gender才能绑定到结构体中。
接下来模拟一个GET请求用来获取用户信息
response是包含了返回信息的结构体,echo提供了多种类型的返回结果
上面编写了处理请求的handler,这里介绍一下如何把handler注册到路由中,这里对应的就是上面handler。