本文目录:
ssh2工作原理
最佳答案:
SSH2(Secure Shell Version 2)是一种用于在不安全的网络上提供安全远程登录和其他网络服务的协议。它通过加密数据传输,确保了数据在传输过程中的机密性和完整性,防止了数据被窃听和篡改。SSH2的工作原理大致可以分为以下几个阶段:
1. 版本号协商阶段:客户端和服务器通过交换版本信息来确定使用的SSH协议版本。如果双方都支持SSH2,则使用SSH2进行后续通信。
2. 密钥和算法协商阶段:双方通过交换支持的加密算法列表,协商出最终使用的加密算法。这包括公钥算法、加密算法、MAC(消息验证码)算法和压缩算法等。
3. 密钥交换和会话密钥生成:使用Diffie-Hellman算法进行密钥交换,生成一个只有双方知道的共享密钥。这个过程确保了即使第三方截获了交换的信息,也无法得到共享密钥。
4. 认证阶段:客户端向服务器发送认证请求,服务器对客户端进行认证。SSH2支持多种认证方法,包括密码认证、公钥认证等。
5. 交互会话阶段:认证通过后,客户端和服务器进入交互会话阶段。在这个阶段,所有传输的数据都使用共享密钥进行加密和解密,确保了数据的安全性。
SSH2还支持SFTP(Secure File Transfer Protocol),这是一种安全的文件传输方式,允许用户通过加密的SSH连接传输文件,为数据传输提供了更高的安全保障。
通过这些步骤,SSH2确保了远程登录和网络服务的安全性,防止了中间人攻击和其他网络威胁。
浅谈SSH2工作原理
最近在研究 GitHub 多账号管理 的问题,这其中就涉及到了 SSH 的连接方式,因此不得不了解一下 SSH 的工作原理。一番搜索和实践后发现,这里面的水其实很深,真要理解透彻可能需要去读几本关于密码学的书。本人并没有多大兴趣去研究这个,所以只是浅谈,但对于只是使用 SSH 工具的人来说,这完全够用了。
几年前我了解到的是 SSH 使用非对称加密算法(RSA)来完成对称加密算法的密钥交换,最后使用对称加密算法实现数据安全传输。现在网上查到的却是先使用 Diffie-Hellman(DH)算法完成对称加密算法的密钥交换,再通过客户端的公钥识别身份。这让我丈二和尚摸不着头脑。
直到写这篇文章,在搜索了 SSH1 和 SSH2 的区别后,我才找到答案。原来这里面说的其实是两个不同的东西,一个是 SSH1,一个是 SSH2。现在都流行使用 SSH2,所以网上搜到的大多都是 SSH2 方面的东西。
如果你直接在网上搜索 “ SSH 实现原理 ”,那么搜到的大多都只是在谈 SSH 的身份认证部分而非整一个工作原理。试着搜索 “ SSH 协商会话加密 ”,你将会看到不一样的内容。
SSH2 的整一个连接过程大体上可分为两个部分: 协商会话加密 和 身份认证 。
这其中还用到了 对称加密 、 非对称加密 和 哈希 算法( MD5 )。
协商会话加密 使用 Diffie-Hellman 算法生成会话密钥,具体流程如下。(大概流程)
注意这里的公钥、私钥和下面要讲的非对称加密的公钥、私钥是不一样的,不是同一个东西。
共享密钥 确定后,接下来的通信都使用 共享密钥 进行加密和解密,因此是安全的,但我们还没有确认双方的身份。
客户端识别服务端是通过人工进行确认的。我们在第一次连接服务器时,都会弹出一个警告,让用户确定是否进行连接。警告的内容包含了服务器的 公钥指纹 ,如下图。
既然 公钥 是公开的,那中间人是不是也可以伪造这样的信息,让我们误以为是真实的服务器发出来的?答案是“是的”,所以我们还需要确定服务端是否拥有对应的私钥。不过查阅相关的文章,好像没有这样一个过程,都是在用户确定服务端公钥(回复yes)后就进行下一步操作(确认客户端身份)。个人感觉不合理,应该是要有的,具体我也没有深究,毕竟这篇文章是 浅谈 嘛!(好像被发现为什么要用这个做标题了😁。)
其实要确定服务端是否拥有对应的私钥也很容易,接下来讲的如何确定客户端身份会讲到,道理是一样。
服务端识别客户端身份有两种方式: 账号密码 和 SSH密钥对 。
账号密码 验证的方式很容易理解,客户端将用户名和密码用 共享密钥 加密后发给服务端,服务端再使用 共享密钥 解密,取得用户名和密码,再以此验证用户信息。
SSH密钥对 需要管理员事先将客户端的公钥上传到服务端对应用户的 ~/.ssh/authorized_keys 文件中,再进行以下流程。
前面说到在 协商会话加密 后,以后的通信都会使用 共享密钥 进行加密。在使用 SSH密钥对 进行 身份认证中 ,是可以不使用 共享密钥 进行加密的,因为整个过程所用到的 加密随机数 和 MD5值 是可以公开的。具体在真实的场景中有没有使用 共享密钥 加密这个过程我也不太清楚( 浅谈浅谈),不过不会有什么安全问题。
到这里,整个通信流程大家应该都理解了,不过我猜大家还会有一些问题。
一开始我以为是为了连接速度,后来查了 SSH1 和 SSH2 的区别才发现,问题并不简单。
下面引用 海里木有鱼 的 SSH1和SSH2的区别 内容来解答这个问题。
一切,都是利益的纠葛!
ssh-agent 自动寻找,或者 ssh 登录时指定私钥(公钥和私钥名相同)。详细内容可以看 SSH多种远程登录方法
由于这个种子值是可以公开的,所以不怕被第三方知道。可以由客户端或者服务端自己随机生成然后发给对方,只要对方同意就行了。就像两个人去吃饭,讨论要选择哪个餐馆是一样的道理。
Understanding the SSH Encryption and Connection Process ,Justin Ellingwood
SSH 加密和连接过程 ,WqyJh
SSH1和SSH2的区别 ,海里木有鱼
Linux系统中SSH命令的使用教程
ssh用于登录远程主机, 并且在远程主机上执行命令,它的目的是替换rlogin和rsh,同时在不安全的网络之上,两个互不信任的主机之间, 提供加密的, 安全的通信连接.先来看一下ssh命令的一些参数:参数
-a
禁止转发认证代理的连接.
-A
允许转发认证代理的连接. 可以在配置文件中对每个主机单独设定这个参数.
代理转发须谨慎. 某些用户能够在远程主机上绕过文件访问权限 (由于代理的 UNIX 域 socket), 他们可以通过转发的连接访问本地代理. 攻击者不可能从代理获得密钥内容, 但是他们能够操作这些密钥, 利用加载到代理上 的身份信息通过认证.
-b bind_address
在拥有多个接口或地址别名的机器上, 指定收发接口.
-c blowfish 3des des
选择加密会话的密码术. 3des 是默认算法. 3des (triple-des) 用三支不同的密钥做加密-解密-加密三次运算, 被认为比较可靠. blowfish 是一种快速的分组加密术(block cipher), 非常安全, 而且速度比 3des 快的多. des 仅支持 客户端, 目的是能够和老式的不支持 3des 的协议第一版互操作. 由于其密码算法上的弱点, 强烈建议避免使用.
-c cipher_spec
另外, 对于协议第二版, 这里可以指定一组用逗号隔开, 按优先顺序排列的密码术. 详见 Ciphers
-e ch ^ch none
设置 pty 会话的 escape 字符 (默认字符: `~ ) . escape 字符只在行首有效, escape 字符后面跟一个点 (`. ) 表示结束连接, 跟一个 control-Z 表示挂起连接(suspend), 跟 escape 字符自己 表示输出这个字符. 把这个字符设为 ``none 则禁止 escape 功能, 使会话完全透明.
-f
要求 在执行命令前退至后台. 它用于当 准备询问口令或密语, 但是用户希望它在后台进行. 该选项隐含了 -n 选项. 在远端机器上启动 X11 程序的推荐手法就是类似于 ssh -f host xterm 的命令.
-g
允许远端主机连接本地转发的端口.
-i identity_file
指定一个 RSA 或 DSA 认证所需的身份(私钥)文件. 默认文件是协议第一版的 $HOME/.ssh/identity 以及协议第二版的 $HOME/.ssh/id_rsa 和 $HOME/.ssh/id_dsa 文件. 也可以在配置文件中对每个主机单独指定身份文件. 可以同时使用多个 -i 选项 (也可以在配置文件中指定多个身份文件).
-I smartcard_device
指定智能卡(smartcard)设备. 参数是设备文件, 能够用它和智能卡通信, 智能卡里面存储了用户的 RSA 私钥.
-k
禁止转发 Kerberos 门票和 AFS 令牌. 可以在配置文件中对每个主机单独设定这个参数.
-l login_name
指定登录远程主机的用户. 可以在配置文件中对每个主机单独设定这个参数.
-m mac_spec
另外, 对于协议第二版, 这里可以指定一组用逗号隔开, 按优先顺序排列的 MAC(消息验证码)算法 (message authentication code). 详情以 MACs 为关键字查询.
-n
把 stdin 重定向到 /dev/null (实际上防止从 stdin 读取数据). 在后台运行时一定会用到这个选项. 它的常用技巧是远程运行 X11 程序. 例如, ssh -n shadows.cs.hut.fi emacs 将会在 shadows.cs.hut.fi 上启动 emacs, 同时自动在加密通道中转发 X11 连接. 在后台运行. (但是如果 要求口令或密语, 这种方式就无法工作; 参见 -f 选项.)
-N
不执行远程命令. 用于转发端口. (仅限协议第二版)
-o option
可以在这里给出某些选项, 格式和配置文件中的格式一样. 它用来设置那些没有命令行开关的选项.
-p port
指定远程主机的端口. 可以在配置文件中对每个主机单独设定这个参数.
-q
安静模式. 消除所有的警告和诊断信息.
-s
请求远程系统激活一个子系统. 子系统是 SSH2 协议的一个特性, 能够协助 其他应用程序(如 sftp)把SSH用做安全通路. 子系统通过远程命令指定.
-t
强制分配伪终端. 可以在远程机器上执行任何全屏幕(screen-based)程序, 所以非常有用, 例如菜单服务. 并联的 -t 选项强制分配终端, 即使 没有本地终端.
-T
禁止分配伪终端.
-v
冗详模式. 使 打印关于运行情况的调试信息. 在调试连接, 认证和配置问题时非常有用. 并联的 -v 选项能够增加冗详程度. 最多为三个.
-x
禁止 X11 转发.
-X
允许 X11 转发. 可以在配置文件中对每个主机单独设定这个参数.
应该谨慎使用 X11 转发. 如果用户在远程主机上能够绕过文件访问权限 (根据用户的X授权数据库), 他就可以通过转发的连接访问本地 X11 显示器. 攻击者可以据此采取行动, 如监视键盘输入等.
-C
要求进行数据压缩 (包括 stdin, stdout, stderr 以及转发 X11 和 TCP/IP 连接 的数据). 压缩算法和 gzip(1) 的一样, 协议第一版中, 压缩级别 ``level 用 CompressionLevel 选项控制. 压缩技术在 modem 线路或其他慢速连接上很有用, 但是在高速网络上反而 可能降低速度. 可以在配置文件中对每个主机单独设定这个参数. 另见 Compression 选项.
-F configfile
指定一个用户级配置文件. 如果在命令行上指定了配置文件, 系统级配置文件 (/etc/ssh/ssh_config ) 将被忽略. 默认的用户级配置文件是 $HOME/.ssh/config
-L port:host:hostport
将本地机(客户机)的某个端口转发到远端指定机器的指定端口. 工作原理是这样的, 本地机器上分配了一个 socket 侦听 port 端口, 一旦这个端口上有了连接, 该连接就经过安全通道转发出去, 同时远程主机和 host 的 hostport 端口建立连接. 可以在配置文件中指定端口的转发. 只有 root 才能转发特权端口. IPv6 地址用另一种格式说明: port/host/hostport
-R port:host:hostport
将远程主机(服务器)的某个端口转发到本地端指定机器的指定端口. 工作原理是这样的, 远程主机上分配了一个 socket 侦听 port 端口, 一旦这个端口上有了连接, 该连接就经过安全通道转向出去, 同时本地主机和 host 的 hostport 端口建立连接. 可以在配置文件中指定端口的转发. 只有用 root 登录远程主机 才能转发特权端口. IPv6 地址用另一种格式说明: port/host/hostport
-D port
指定一个本地机器 ``动态的 应用程序端口转发. 工作原理是这样的, 本地机器上分配了一个 socket 侦听 port 端口, 一旦这个端口上有了连接, 该连接就经过安全通道转发出去, 根据应用程序的协议可以判断出远程主机将和哪里连接. 目前支持 SOCKS4 协议, 将充当 SOCKS4 服务器. 只有 root 才能转发特权端口. 可以在配置文件中指定动态端口的转发.
-1
强制 只使用协议第一版.
-2
强制 只使用协议第二版.
-4
强制 只使用 IPv4 地址.
-6
强制 只使用 IPv6 地址.
基本用法
最简单的 SSH 命令只需要指定用户名和主机名参数即可. 主机名可以是 IP 地址或者域名. 命令格式如下:
复制代码代码如下:
$ ssh user@hostname
比如要在我的局域网内登录一个树莓派系统, 只需要简单的在命令行输入如下命令:
复制代码代码如下:
$ ssh pi@10.42.0.47
命令中的 pi 和 10.42.0.47 分别是我的树莓派系统的用户名和局域网 IP 地址. 实际使用时主机名需要改成你的目标主机(局域网内或者远程)的 IP 地址.
如果你能够成功登陆, 那么下面的内容对你来说就轻而易举了.
使用其他端口
SSH 默认连接到目标主机的 22 端口上,但是由于各种原因你可能需要连接到其他端口.
复制代码代码如下:
$ ssh -p 10022 user@hostname
如上命令就是通过添加参数 -p 指定端口号为 10022.远程执行命令
有时在远程主机执行一条命令并显示到本地, 然后继续本地工作是很方便的. SSH 就能满足这个需求:
复制代码代码如下:
$ ssh pi@10.42.0.47 ls -l
比如上面这个命令就会枚举远程主机的主目录内容并在本地显示. 是不是很酷? 你可以尝试下其他命令看看.
挂载远程文件系统
另外一个很赞的基于 SSH 的工具叫 sshfs. sshfs 可以让你在本地直接挂载远程主机的文件系统.
复制代码代码如下:
$ sshfs -o idmap=user user@hostname:/home/user ~/Remote
比如下面这条命令:
复制代码代码如下:
$ sshfs -o idmap=user pi@10.42.0.47:/home/pi ~/Pi
该命令就将远程主机 pi 用户的主目录挂载到本地主目录下的 Pi 文件夹.要详细了解可以参考 sshfs 教程.
X11 图形界面
假如现在你想要在远程主机运行一个图形界面的程序, SSH 已经帮你想到了! 用前面提到的 SSH 基本命令加上参数 -X 连接到远程主机即可开启 X11 转发功能. 登录后你可能觉得没什么差别, 但是当你运行一个图形界面程序后就会发现其中的不同的.
复制代码代码如下:
$ ssh -X pi@10.42.0.47
$ pistore
如果你想在运行图形界面程序的同时做些别的事情, 只需要简单地在命令末尾加一个 & 符号.
复制代码代码如下:
$ pistore&
转义字符
SSH 提供了多样的转义字符功能. 用 SSH 连接到任意一台远程主机然后输入 ~? 你就可以看到支持的转义字符和功能说明列表. 以下例子展示了 ~# 和 ~C 的效果.
配置 SSH
如果你需要改变 SSH 的配置, 请用你喜好的文本编辑器打开 /etc/ssh/sshd_config 进行编辑. 比如你想改变登陆的标语, 在配置文件中找到下面这行:
复制代码代码如下:
#Banner none
删除 # 字符(取消该行的注释), 将 none 替换为包含你期望显示内容的文件地址. 修改后该行应该类似这样:
复制代码代码如下:
Banner /etc/issue
在配置文件 /etc/ssh/sshd_config 中你还可以找到端口号, 空闲超时时间等配置项. 配置项大都比较容易理解, 但是保险起见在你修改一些不是很确定的配置项时最好参考下 SSH 的帮助文档.构建 ssh 密钥对
运行以下命令创建密钥对:
复制代码代码如下:
$ ssh-keygen -t dsa
此命令会要求你输入密码(可以留空), 然后就会生成密钥并会显示一张该密钥对应的随机图.
寻找主机密钥
在你准备添加密钥之前不妨先用以下命令看看是否已经添加了对应主机的密钥了.
复制代码代码如下:
$ ssh-keygen -F 10.42.0.47
删除主机密钥
某些情况下, 比如主机地址更改或者不再使用某个密钥, 你就可能需要删除某个密钥.
复制代码代码如下:
$ ssh-keygen -R 10.42.0.47
用以上命令就可删除. 这比手动在 ~/.ssh/known_hosts 文件中删除要方便很多.
总结
通过以上的内容你应该可以轻松使用 SSH 了. SSH 还有很多功能值得你去发掘, 这就要看你的想象力了。