一文理清sshc包的使用场景和掌握两种连接方式及异常场景

2024-06-14 13:36

本文主要是介绍一文理清sshc包的使用场景和掌握两种连接方式及异常场景,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一文理清sshc、ssh包的使用场景和两种连接方式

  • SSH协议
      • SSH(Secure Shell)协议支持通过多种编程语言实现客户端和服务端的功能,包括Go、Python、Java、C#等。
  • GO语言 sshc包的使用
    • 建立连接
      • 1.DialWithKey
      • 2.DialWithPasswd
    • 运行命令
    • 异常场景
      • 思维导图

SSH协议

在实际工作中我们往往需要通过各种语言实现SSH客户端和服务端的功能。

SSH(Secure Shell)协议支持通过多种编程语言实现客户端和服务端的功能,包括Go、Python、Java、C#等。

在网络通信领域,SSH协议因其出色的安全性和广泛的应用场景而成为远程管理服务器不可或缺的工具。从系统管理员到开发人员,不同背景的用户都依赖于SSH来实现安全的文件传输、命令执行以及环境配置等。接下来介绍一下使用不同编程语言实现SSH客户端和服务端的具体方式:

  • Go:通过golang.org/x/crypto/ssh包,Go语言提供了丰富的API来创建SSH客户端和服务端。如搜索结果中的示例代码所示,开发者可以建立连接、认证、执行远程命令等操作。

  • Python:Python的paramiko库是构建SSH客户端的常用方式。它提供了一个简单的方法来连接SSH服务器并执行命令,同时支持密钥认证等多种认证方式。

  • Java:Java生态中,JSch是一个流行的纯Java实现的SSH2客户端,允许连接到一个SSH服务器并执行命令、文件传输等操作。

  • C#:对于.NET环境,可以使用SSH.NET库来实现SSH功能。这个库提供了SCP客户端和服务器端的实现,支持SSH文件传输。

  • JavaScript:Node.js环境中,可以使用ssh2库来实现SSH客户端。它支持异步调用,适用于需要长时间运行SSH会话的场景。

  • C++:虽然不如其他语言流行,但C++也有像libssh这样的库,为C和C++开发者提供SSH功能的实现。

了解各种语言的SSH实现不仅有助于跨平台的应用程序开发,还能提高开发效率,特别是在进行自动化部署、配置管理和远程监控任务时。每种语言的SSH实现都有其特点,开发者应根据具体需求和环境选择最合适的工具。

综上所述,通过各种编程语言实现SSH客户端和服务端的功能不仅展示了SSH协议的灵活性和强大性,也为开发者提供了广泛的选择来满足不同的应用需求。无论是在系统运维、自动化测试还是日常开发中,合理利用这些工具都能显著提高工作的效率和安全性。

这里给大家介绍一下GO语言的crypto/ssh、sshc使用场景以及两种连接方式举例。

GO语言 sshc包的使用

golang.org/x/crypto/ssh 包为Go语言开发者提供了实现SSH客户端和服务端的功能。在现代的软件开发中,远程操作和管理服务器是一项常见的需求,而SSH协议是这一过程中的关键。通过使用Go语言的ssh包,开发人员能够以编程方式与SSH服务器进行交互,实现自动化和脚本化管理任务。
SSHc包通常是指实现了SSH客户端功能的代码库或工具集。
使用sshc包具体流程如下:

  1. 建立连接:通过以上介绍的两个连接函数,可以传入服务器地址、端口以及客户端用户、密码或者密钥,从而建立起到SSH服务器的连接,并返回一个Client对象。
  2. 运行命令:在获取到Client对象之后,可以通过err = client.Cmd(cmd).SetStdio(&stdout, &stderr).Run() 执行一个命令,并将标准输出和标准错误输出重定向到指定的变量中。其中,cmd是要执行的命令,stdout和stderr分别是用于存储标准输出和标准错误输出的变量。最后,Run()方法会执行该命令并返回一个error类型的值,表示命令执行的结果。

建立连接

1.DialWithKey

函数说明:这是一个使用密钥进行SSH连接的函数,函数名为DialWithKey,接收三个参数:addr(地址),user(用户名)和keyfile(密钥文件路径)。
函数返回一个*Client类型的对象和一个error类型的错误信息。

/*
函数内部首先读取密钥文件内容,然后解析私钥,如果出错则返回错误信息。
接着创建一个ssh.ClientConfig类型的对象config,设置用户名、认证方式(公钥)
和主机密钥回调函数。最后调用Dial函数,传入协议类型(tcp)、地址和配置信息,返回结果。
*/
func DialWithKey(addr, user, keyfile string) (*Client, error) {key, err := ioutil.ReadFile(keyfile)if err != nil {return nil, err}signer, err := ssh.ParsePrivateKey(key)if err != nil {return nil, err}config := &ssh.ClientConfig{User: user,Auth: []ssh.AuthMethod{ssh.PublicKeys(signer),},HostKeyCallback: ssh.HostKeyCallback(func(hostname string, remote net.Addr, key ssh.PublicKey) error { return nil }),}return Dial("tcp", addr, config)
}

使用这个方法前,你应该配置互信,在远程服务器中存在这样一个文件
在这里插入图片描述
这个文件可以是你手动创建的也可以是ssh-copy-id命令创建的
这里博主介绍一下手动创建的方法:在你的windows用户路径下找到.ssh文件夹,将里面的id_rsa.pub复制到远程authorized_keys文件中。现在即可通过密钥的方式进行ssh连接。
在这里插入图片描述
直接调用,建立起到SSH服务器的连接,并返回一个Client对象

client, err := sshc.DialWithKey(addr, user, "C:\\Users\\SU\\.ssh\\id_rsa")

2.DialWithPasswd

这是一个使用密码进行SSH连接的函数,函数名为DialWithPasswd,接收三个参数:addr(地址),user(用户名)和passwd(密码)。函数返回一个*Client类型的对象和一个error类型的错误信息。

/*
函数内部首先创建一个ssh.ClientConfig类型的对象config,
设置用户名、认证方式(密码)和主机密钥回调函数。
然后调用Dial函数,传入协议类型(tcp)、地址和配置信息,最后返回结果。
*/
func DialWithPasswd(addr, user, passwd string) (*Client, error) {config := &ssh.ClientConfig{User: user,Auth: []ssh.AuthMethod{ssh.Password(passwd),},HostKeyCallback: ssh.HostKeyCallback(func(hostname string, remote net.Addr, key ssh.PublicKey) error { return nil }),}return Dial("tcp", addr, config)
}

我们使用的时候仅需要提供地址(add := “172.156.13.22:22” 你需要使用的目标ip+端口号22即可)用户(user := “root” 你拥有远程服务器访问权限的用户名,你可以本地试验一下通过ssh IP -I root 比如我当前这个服务器不支持指定root用户登录)
在这里插入图片描述
直接调用,建立起到SSH服务器的连接,并返回一个Client对象

client, err := sshc.DialWithPasswd(addr, user, passwd)

运行命令

以密码登录连接为例:

func SshExec(addr string, user string, passwd string, cmd string) (code int, outStr, errStr string, err error) {var (stdout bytes.Bufferstderr bytes.Buffer)client, err := sshc.DialWithPasswd(addr, user, passwd)if err != nil {return -1, "", "", err}defer client.Close()err = client.Cmd(cmd).SetStdio(&stdout, &stderr).Run()if err != nil {var statErr *ssh.ExitError  //这个类型通常用于处理SSH连接过程中的错误。if errors.As(err, &statErr) {code = statErr.Waitmsg.ExitStatus()  //这里的code值可以用来做特判outStr = stdout.String()errStr = stderr.String()return}return -1, "", "", err}return 0, stdout.String(), stderr.String(), nil
}
//调用
code, stdout, stderr, err := SshExec("远程服务器ip:22", "登录用户", "登录密码", "你想执行的shell命令")

异常场景

在通过SSH(Secure Shell)进行远程连接时,可能会遇到一系列的异常场景,这些场景通常涉及到网络问题、服务器配置、SSH服务配置等因素。以下将探讨一些常见的SSH连接异常场景及其解决方法:

  1. 连接被拒绝

    原因分析:当出现“ssh: connect to host 端口 Connection refused”的错误信息时,通常意味着SSH服务未运行或者网络配置有误。
    解决办法:首先检查SSH服务是否已安装并启动。可以使用命令ps -e | grep ssh来检查sshd服务是否运行,如果没有安装sshd,需要使用apt-get install openssh-server命令进行安装。若服务已安装但未运行,可以通过service sshd restart命令重启服务。

  2. 权限拒绝

    原因分析:“Permission denied,please try again”错误通常表明用户账号存在问题,可能是账号不存在、密码错误或账号被禁止登录。
    解决办法:确认用户名是否存在,可以使用id 命令检查。如果用户不存在,需要创建该用户并设置密码。若密码输入无误但仍然无法登录,检查/etc/ssh/sshd_config配置文件中的PermitRootLogin选项,确保其设置为yes,然后重启sshd服务。

  3. 主机密钥验证失败

    原因分析“@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!”这样的警告信息表示主机的密钥发生了变化,可能遭受了中间人攻击。
    解决办法:检查目标主机的公钥是否发生了变化。可以通过删除~/.ssh/known_hosts文件中的相关条目来解决,使用命令ssh-keygen -f "/root/.ssh/known_hosts" -R "<host_ip>",然后重新连接以更新密钥。

  4. SSH会话连接超时

    原因分析:SSH连接超时可能是由于网络不稳定、SSH配置文件设置不当或防火墙阻止等原因造成的。
    解决办法:首先检查网络连接稳定性,可以使用ping命令。接着,检查SSH配置文件/etc/ssh/sshd_config中的ClientAliveInterval和ClientAliveCountMax参数设置是否合理。如果问题依旧,检查防火墙设置,确保没有阻止SSH连接。

  5. SSH服务配置问题

    原因分析:SSH服务的配置错误也可能导致连接异常,例如错误的端口配置或认证方式设置。
    解决办法:检查SSH服务的配置文件/etc/ssh/sshd_config,确保所有设置正确无误,特别是端口号、认证方式等关键配置。修改配置后,需要重启SSH服务使更改生效。

思维导图

在这里插入图片描述

综上所述,Go语言的ssh包为开发人员提供了一个强大且灵活的工具,用于构建需要SSH交互的应用程序。通过合理利用其提供的API,可以实现高效且安全的远程服务器管理和自动化任务执行。

这篇关于一文理清sshc包的使用场景和掌握两种连接方式及异常场景的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1060549

相关文章

SpringBoot中@Value注入静态变量方式

《SpringBoot中@Value注入静态变量方式》SpringBoot中静态变量无法直接用@Value注入,需通过setter方法,@Value(${})从属性文件获取值,@Value(#{})用... 目录项目场景解决方案注解说明1、@Value("${}")使用示例2、@Value("#{}"php

SpringBoot分段处理List集合多线程批量插入数据方式

《SpringBoot分段处理List集合多线程批量插入数据方式》文章介绍如何处理大数据量List批量插入数据库的优化方案:通过拆分List并分配独立线程处理,结合Spring线程池与异步方法提升效率... 目录项目场景解决方案1.实体类2.Mapper3.spring容器注入线程池bejsan对象4.创建

Python使用FastAPI实现大文件分片上传与断点续传功能

《Python使用FastAPI实现大文件分片上传与断点续传功能》大文件直传常遇到超时、网络抖动失败、失败后只能重传的问题,分片上传+断点续传可以把大文件拆成若干小块逐个上传,并在中断后从已完成分片继... 目录一、接口设计二、服务端实现(FastAPI)2.1 运行环境2.2 目录结构建议2.3 serv

Spring Security简介、使用与最佳实践

《SpringSecurity简介、使用与最佳实践》SpringSecurity是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架,本文给大家介绍SpringSec... 目录一、如何理解 Spring Security?—— 核心思想二、如何在 Java 项目中使用?——

springboot中使用okhttp3的小结

《springboot中使用okhttp3的小结》OkHttp3是一个JavaHTTP客户端,可以处理各种请求类型,比如GET、POST、PUT等,并且支持高效的HTTP连接池、请求和响应缓存、以及异... 在 Spring Boot 项目中使用 OkHttp3 进行 HTTP 请求是一个高效且流行的方式。

java.sql.SQLTransientConnectionException连接超时异常原因及解决方案

《java.sql.SQLTransientConnectionException连接超时异常原因及解决方案》:本文主要介绍java.sql.SQLTransientConnectionExcep... 目录一、引言二、异常信息分析三、可能的原因3.1 连接池配置不合理3.2 数据库负载过高3.3 连接泄漏

防止Linux rm命令误操作的多场景防护方案与实践

《防止Linuxrm命令误操作的多场景防护方案与实践》在Linux系统中,rm命令是删除文件和目录的高效工具,但一旦误操作,如执行rm-rf/或rm-rf/*,极易导致系统数据灾难,本文针对不同场景... 目录引言理解 rm 命令及误操作风险rm 命令基础常见误操作案例防护方案使用 rm编程 别名及安全删除

python获取指定名字的程序的文件路径的两种方法

《python获取指定名字的程序的文件路径的两种方法》本文主要介绍了python获取指定名字的程序的文件路径的两种方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要... 最近在做项目,需要用到给定一个程序名字就可以自动获取到这个程序在Windows系统下的绝对路径,以下

Java使用Javassist动态生成HelloWorld类

《Java使用Javassist动态生成HelloWorld类》Javassist是一个非常强大的字节码操作和定义库,它允许开发者在运行时创建新的类或者修改现有的类,本文将简单介绍如何使用Javass... 目录1. Javassist简介2. 环境准备3. 动态生成HelloWorld类3.1 创建CtC

使用Python批量将.ncm格式的音频文件转换为.mp3格式的实战详解

《使用Python批量将.ncm格式的音频文件转换为.mp3格式的实战详解》本文详细介绍了如何使用Python通过ncmdump工具批量将.ncm音频转换为.mp3的步骤,包括安装、配置ffmpeg环... 目录1. 前言2. 安装 ncmdump3. 实现 .ncm 转 .mp34. 执行过程5. 执行结