先来了解什么是 SSH 和什么是 SSH key。
简单的说:Secure Shell(SSH)是一种网络协议,用于加密客户端和服务器之间的连接。
SSH
Secure Shell (SSH) 是一个允许两台电脑之间通过安全的连接进行数据交换 的网络协议。通过加密保证了数据的保密性和完整性。SSH 采用公钥加密技术 来验证远程主机,以及(必要时)允许远程主机验证用户。
传统的 FTP、Telnet 是再网络中明文传送数据、用户帐号和密码,很容易受到中间人攻击 。
SSH 是目前较可靠,专为远程登录会话和其他网络服务提供安全性的协议。利用 SSH 协议 可以有效防止远程管理过程中的信息泄露问题。通过SSH可以对所有传输的数据进行加 密,也能够防止 DNS 欺骗和 IP 欺骗。
ssh客户端(ssh) ssh服务端(sshd)
+----------+ +---------+
| | | |
| | | |
| | | |
| | | |
+---+---+--+ +-+---+---+
| | | |
| | | |
| +----------------------------+ |
| |
| ssh加密了的TCP通信 |
+------------------------------------+
SSH连接
在客户端来看,SSH 提供两种级别的安全验证:
- 第一种级别(基于密码的安全验证),知道帐号和密码,就可以登录到远程主机,并且所 有传输的数据都会被加密。但是,可能会有别的服务器在冒充真正的服务器,无法避免被 “中间人"攻击。
- 第二种级别(基 于密钥的 安全验证),需要依靠密钥,也就是你必须为自己创建一对密钥,并把公有密钥放在需 要访问的服务器上。客户端软件会向服务器发出请求,请求用你的密钥进行安全验证。 服务器收到请求之后,先在你在该服务器的用户根目录下寻找你的公有密钥,然后把它和 你发送过来的公有密钥进行比较。如果两个密钥一致,服务器就用公有密钥加密"质询 “(challenge)并把它发送给客户端软件。从而避免被"中间人"攻击。
在服务器端,SSH 也提供安全验证:
- 在第一种方案中,主机将自己的公用密钥分发给相关的客户端,客户端在访问主机时则使 用该主机的公开密钥来加密数据,主机则使用自己的私有密钥来解密数据,从而实现主机 密钥认证,确保数据的保密性。
- 在第二种方案中,存在一个密钥认证中心,所有提供服务的主机都将自己的公开密钥提交 给认证中心,而任何作为客户端的主机则只要保存一份认证中心的公开密钥就可以了。在 这种模式下,客户端必须访问认证中心然后才能访问服务器主机。
SSH 服务端和客户端程序
SSH 只是一种协议,其开源实现有 OpenSSH 程序。
OpenSSH (OpenBSD Secure Shell) 是一套使用 ssh 协议,通过计算机网络,提供加密 通讯会话的计算机程序。
如果需要作为 ssh 的服务端,则需要安装 openssh 程序。
如果仅是作为 ssh 客户端,在 Linux 中直接使用ssh
命令即可。
在 Windows 中的 ssh 客户端程序有:
- Putty
- PuTTY Tray(Putty 的加强版)
- Bitvise 的 ssh client (功能多,自带 sftp,免费) 推 荐
- Xshell (2017 年被爆多版本存在后门)
- SecureCRT(算了吧)
SSH Key
SSH 密钥对 最直观的作用:让你方便的登录到 SSH 服务器,而无需输入密码。由 于你无需发送你的密码到网络中,SSH 密钥对被认为是更加安全的方式。
原因是:SSH 利用 SSH Key 来进行前面提到的基于密钥的安全验证。
使用 SSH key 的步骤:
- 在客户端生成 SSH key(密钥对:公钥和私钥)
- 在服务端的配置文件中加入你的公钥。(比如我们需要再 GitHub 中粘贴你的公钥)
生成密钥对
ssh-keygen 命令用于为 ssh 生成、管理和转换认证密钥,它支持 RSA 和 DSA 两种认 证密钥。
该命令的选项:
|
|
生成密钥对时,有一个选项要求你设置密码(passphrase),该密码是用来保护你的私钥的
密码。如果设置了则在使用私钥时会要求你输入这个密码;一般不设置,记不住【之后
还可更改此密码,使用ssh-keygen -p
】。
生成后最好将私钥进行备份。
常用的两者加密方式:
- 为了安全考虑如果使用 RSA 加密方式则指定密钥长度为
-b 4096
(1024 的密钥长度能 够被破解,建议指定为 4096)。 - 但现在有了更安全的加密方式 ed25519 ,这是目前最受推荐的公钥算法。当使用
ed25519 加密方式时,它会忽略
-b
选项,因为它的长度是固定的。生成的密钥更紧凑 、更短(仅包含 68 个字符)、在签名验证时也更快并且还更安全。它还将使用新的 OpenSSH 格式(OpenSSH 6.5+)而不是 PEM 格式保存私钥,Windows10 中的 OpenSSH 最 先支持的也是 ed25519 类型的密钥。
使用 rsa 加密方式的示例:
|
|
使用 ed25519 加密方式生成密钥的示例:
|
|
公钥是一串很长的字符;为了便于肉眼比对和识别,所以有了指纹这东西;指纹位数短 ,更便于识别且与公钥一一对应。
公钥加密指纹 fingerprint 有两种形式:
- 之前的十六进制形式:
16:27:ac:a5:76:28:2d:36:63:1b:56:4d:eb:df:a6:48
- 现在使用 sha256 哈希值并且使用 base64 进行格式
:
SHA256:nThbg6kXUpJWGl7E1IGOCspRomTxdCARLviKw6E5SY8
指纹的用处之一是在使用 SSH 第一次连接到某主机时,会返回该主机使用的公钥的指纹让 你识别。示例:
The authenticity of host '某主机名' can't be established.
RSA key fingerprint is SHA256:nThbg6kXUpJWGl7E1IGOCspRomTxdCARLviKw6E5SY8.
Are you sure you want to continue connecting (yes/no)?
简单介绍一下:
公钥用于给别人用来加密文件。公钥就是一把锁,你把锁给别人,他用锁锁住东西后,除 了你自己外其他人是没有钥匙(私钥)的,都无法打开。配对的私钥就是钥匙。
必须保证使用你的公钥的人明确知道这个公钥一定是你的。你可以在网站或通过其它方式 公布你的公钥,以便他人进行对照确认。由于公钥很长,所以有了对应的指纹(指纹更易 辨别,位数更少),可以通过指纹进行对照(公布指纹)。
如何创建多个 ssh key 而不是覆盖默认文件
在创建 ssh key 时自行输入路径和文件名称,而非使用默认路径和文件名即可。
或者使用 -f
来指定文件名
ssh-keygen -t rsa -C "[email protected]" -f ~/.ssh/second-rsa
使用非默认的 SSH key
对于 OpenSSH 客户端(Linux 默认安装),需要在 ~/.ssh/config
文件中进行配置。
分为如下两种情况。
1.为不同服务器的同一用户配置不同 SSH key
这里同一用户在不同服务器上可以使用同一个 SSH key
Working with non-default SSH key pair paths
比如:你在 GitLab 上粘贴的公钥(Public SSH keys)不是默认的密钥对;此时要想让你的 ssh client 正常与 GitLab 服务器通信,必须对 ssh client 进行配置,当通信对象为 GitLab 服务器主机时,使用哪个私钥(SSH private key)。
注意:这里使用公钥也是可以的
示例:
|
|
**对于 GitLab 等:**上传到 GitLab 服务器中的 SSH 公钥只能属于单个用户,你的 SSH 密钥是您通过 SSH 推送代码时的标识符;它需要唯一映射到单个用户。也就是说,一个 公钥在该服务器上只能被一个账户使用;但是你可以在不同的服务器上使用同一个密钥对, 也可以在不同服务器上分别使用不同的密钥对 。
GitHub 使用非默认密钥对:
|
|
配置完成后可以使用如下命令测试连接:
|
|
如果测试时出现如下提示:
Unsupported option "rsaauthentication"
,则可以选择 忽略或注释掉配置文件中的RSAAuthentication yes
行。
2.配置多个账户
为同一服务器配置不同账户,比如说你在 coding 上有两个账户,那么可以这样在 config 文件中配置:
|
|
配置好之后,如果不能正常运行,需要将下面的内容添加到 .bashrc
文件中
|
|
SSH agent
ssh agent ,意为 ssh 代理,是一个密钥管理器,用来管理一个多个密钥。
另见我的 ssh-agent
Github/GitLab 中为什么会用到 SSH?
Using the SSH protocol, you can connect and authenticate to remote servers and services. With SSH keys, you can connect to GitHub without supplying your username or password at each visit.
使用 SSH 协议,您可以连接和验证远程服务器和服务。
使用 SSH 密钥,您可以连接到 GitHub,而无需在每次访问时提供用户名或密码。
与 Github 主机进行通信的两种方式
访问远程仓库时可以选择 SSH 或者 HTTPS 协议进行访问。
(比如,与 gitlab 远程仓库进行进行安全认证可选择使用 ssh 或者 https),两者的表现 形式:
SSH [email protected]:faner/test01.git
HTTPS https://gitlab.com/faner/test01.git
当你选择 HTTPS 时,会看到它有下面的一段提示"Create a personal access token on your account to pull or push via Https"简单的翻译一下就是"在您的帐户上创建个人 访问令牌,以通过 Https 进行 pull 或 push”,并且在你第一次将本地仓库 push 到远 程仓库时会要求你输入 gitlab 的用户名和密码。
GitHub/GitLab 中导入 SSH Key
SSH Key 导入 :导入过程比较简单。
GitHub: 点击用户头像 > Setting > SSH and GPG keys > New SSH key > 粘贴你生成的 公钥(简单的方法是用文本编辑器打开公钥文件然后复制)。
那么现在您已经设置了 SSH 密钥,在下次克隆存储库时可以使用 SSH 的 URL。如果您已经 拥有通过 HTTPS 克隆的存储库,可以将存储库的远程 URL 更改为其 SSH URL 。
问题:生成 ssh key 所使用的邮箱是否需要和本地 git 设置的邮箱相同?
本地 git 中配置的用户名和邮箱会随同提交日志被公开到 GitHub 上,而非生成 ssh key 时使用的邮箱(两者之间没有必然关系)。
参考
- https://zh.wikipedia.org/wiki/Secure_Shell
- https://help.github.com/articles/connecting-to-github-with-ssh/
- https://gitlab.com/help/ssh/README.md
- https://coding.net/help/doc/account/ssh-key.html
- http://www.ruanyifeng.com/blog/2011/12/ssh_remote_login.html
- http://www.ruanyifeng.com/blog/2011/12/ssh_port_forwarding.html
- https://www.ssh.com/ssh
- SSH keys - ArchWiki
- Upgrade Your SSH Key to Ed25519 - risan - Medium
- Using Ed25519 for OpenSSH keys (instead of DSA/RSA/ECDSA) - Linux Audit