How to implement remote command execution using Go language
- 2020-05-30 20:23:41
- OfStack
preface
What is the use of remote command execution? Why execute commands remotely? If you only have 2 or 3 servers to manage, it really doesn't matter if you can execute commands remotely, you can log in to each server and do all kinds of things. When you have more than three servers, remote command execution can greatly increase your productivity.
If you have a tool that can execute commands remotely, you can operate multiple machines as if they were a single machine. The more machines you have, the more efficient you will be. The most common way to execute a command remotely is to use the SSH protocol to send the command to a remote machine for execution and get the result back.
1 a command
A "1" command is a command that will be executed within a certain time frame. grep, cat, etc. The steps to execute the command are: connect, execute, and get the result
The connection
The connection contains authentication, which can be done using either password or sshkey 2. The following example USES password authentication to complete the connection for simplicity.
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
}
The method of connection is simple, as long as the user *, * password *, * hostname or IP*, *SSH port is provided
Execute, command to get the result
Once the connection is successful, executing the command is simple
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")
}
After the above code runs, the command executes normally, but there is no normal output result, and there is no abnormal output result. To display the results, the Stdout and Stderr redirects of session need to modify func main as follows:
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")
}
So you can display normal, abnormal information on the screen.
Interactive command
The above method cannot execute interactive commands remotely, such as top, or edit a file remotely, such as
vi /etc/nginx/nginx.conf
To support interactive commands, you need the current terminal to take over the remote 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")
}
conclusion
Ok, so you can perform interactive commands, such as the above top through vi etc/nginx/nignx conf commands to remote editing files. That's all about how to use Go to implement remote commands. I hope this article will help you learn python.