SSH is called Secure Shell, and is a network protocol used to securely remotely log in to other computers on the network. I believe that all students who do back-end development do not understand SSH. The more commonly used shell tools for logging into servers, such as Xshell, SecureCRT, iTerm2, etc., are implemented based on the SSH protocol. The crypto/ssh package in Golang provides the functions of implementing SSH clients. This article will explain in detail how to use Golang to implement SSH clients.
Create an SSH client configuration
First, you need to configure the parameters of the SSH client connecting to the server. The most basic configuration includes the user name, authentication method and host key callback. The sample code is as follows:
package main import "/x/crypto/ssh" func main() { config := &{ User: "username", Auth: []{ ("password"), }, HostKeyCallback: (), } }
In this configuration, the user name is set to "username" and the password is set to "password". Use the function to create a password authentication method. The HostKeyCallback function is called every time it connects to a new host to verify the server's host key. In this example, it means accepting any host key. This is not recommended in production environments because the host key does not verify, which poses a security risk.
Connect to an SSH server
Use the function to connect to a remote SSH server. Three parameters are required: network type (usually "tcp"), server address and port, and configuration objects created earlier. The sample code is as follows:
package main import ( "/x/crypto/ssh" "log" ) func main() { config := &{ User: "username", Auth: []{ ("password"), }, HostKeyCallback: (), } client, err := ("tcp", "192.168.3.111:22", config) if err != nil { ("Failed to dial: ", err) } }
Connect to port 22 (the default port of the SSH protocol) with an IP of 192.168.3.111. If the connection fails, an error will be returned. You can use Print an error and exit the program.
Create an SSH session
After establishing an SSH connection, an SSH session can be created and the server can be communicated through the session. The sample code is as follows:
package main import ( "/x/crypto/ssh" "log" ) func main() { config := &{ User: "username", Auth: []{ ("password"), }, HostKeyCallback: (), } client, err := ("tcp", "192.168.3.111:22", config) if err != nil { ("Failed to dial: ", err) } session, err := () if err != nil { ("Failed to create session: ", err) } defer () }
Use the method to create a new session, and if the creation fails, an error will be returned. Use the defer keyword to ensure that the session is closed after the operation is finished.
Create a pseudo-terminal
The SSH protocol can create a pseudo terminal. The pseudo terminal simulates a real terminal behavior and can run interactive commands such as shells or text editors. The sample code is as follows:
package main import ( "/x/crypto/ssh" "log" ) func main() { config := &{ User: "username", Auth: []{ ("password"), }, HostKeyCallback: (), } client, err := ("tcp", "192.168.3.111:22", config) if err != nil { ("Failed to dial: ", err) } session, err := () if err != nil { ("Failed to create session: ", err) } defer () modes := { : 0, // disable echoing ssh.TTY_OP_ISPEED: 14400, // input speed = 14.4kbaud ssh.TTY_OP_OSPEED: 14400, // output speed = 14.4kbaud } if err := ("linux", 80, 40, modes); err != nil { ("request for pseudo terminal failed: ", err) } }
Use method to request a pseudo-terminal, requiring four parameters: terminal type (using "xterm" here), terminal width and height, and a map that sets terminal mode. Set to 0 in this map, which will disable echo, and also set the input and output speed to 14.4 kbaud.
Set input and output
Specify the standard input and output of the remote shell, the sample code is as follows:
package main import ( "/x/crypto/ssh" "log" "os" ) func main() { config := &{ User: "username", Auth: []{ ("password"), }, HostKeyCallback: (), } client, err := ("tcp", "192.168.3.111:22", config) if err != nil { ("Failed to dial: ", err) } session, err := () if err != nil { ("Failed to create session: ", err) } defer () modes := { : 0, // disable echoing ssh.TTY_OP_ISPEED: 14400, // input speed = 14.4kbaud ssh.TTY_OP_OSPEED: 14400, // output speed = 14.4kbaud } if err := ("linux", 80, 40, modes); err != nil { ("request for pseudo terminal failed: ", err) } //Set input and output = = = }
Start a remote shell
A remote shell is ready to start a default shell using the method, or use the method to run a specified command. The sample code is as follows:
package main import ( "/x/crypto/ssh" "log" ) func main() { config := &{ User: "username", Auth: []{ ("password"), }, HostKeyCallback: (), } client, err := ("tcp", "192.168.3.111:22", config) if err != nil { ("Failed to dial: ", err) } session, err := () if err != nil { ("Failed to create session: ", err) } defer () modes := { : 0, // disable echoing ssh.TTY_OP_ISPEED: 14400, // input speed = 14.4kbaud ssh.TTY_OP_OSPEED: 14400, // output speed = 14.4kbaud } if err := ("linux", 80, 40, modes); err != nil { ("request for pseudo terminal failed: ", err) } //Set input and output = = = if err := (); err != nil { ("failed to start shell: ", err) } }
A default shell is started, and an error will be returned if it fails.
Wait for the end of the session
Use the method to block until the session ends. The sample code is as follows:
package main import ( "/x/crypto/ssh" "log" "os" ) func main() { config := &{ User: "username", Auth: []{ ("password"), }, HostKeyCallback: (), } client, err := ("tcp", "192.168.3.111:22", config) if err != nil { ("Failed to dial: ", err) } session, err := () if err != nil { ("Failed to create session: ", err) } defer () modes := { : 0, // disable echoing ssh.TTY_OP_ISPEED: 14400, // input speed = 14.4kbaud ssh.TTY_OP_OSPEED: 14400, // output speed = 14.4kbaud } if err := ("linux", 80, 40, modes); err != nil { ("request for pseudo terminal failed: ", err) } //Set input and output = = = if err := (); err != nil { ("failed to start shell: ", err) } err = () if err != nil { ("Failed to run: " + ()) } }
At this point, a basic SSH client implementation is completed. This client can connect to an SSH server and start a remote shell, then wait for the session to end.
summary
The SSH client implemented in this article only provides the most basic functions. To implement an SSH client with complete functions and good experience, you need to pay attention to a lot of detailed processing, such as error handling, reconnection, timeout, signal processing, etc.
The above is a detailed article about using Golang to implement SSH client. For more information about Go to implement SSH client, please follow my other related articles!