Go语言网络编程:SSH连接
旨在提升Go语言网络编程能力
SSH是什么?
SSH 为 Secure Shell 的缩写,为建立在应用层基础上的安全协议。SSH 是较可靠,专为远程登录会话和其他网络服务提供安全性的协议。利用 SSH 协议可以有效防止远程管理过程中的信息泄露问题。
通过使用SSH,可以把所有传输的数据进行加密,这样"中间人"这种攻击方式就不可能实现了,而且也能够防止DNS欺骗和IP欺骗。使用SSH,还有一个额外的好处就是传输的数据是经过压缩的,所以可以加快传输的速度。
SSH如何工作?
SSH由服务器和客户端组成,在整个通信过程中,为建立安全的SSH通道,会经历如下几个阶段:
- 连接建立
SSH服务器在指定的端口侦听客户端的连接请求,在客户端向服务器发起连接请求后,双方建立一个TCP连接。
- 版本协商
SSH协议目前存在SSH1.X(SSH2.0之前的版本)和SSH2.0版本。SSH2.0协议相比SSH1.X协议来说,在结构上做了扩展,可以支持更多的认证方法和密钥交换方法,同时提高了服务能力。SSH服务器和客户端通过协商确定最终使用的SSH版本号。
- 算法协商
SSH支持多种加密算法,双方根据各自支持的算法,协商出最终用于产生会话密钥的密钥交换算法、用于数据信息加密的加密算法、用于进行数字签名和认证的公钥算法以及用于数据完整性保护的HMAC算法。
- 密钥交换
服务器和客户端通过密钥交换算法,动态生成共享的会话密钥和会话ID,建立加密通道。会话密钥主要用于后续数据传输的加密,会话ID用于在认证过程中标识该SSH连接。
- 用户认证
SSH客户端向服务器端发起认证请求,服务器端对客户端进行认证。SSH支持以下几种认证方式:
- 密码(password)认证:客户端通过用户名和密码的方式进行认证,将加密后的用户名和密码发送给服务器,服务器解密后与本地保存的用户名和密码进行对比,并向客户端返回认证成功或失败的消息。
- 密钥(publickey)认证:客户端通过用户名,公钥以及公钥算法等信息来与服务器进行认证。
- password-publickey认证:指用户需要同时满足密码认证和密钥认证才能登录。
- all认证:只要满足密码认证和密钥认证其中一种即可。
- 会话请求
认证通过后,SSH客户端向服务器端发送会话请求,请求服务器提供某种类型的服务,即请求与服务器建立相应的会话。
- 会话交互
会话建立后,SSH服务器端和客户端在该会话上进行数据信息的交互。
代码实现
可以使用Go语言的ssh包
go get golang.org/x/crypto/ssh
首先是向服务器发起请求,建立连接。这里使用ssh.Dial函数,
func Dial(network string, addr string, config *ClientConfig) (*Client, error)
SSH是基于TCP的,所以对该函数的第一个参数传入"TCP",第二个参数指定为IP地址,第三个参数是客户端配置信息。
ClientConfig结构如下:
type ClientConfig struct {
Config
User string
Auth []AuthMethod
HostKeyCallback HostKeyCallback
BannerCallback BannerCallback
ClientVersion string
HostKeyAlgorithms []string
Timeout time.Duration
}
在该结构中首先要指定User,即用户名。Auth,同样要被指定,这个参数包含了可用于服务器的身份验证方法。最后要指定HostKeyCallBack,在加密握手期间调用HostKeyCallback以验证服务器的主机密钥。
上述函数包含了从建立连接到用户认证的过程,下面要创建一个会话。调用NewSession方法可以创建会话。
func (c *Client) NewSession() (*Session, error)
然后发起会话请求,使用如下函数
func (s *Session) RequestPty(term string, h, w int, termmodes TerminalModes) error
pty是伪终端,伪终端由终端模拟器提供,终端模拟器是一个运行在用户态的应用程序。
该函数的第四个参数是终端模式,这是一个map,可以传入一些键值,进行设置。
type TerminalModes map[uint8]uint32
最后要将会话的输入输出设置为系统的标准输入输出,使得用户可以直接从终端输入指令。
完整代码
package main
import (
"golang.org/x/crypto/ssh"
"log"
"os"
)
// 基本信息
const (
address = "xx.xx.xx.xx"
username = "username"
password = "password"
)
func main() {
// 设置配置信息
config := ssh.ClientConfig{
User: username,
Auth: []ssh.AuthMethod{ssh.Password(password)},
HostKeyCallback: ssh.InsecureIgnoreHostKey(), // 用于简单的认证
}
// 与服务器建立连接
client, err := ssh.Dial("tcp", address, &config)
if err != nil {
log.Println(err)
return
}
// 创建一个会话
session, _ := client.NewSession()
defer session.Close()
// 设置Terminal Mode
modes := ssh.TerminalModes{
ssh.ECHO: 0, // 关闭回显
ssh.TTY_OP_ISPEED: 14400, // 设置传输速率
ssh.TTY_OP_OSPEED: 14400,
}
// 请求伪终端
err = session.RequestPty("linux", 32, 160, modes)
if err != nil {
log.Println(err)
return
}
// 设置输入输出
session.Stdout = os.Stdout
session.Stdin = os.Stdin
session.Stderr = os.Stderr
session.Shell() // 启动shell
session.Wait() // 等待退出
}
运行
Activate the web console with: systemctl enable --now cockpit.socket
Last login: Wed May 18 18:18:03 2022
[root@VM-4-16-centos ~]# uname
Linux
Go语言网络编程:SSH连接的更多相关文章
- 11. Go 语言网络编程
Go 语言网络编程 Go语言在编写 web 应用方面非常得力.因为目前它还没有 GUI(Graphic User Interface 图形化用户界面)的框架,通过文本或者模板展现的 html 界面是目 ...
- 聊聊iOS中网络编程长连接的那些事
1.长连接在iOS开发中的应用 常见的短连接应用场景:一般的App的网络请求都是基于Http1.0进行的,使用的是NSURLConnection.NSURLSession或者是AFNetworking ...
- 《Go语言网络编程》第一章:体系
原书地址:http://tumregels.github.io/Network-Programming-with-Go 如果不知道想要构建什么,是不可能创建一个系统的.而且如果不知道它工作的环境,也同 ...
- C语言网络编程(Linux && Windows)(1)
和朋友一起做课程设计,同时学习C语言的网络编程,以前写的都是python网络编程,但python很多的库都是封装好的,大部分人在使用的时候不会去了解底层的实现,这样对长远的学习不太好,也改正自己这方面 ...
- GO语言网络编程
socket编程 Socket是BSD UNIX的进程通信机制,通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄.Socket可以理解为TCP/IP网络的API,它 ...
- 三十天学不会TCP,UDP/IP网络编程-ARP -- 连接MAC和IP
继续来做(da)推(guang)介(gao)我自己的!由于这两年接触到了比较多的这方面的知识,不想忘了,我决定把他们记录下来,所以决定在GitBook用半年时间上面写下来,这是目前写的一节,目前已完成 ...
- UNIX网络编程——TCP连接的建立和断开、滑动窗口
一.TCP段格式: TCP的段格式如下图所示: 源端口号与目的端口号:源端口号和目的端口号,加上IP首部的源IP地址和目的IP地址唯一确定一个TCP连接. 序号:序号表示在这个报文段中的第一个数据字节 ...
- python网络编程--TCP连接的三次握手(三报文握手)与四次挥手
一.TCP连接 运输连接有三个阶段: 连接建立.数据传送和连接释放. 在TCP连接建立过程中要解决以下三个问题: 1,要使每一方能够确知对方的存在. 2.要允许双方协商一些参数(如最大窗口之,是否使用 ...
- Linux C语言 网络编程(二) server模型
前面介绍了关于连接linux服务端方式,可是服务端的资源是有限的,所以我们通常须要又一次思考,设计一套server模型来处理相应的client的请求. 第一种:并发server.通过主进程统一处理cl ...
- 网络编程ssh,粘包
1.什么是socket? TCP,可靠地,面向连接协议,有阻塞rect udp,不可靠的,无线连接的服务 这里因为不需要阻塞,所以速度会很快,但安全性不高 2.关于客户端退出而服务器未退出的解决办法 ...
随机推荐
- AJAX请求的基本操作
1 const { request, response } = require('express'); 2 //引入express 3 const express = require('express ...
- git练习网站(图形化版)
https://learngitbranching.js.org/?locale=zh_CN
- springboot项目导出excel实现
参见:https://blog.csdn.net/duli_0105/article/details/102809936
- linux 安装 jupyter notebook
虚拟机使用的是ubuntu系统 直接遇见一个问题 E: 无法获得锁 /var/lib/dpkg/lock - open (11: 资源暂时不可用) E: 无法锁定管理目录(/var/lib/dpkg/ ...
- vue打包记录
这里的确是css以及js文件的路径问题,但解决时并不需要手动改路径或者加一段判断去修改,最方便的办法时在项目打包前的vue.config.js里面将publicPath属性添加或者修改为 public ...
- mysql创建函数时提示1418。可选关闭二进制日志或者设置log_bin_trust_function_creators=1
报错详情如下:1418--This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its declaration a ...
- 在Vue的mixins(混入)里面调用Vuex(@/store/index.js)的函数
第一步:在mixin.js里面引入 mapMutations 第二步:跟组件内调用一样,在methods里面写 "...mapMutations(['xxx'])", 然后LZ ...
- nginx配置权重,ip_hash....
nginx为后端web服务器(apache,nginx,tomcat,weblogic)等做反向代理 几台后端web服务器需要考虑文件共享,数据库共享,session共享问题.文件共享可以使用nfs, ...
- pycharm安装包的简便方法
- 记录小程序字符串模板渲染WxParse
1.先去https://github.com/icindy/wxParse上downLoad代码,然后直接复制到项目里,跟pages目录同级 2.在要用的js页面声明 var WxParse = re ...