欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

一文帶你使用Golang實(shí)現(xiàn)SSH客戶端

 更新時(shí)間:2023年11月09日 09:32:52   作者:路多辛  
SSH?全稱為?Secure?Shell,是一種用于安全地遠(yuǎn)程登錄到網(wǎng)絡(luò)上的其他計(jì)算機(jī)的網(wǎng)絡(luò)協(xié)議,本文主要為大家詳細(xì)介紹了如何使用?Golang?實(shí)現(xiàn)?SSH?客戶端,需要的可以參考下

SSH 全稱為 Secure Shell,是一種用于安全地遠(yuǎn)程登錄到網(wǎng)絡(luò)上的其他計(jì)算機(jī)的網(wǎng)絡(luò)協(xié)議。相信做后端開(kāi)發(fā)的同學(xué)沒(méi)有不了解 SSH的,比較常用的登錄服務(wù)器的 shell 工具例如 Xshell、SecureCRT、iTerm2 等都是基于 SSH 協(xié)議實(shí)現(xiàn)的。Golang 中的的 crypto/ssh 包提供了實(shí)現(xiàn) SSH 客戶端的功能,本文接下來(lái)詳細(xì)講解下如何使用 Golang 實(shí)現(xiàn) SSH 客戶端。

創(chuàng)建 SSH 客戶端配置

首先需要配置一下 SSH 客戶端連接服務(wù)器的參數(shù),最基本的配置包括用戶名、認(rèn)證方法和主機(jī)密鑰回調(diào)。示例代碼如下:

package main
 
import "golang.org/x/crypto/ssh"
 
func main() {
    config := &ssh.ClientConfig{
        User: "username",
        Auth: []ssh.AuthMethod{
            ssh.Password("password"),
        },
        HostKeyCallback: ssh.InsecureIgnoreHostKey(),
    }
}

在這個(gè)配置中,設(shè)置了用戶名為"username",密碼為"password"。使用 ssh.Password 函數(shù)來(lái)創(chuàng)建一個(gè)密碼認(rèn)證方法。HostKeyCallback 函數(shù)會(huì)在每次連接到一個(gè)新的主機(jī)時(shí)被調(diào)用,用于驗(yàn)證服務(wù)器的主機(jī)密鑰。本例中使用了 ssh.InsecureIgnoreHostKey,意思是接受任何主機(jī)密鑰。生產(chǎn)環(huán)境中不建議這么用,因?yàn)椴或?yàn)證主機(jī)密鑰,存在安全風(fēng)險(xiǎn)。

連接到 SSH 服務(wù)器

使用 ssh.Dial 函數(shù)可以連接到遠(yuǎn)程的 SSH 服務(wù)器。需要三個(gè)參數(shù):網(wǎng)絡(luò)類型(通常是"tcp"),服務(wù)器的地址和端口,以及之前創(chuàng)建的配置對(duì)象。示例代碼如下:

package main
 
import (
    "golang.org/x/crypto/ssh"
    "log"
)
 
func main() {
    config := &ssh.ClientConfig{
        User: "username",
        Auth: []ssh.AuthMethod{
            ssh.Password("password"),
        },
        HostKeyCallback: ssh.InsecureIgnoreHostKey(),
    }
 
    client, err := ssh.Dial("tcp", "192.168.3.111:22", config)
    if err != nil {
        log.Fatal("Failed to dial: ", err)
    }
}

連接到 IP 為192.168.3.111服務(wù)器的22端口(SSH協(xié)議的默認(rèn)端口),如果連接失敗,將返回一個(gè)錯(cuò)誤,可以使用 log.Fatal 打印錯(cuò)誤并退出程序。

創(chuàng)建 SSH 會(huì)話

建立了 SSH 連接后就可以創(chuàng)建 SSH 會(huì)話了,可以通過(guò)會(huì)話與服務(wù)器進(jìn)行通信。示例代碼如下:

package main
 
import (
    "golang.org/x/crypto/ssh"
    "log"
)
 
func main() {
    config := &ssh.ClientConfig{
        User: "username",
        Auth: []ssh.AuthMethod{
            ssh.Password("password"),
        },
        HostKeyCallback: ssh.InsecureIgnoreHostKey(),
    }
 
    client, err := ssh.Dial("tcp", "192.168.3.111:22", config)
    if err != nil {
        log.Fatal("Failed to dial: ", err)
    }
 
    session, err := client.NewSession()
    if err != nil {
        log.Fatal("Failed to create session: ", err)
    }
    defer session.Close()
}

使用 client.NewSession 方法創(chuàng)建一個(gè)新的會(huì)話,如果創(chuàng)建失敗,將返回一個(gè)錯(cuò)誤。使用 defer 關(guān)鍵字來(lái)確保會(huì)話在操作結(jié)束后被關(guān)閉。

創(chuàng)建偽終端

SSH 協(xié)議可以創(chuàng)建偽終端(pseudo terminal),偽終端模擬了一個(gè)真實(shí)的終端行為,可以運(yùn)行交互式命令,如 shell 或文本編輯器等。示例代碼如下:

package main
 
import (
    "golang.org/x/crypto/ssh"
    "log"
)
 
func main() {
    config := &ssh.ClientConfig{
        User: "username",
        Auth: []ssh.AuthMethod{
            ssh.Password("password"),
        },
        HostKeyCallback: ssh.InsecureIgnoreHostKey(),
    }
 
    client, err := ssh.Dial("tcp", "192.168.3.111:22", config)
    if err != nil {
        log.Fatal("Failed to dial: ", err)
    }
 
    session, err := client.NewSession()
    if err != nil {
        log.Fatal("Failed to create session: ", err)
    }
    defer session.Close()
 
    modes := ssh.TerminalModes{
        ssh.ECHO:          0,     // disable echoing
        ssh.TTY_OP_ISPEED: 14400, // input speed = 14.4kbaud
        ssh.TTY_OP_OSPEED: 14400, // output speed = 14.4kbaud
    }
    if err := session.RequestPty("linux", 80, 40, modes); err != nil {
        log.Fatal("request for pseudo terminal failed: ", err)
    }
}

使用 session.RequestPty 方法請(qǐng)求一個(gè)偽終端,需要四個(gè)參數(shù):終端類型(這里使用"xterm"),終端的寬度和高度,以及一個(gè)設(shè)置終端模式的 map。在這個(gè) map 中設(shè)置了 ssh.ECHO 為0,這將禁止回顯,還設(shè)置了輸入和輸出的速度為14.4 kbaud。

設(shè)置輸入輸出

指定遠(yuǎn)程 shell 的標(biāo)準(zhǔn)輸入和輸出,示例代碼如下:

package main
 
import (
    "golang.org/x/crypto/ssh"
    "log"
    "os"
)
 
func main() {
    config := &ssh.ClientConfig{
        User: "username",
        Auth: []ssh.AuthMethod{
            ssh.Password("password"),
        },
        HostKeyCallback: ssh.InsecureIgnoreHostKey(),
    }
 
    client, err := ssh.Dial("tcp", "192.168.3.111:22", config)
    if err != nil {
        log.Fatal("Failed to dial: ", err)
    }
 
    session, err := client.NewSession()
    if err != nil {
        log.Fatal("Failed to create session: ", err)
    }
    defer session.Close()
 
    modes := ssh.TerminalModes{
        ssh.ECHO:          0,     // disable echoing
        ssh.TTY_OP_ISPEED: 14400, // input speed = 14.4kbaud
        ssh.TTY_OP_OSPEED: 14400, // output speed = 14.4kbaud
    }
    if err := session.RequestPty("linux", 80, 40, modes); err != nil {
        log.Fatal("request for pseudo terminal failed: ", err)
    }
 
    //設(shè)置輸入輸出
    session.Stdout = os.Stdout
    session.Stdin = os.Stdin
    session.Stderr = os.Stderr
}

啟動(dòng)遠(yuǎn)程 shell

一個(gè)遠(yuǎn)程 shell 已經(jīng)準(zhǔn)備就緒了,可以使用 session.Shell 方法啟動(dòng)一個(gè)默認(rèn)的 shell,或者使用 session.Run 方法來(lái)運(yùn)行一個(gè)指定的命令。示例代碼如下:

package main
 
import (
    "golang.org/x/crypto/ssh"
    "log"
)
 
func main() {
    config := &ssh.ClientConfig{
        User: "username",
        Auth: []ssh.AuthMethod{
            ssh.Password("password"),
        },
        HostKeyCallback: ssh.InsecureIgnoreHostKey(),
    }
 
    client, err := ssh.Dial("tcp", "192.168.3.111:22", config)
    if err != nil {
        log.Fatal("Failed to dial: ", err)
    }
 
    session, err := client.NewSession()
    if err != nil {
        log.Fatal("Failed to create session: ", err)
    }
    defer session.Close()
 
    modes := ssh.TerminalModes{
        ssh.ECHO:          0,     // disable echoing
        ssh.TTY_OP_ISPEED: 14400, // input speed = 14.4kbaud
        ssh.TTY_OP_OSPEED: 14400, // output speed = 14.4kbaud
    }
    if err := session.RequestPty("linux", 80, 40, modes); err != nil {
        log.Fatal("request for pseudo terminal failed: ", err)
    }
  
  //設(shè)置輸入輸出
    session.Stdout = os.Stdout
    session.Stdin = os.Stdin
    session.Stderr = os.Stderr
 
    if err := session.Shell(); err != nil {
        log.Fatal("failed to start shell: ", err)
    }
}

啟動(dòng)了一個(gè)默認(rèn)的 shell,如果啟動(dòng)失敗,將返回一個(gè)錯(cuò)誤。

等待會(huì)話結(jié)束

使用 session.Wait 方法來(lái)阻塞,直到會(huì)話結(jié)束。示例代碼如下:

package main
 
import (
    "golang.org/x/crypto/ssh"
    "log"
    "os"
)
 
func main() {
    config := &ssh.ClientConfig{
        User: "username",
        Auth: []ssh.AuthMethod{
            ssh.Password("password"),
        },
        HostKeyCallback: ssh.InsecureIgnoreHostKey(),
    }
 
    client, err := ssh.Dial("tcp", "192.168.3.111:22", config)
    if err != nil {
        log.Fatal("Failed to dial: ", err)
    }
 
    session, err := client.NewSession()
    if err != nil {
        log.Fatal("Failed to create session: ", err)
    }
    defer session.Close()
 
    modes := ssh.TerminalModes{
        ssh.ECHO:          0,     // disable echoing
        ssh.TTY_OP_ISPEED: 14400, // input speed = 14.4kbaud
        ssh.TTY_OP_OSPEED: 14400, // output speed = 14.4kbaud
    }
    if err := session.RequestPty("linux", 80, 40, modes); err != nil {
        log.Fatal("request for pseudo terminal failed: ", err)
    }
 
    //設(shè)置輸入輸出
    session.Stdout = os.Stdout
    session.Stdin = os.Stdin
    session.Stderr = os.Stderr
 
    if err := session.Shell(); err != nil {
        log.Fatal("failed to start shell: ", err)
    }
 
    err = session.Wait()
    if err != nil {
        log.Fatal("Failed to run: " + err.Error())
    }
}

到這里,就完成了一個(gè)基本的 SSH 客戶端的實(shí)現(xiàn)了。這個(gè)客戶端可以連接到一個(gè) SSH 服務(wù)器并啟動(dòng)一個(gè)遠(yuǎn)程 shell,然后等待會(huì)話結(jié)束。

小結(jié)

本文實(shí)現(xiàn)的 SSH 客戶端只是提供了最基本的功能,要實(shí)現(xiàn)一個(gè)功能完備、體驗(yàn)良好的 SSH 客戶端需要注意很多的細(xì)節(jié)處理,例如錯(cuò)誤處理、重新連接、超時(shí)、信號(hào)處理等。

以上就是一文帶你使用Golang實(shí)現(xiàn)SSH客戶端的詳細(xì)內(nèi)容,更多關(guān)于Go實(shí)現(xiàn)SSH客戶端的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Go語(yǔ)言數(shù)據(jù)類型詳細(xì)介紹

    Go語(yǔ)言數(shù)據(jù)類型詳細(xì)介紹

    這篇文章主要介紹了Go語(yǔ)言數(shù)據(jù)類型詳細(xì)介紹,Go語(yǔ)言數(shù)據(jù)類型包含基礎(chǔ)類型和復(fù)合類型兩大類,下文關(guān)于這兩類型的相關(guān)介紹,需要的小伙伴可以參考一下
    2022-03-03
  • go語(yǔ)言簡(jiǎn)單的處理http請(qǐng)求的函數(shù)實(shí)例

    go語(yǔ)言簡(jiǎn)單的處理http請(qǐng)求的函數(shù)實(shí)例

    這篇文章主要介紹了go語(yǔ)言簡(jiǎn)單的處理http請(qǐng)求的函數(shù),實(shí)例分析了Go語(yǔ)言處理http請(qǐng)求的技巧,需要的朋友可以參考下
    2015-03-03
  • Golang交叉編譯(跨平臺(tái)編譯)的使用

    Golang交叉編譯(跨平臺(tái)編譯)的使用

    本文主要介紹了Golang交叉編譯(跨平臺(tái)編譯)的使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-08-08
  • golang簡(jiǎn)單tls協(xié)議用法完整示例

    golang簡(jiǎn)單tls協(xié)議用法完整示例

    這篇文章主要介紹了golang簡(jiǎn)單tls用法,分析了tls協(xié)議的使用步驟及客戶端與服務(wù)器端的相關(guān)實(shí)現(xiàn)代碼,需要的朋友可以參考下
    2016-07-07
  • golang 之 wire 庫(kù)的使用小結(jié)

    golang 之 wire 庫(kù)的使用小結(jié)

    Wire是一個(gè)用于Go語(yǔ)言的編譯時(shí)依賴注入庫(kù),通過(guò)代碼生成提高性能和可維護(hù)性,它支持編譯時(shí)依賴注入、類型安全、簡(jiǎn)單易用等功能,文章通過(guò)代碼示例展示了如何使用Wire進(jìn)行依賴注入,并探討了其優(yōu)點(diǎn)如解耦、可測(cè)試和維護(hù)性,感興趣的朋友跟隨小編一起看看吧
    2025-03-03
  • Go語(yǔ)言七篇入門教程二程序結(jié)構(gòu)與數(shù)據(jù)類型

    Go語(yǔ)言七篇入門教程二程序結(jié)構(gòu)與數(shù)據(jù)類型

    這篇文章主要為大家介紹了Go語(yǔ)言的程序結(jié)構(gòu)與數(shù)據(jù)類型,本篇文章是Go語(yǔ)言七篇入門系列文,有需要的朋友可以借鑒參考下,希望能夠有所幫助
    2021-11-11
  • Golang中的new()和make()函數(shù)本質(zhì)區(qū)別

    Golang中的new()和make()函數(shù)本質(zhì)區(qū)別

    在 Go 語(yǔ)言開(kāi)發(fā)中,new() 和 make() 是兩個(gè)容易讓開(kāi)發(fā)者感到困惑的內(nèi)建函數(shù),盡管它們都用于內(nèi)存分配,但其設(shè)計(jì)目的、適用場(chǎng)景和底層實(shí)現(xiàn)存在本質(zhì)差異,本文將通過(guò)類型系統(tǒng)、內(nèi)存模型和編譯器實(shí)現(xiàn)三個(gè)維度,深入解析這兩個(gè)函數(shù)的本質(zhì)區(qū)別,感興趣的朋友一起看看吧
    2025-02-02
  • Go語(yǔ)言官方依賴注入工具Wire的使用教程

    Go語(yǔ)言官方依賴注入工具Wire的使用教程

    依賴注入是一種實(shí)現(xiàn)控制反轉(zhuǎn)且用于解決依賴性問(wèn)題的設(shè)計(jì)模式。Golang?中常用的依賴注入工具主要有?Inject?、Dig?等。但是今天主要介紹的是?Go?團(tuán)隊(duì)開(kāi)發(fā)的?Wire,一個(gè)編譯期實(shí)現(xiàn)依賴注入的工具,感興趣的可以了解一下
    2022-09-09
  • 詳解Golang如何監(jiān)聽(tīng)某個(gè)函數(shù)的開(kāi)始執(zhí)行和執(zhí)行結(jié)束

    詳解Golang如何監(jiān)聽(tīng)某個(gè)函數(shù)的開(kāi)始執(zhí)行和執(zhí)行結(jié)束

    這篇文章主要為大家詳細(xì)介紹了Golang如何監(jiān)聽(tīng)某個(gè)函數(shù)的開(kāi)始執(zhí)行和執(zhí)行結(jié)束,文中的示例代碼講解詳細(xì),有需要的小伙伴可以參考一下
    2024-02-02
  • Apache?IoTDB開(kāi)發(fā)系統(tǒng)之Go原生接口方法

    Apache?IoTDB開(kāi)發(fā)系統(tǒng)之Go原生接口方法

    這篇文章主要為大家介紹了?Apache?IoTDB開(kāi)發(fā)系統(tǒng)之Go原生接口方法,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-09-09

最新評(píng)論