写点什么

SSH 的工作原理、加密方式以及配置多个 ssh key

作者:甜点cc
  • 2022-10-31
    河南
  • 本文字数:3696 字

    阅读完需:约 12 分钟

1、SSH 工作原理

从 ssh 的加密方式说开去,看下文👇

1.1、对称加密

客户端和服务端采用相同的密钥进行数据的加解密,很难保证密钥不丢失,或者被截获。隐藏着中间人攻击的风险


如果攻击者插在用户与远程主机之间(比如在公共的 wifi 区域),用伪造的公钥,获取用户的登录密码。再用这个密码登录远程主机,那么 SSH 的安全机制就不存在了。这种风险就是著名的"中间人攻击"(Man-in-the-middle attack


为了解决对称加密的漏洞,就出现了非对称加密。非对称加密有两个密钥:“公钥”和“私钥”。公钥加密后的密文,只能通过对应的私钥进行解密。想从公钥推理出私钥几乎不可能,所以非对称加密的安全性比较高。

1.2、非对称加密

ssh 连接远程 git 仓库时的登录验证原理:本地主机向远程主机发送登录请求,远程主机收到请求后,返回给本地主机一个随机字符串 A,本地主机用私钥加密字符串 A 得到密文 B,并把密文 B 发送给远程主机,远程主机用公钥解密密文 A 得到字符串 B,并判断 A 是否等于 B,如果相等,则认证成功,反之,则反之。不在要求使用密码登录,以公私钥的方式实现免密登录


1.3、基于口令和公钥认证

只有在第一次连接的时候需要,通信双方验证身份之后就可以通过在客户端的私钥和你存放在服务器的公钥进行认证。(通过服务器上的公钥加密,客户端的私钥解密来验证)


第一次登录:


如果不是第一次登录,想看一下效果的话,可以修改一下本地的 ~/.ssh/known_hosts 文件名(~/.ssh/known_hosts文件中保存的是已经认证过的公钥信息),重命名该文件之后,相当于清空了认证过的公钥信息,再次连接的时候就会重新认证😁😁


  1. ssh 连接远程主机


$ git clone git@gitcode.net:xxx.gitCloning into 'xxx'...The authenticity of host 'gitcode.net (119.3.229.170)' can't be established.RSA key fingerprint is SHA256:pyrMa3p0o90Qsuz2+kMX3CIBl+S1cZsdRlCoaosSg00Qs.Are you sure you want to continue connecting (yes/no/[fingerprint])?yesWarning: Permanently added 'gitcode.net,119.3.229.170' (RSA) to the list of known hosts.
复制代码


  1. 查看 known_hosts 文件


# 查看known_hosts文件$ cat known_hostsgitcode.net,119.3.229.170 ssh-rsa AAAAB3NzaC1yc2EAAAL......
复制代码


  • 因为公钥长度较长(采用RSA算法),很难比对,所以对其进行MD5计算,将它变成一个 128 位的指纹,如上fingerprint,这样比对就容易多了。

  • 当远程主机的公钥被接受以后,它就会被永久保存在文件 ~/.ssh/known_hosts 文件之中,下次再登录就会跳过Warning部分



上图来源网络,侵删


下面以多个主机配置ssh连接时怎么指定使用哪个公钥为切入点,讲解ssh config。讲透、看明白!

2、多个代码仓库配置 ssh 连接问题

SSH 是连接远程主机最常用的方式,尽管连接到单个主机的基本操作非常直接,但当你开始使用大量的远程系统时(比如:配置多个代码托管平台的 ssh),这就会成为笨重和复杂的任务。


幸运的是,OpenSSH 允许您提供自定义的客户端连接选项。这些选项可以被存储到一个配置文件中,这个配置文件可以用来定义每个主机的配置。这有助于保持每个主机的连接选项更好的独立和组织,也让你在需要连接时避免在命令行中写繁琐的选项。


目前我使用的代码托管平台有GitHub、Gitee、Gitlab、Gitcode(瞎折腾👀),即使只使用一个平台,比如 gitlab,也会存在公司账号跟个人账号的 ssh 配置问题,下面讲解 ssh 连接远程主机时怎么指定使用哪个公钥


下面展示都在 Windows 系统下

3、ssh config 自定义主机配置

3.1、ssh config 介绍

解决多个 ssh 密钥使用问题的最佳方案就是通过维护一个本地配置 config,指定主机使用哪个密钥。


其他方案:(需要连接的主机多了同样很难管理,不建议使用,了解即可)

  1. 设置环境变量GIT_SSH_COMMAND解决

  2. 指定命令行参数:ssh -i ~/.ssh/xxx.pub -p 22 www.example.com


用户级设置的路径: ~/.ssh/config

3.1.1、文件格式

Host firsthost    SSH_OPTIONS_1 custom_value    SSH_OPTIONS_2 custom_value    SSH_OPTIONS_3 custom_value
Host secondhost ANOTHER_OPTION custom_value
Host *host ANOTHER_OPTION custom_value
# 公用配置在最下面Host * CHANGE_DEFAULT custom_value
复制代码


解释:Host:ssh 连接主机的别称 alias

3.1.2、尝鲜一下

本地系统的每个用户都可以维护一个客户端的 SSH 配置文件,这个配置文件可以包含你在命令行中使用 ssh 时参数,也可以存储公共连接选项并在连接时自动处理。你可以在命令中使用 ssh 来指定 flag ,以覆盖配置文件中的选项。看一个例子:


  • ssh 命令行的方式:


ssh -i ~/.ssh/xxx -p 22 -l admin \ www.example.com
复制代码


上面的命令可以转换成 config 的形式,如下:


  • ssh/config 定义主机连接参数配置


Host myserver1  Hostname www.example.com  # User admin  Port 22  IdentityFile ~/.ssh/xxx
# 公共配置, 必须在文件最下面Host * User admin
复制代码

3.2、解释算法

它从文件顶部向下执行此操作,所以顺序非常重要,了解这个之后,方便我们写出更好的主机定义配置选项、方便运维管理。


当匹配到第一个主机定义时,并不会终止,而是继续往下查找,检查是否有其他匹配的 Host 定义。如果有另一个 Host 定义匹配,SSH 将该 Host 定义下的配置选项跟前面匹配到的主机定义配置选项合并(随着继续往下读取配置,最终配置选项是叠加的

3.3、ssh_config 的工作原理✨

3.3.1、ssh 客户端按以下顺序从三个地方读取配置:

  1. 系统范围内 /etc/ssh/ssh_config(适用于主机下的所有用户,系统级 System)

  2. 用户特定的 ~/.ssh/config (用户级)

  3. ssh 直接提供给的命令行标志 (命令参数可以重写已有的固定配置)


我通常使用的用户级的配置,下面是我个人的配置,仅供参考:


# gitcode - csdnHost gitcode.net  HostName gitcode.net  Preferredauthentications publickey  IdentityFile ~/.ssh/gitcode
# gitlabHost gitlab.com HostName gitlab.com IdentityFile ~/.ssh/gitlab-rsa
# githubHost github.com HostName github.com IdentityFile ~/.ssh/id_rsa
# giteeHost gitee.com HostName gitee.com IdentityFile ~/.ssh/id_rsa
# 共享配置,文件最下面Host * # 认证方式首选 publickey(公钥), 可选: publickey,gssapi-keyex,gssapi-with-mic,password PreferredAuthentications publickey User git # ssh [Host] === ssh [User]@[HostName]
复制代码


解释:


  • Host:ssh 的别称

  • 比如 Host 设置成 xiao ,使用的时候 ssh xiao(注意设置 User)

  • HostName: 服务器的地址

  • PreferredAuthentications : 认证方式

  • 可选: publickey,gssapi-keyex,gssapi-with-mic,password

  • IdentityFile: 指定连接 HostName 的密钥文件的路径

3.3.2、主机别名设置例子

Host dev1    HostName dev1.example.com    User jeery
复制代码


现在要连接到 jeery@dev1.example.com,就可以通过在命令行中输入如下命令:


ssh dev1
# 相当于ssh jeery@dev1.example.com
复制代码

3.3.3、git 仓库连接别名设置例子

3.4、连接问题

PS C:\Users\xiao\.ssh>vim .\configPS C:\Users\xiao\.ssh>ssh -T git@gitcode.netBad owner or permissions on C:\\Users\\xiao/.ssh/configPS C:\Users\xiao\.ssh>
复制代码


解决:


修改 config 文件 权限


cd ~/.ssh/chmod 600 config
复制代码

4、git 仓库设置 ssh 连接

下面演示我的设置步骤,仅供参考

4.1、本地生成公私钥对

ssh-keygen -o -t rsa -C "yourmail" -b 4096
复制代码


🔊 记得设置key的名字哟,默认是 id_rsa(如果不设置key,新生成的 id_rsa 文件会覆盖原有的id_rsa文件,之前添加过的就不能用啦!),参考下图👇


4.2、配置远程主机 ssh

登录要连接的远程主机,这里演示 gitcode 平台


4.3、设置 ssh_config

这里我统一维护在 ~/.ssh/config里面维护,增加gitcode主机定义配置, 如下:


# gitcode - csdnHost gitcode.net  HostName gitcode.net  IdentityFile ~/.ssh/gitcode
# 共用配置,文件最下面Host * # 认证方式首选 publickey(公钥), 可选: publickey,gssapi-keyex,gssapi-with-mic,password PreferredAuthentications publickey User git # ssh [Host] === ssh [User]@[HostName]
复制代码

4.4、测试连接

xiao@LAPTOP-L6TI0438 MINGW64 ~/.sshssh -T gitagitcode.netWelcome to GitLab,@heyYouU!xiao@LAPTOP-L6TI0438 MINGW64 ~/.ssh
复制代码

最后

相信看完上面的讲解,会对 ssh 理解的更清除一点。So,快来更换 ssh 试试吧


连接远程仓库可以选择 https,也可以选择 ssh


区别:


  1. https 连接有文件传输大小限制,ssh 没有

  2. ssh 传输速度比 https 协议快

  3. https 连接提交代码的时候需要输入账户密码登录,ssh 则是以公私钥加解密随机数的方式免密登录


连接仓库的方式可以转换,如: https 转成 ssh,比较简单,不作介绍。


SSH 东西超多的,光 SSH 配置选项就几十个,本文抛砖引玉,大家可以继续往下探索🎉🎉




我是 甜点 cc


热爱前端开发,也喜欢专研各种跟本职工作关系不大的技术,技术、产品兴趣广泛且浓厚。本号主要致力于分享个人经验总结,希望可以给一小部分人一些微小帮助。


希望能和大家一起努力营造一个良好的学习氛围,为了个人和家庭、为了我国的互联网物联网技术、数字化转型、数字经济发展做一点点贡献。数风流人物还看中国、看今朝、看你我。

发布于: 刚刚阅读数: 5
用户头像

甜点cc

关注

微信公众号:看见另一种可能 2020-04-30 加入

https://blog.i-xiao.space/

评论

发布
暂无评论
SSH的工作原理、加密方式以及配置多个ssh key_前端_甜点cc_InfoQ写作社区