ssh 相关概念及命令

ssh related concepts and commands

Posted by Randle on July 31, 2019

ssh

Secure Shell (SSH) 是一个允许两台电脑之间通过安全的连接进行数据交换的网络协议。通过加密保证了数据的保密性和完整性。SSH采用公钥加密技术来验证远程主机,以及(必要时)允许远程主机验证用户。

ssh client/server

OpenSSH (OpenBSD Secure Shell) 是一套使用ssh协议,通过计算机网络,提供加密通讯会话的计算机程序。如果需要作为ssh的服务端,则需要安装openssh。如果仅是作为ssh客户端,在Linux中直接使用ssh命令即可。

ssh-key

SSH 密钥对 最直观的作用:让你方便的登录到 SSH 服务器,而无需输入密码。由于你无需发送你的密码到网络中,SSH 密钥对被认为是更加安全的方式。

原因是:SSH 利用 SSH Key来进行前面提到的基于密钥的安全验证。

使用 ssh 的步骤

  1. 在客户端生成SSH key(密钥对:公钥和私钥).
  2. 在服务端的配置文件中加入你的公钥。(比如我们需要在GitHub中粘贴你的公钥)

生成ssh秘钥对通过ssh-keygen实现。

ssh-keygen

ssh-keygen命令用于为ssh生成、管理和转换认证密钥,它支持RSA和DSA两种认证密钥。

该命令的选项有:

1
2
3
4
5
6
7
8
9
10
-b:指定密钥长度;
-e:读取openssh的私钥或者公钥文件;
-C:添加注释;
-f:指定用来保存密钥的文件名;
-i:读取未加密的ssh-v2兼容的私钥/公钥文件,然后在标准输出设备上显示openssh兼容的私钥/公钥;
-l:显示公钥文件的指纹数据;
-N:提供一个新密语;
-P:提供(旧)密语;
-q:静默模式;
-t:指定要创建的密钥类型。

生成密钥对时,有一个选项要求你设置密码(passphrase),该密码是用来保护你的私钥的密码。如果设置了则在使用私钥时会要求你输入这个密码;一般不设置,记不住【之后还可更改此密码,使用ssh-keygen -p】。

生成后最好将私钥进行备份。另还有-C选项,用于为指定注释,通常使用自己的邮件名作为注释。

示例:为了安全考虑使用RSA加密方式并指定密钥长度-b 2048(1024的密钥长度能够被破解,建议指定为2048或4096)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
$ ssh-keygen -t rsa -C "Fan@outlook.com" -b 2048
Generating public/private rsa key pair.
Enter file in which to save the key (/home/fan/.ssh/id_rsa): /home/fan/.ssh/FDGitHub_rsa
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /home/fan/.ssh/FDGitHub_rsa.
Your public key has been saved in /home/fan/.ssh/FDGitHub_rsa.pub.
The key fingerprint is:
SHA256:GcK7ORvFzH6fzA7qPmnzBr1DOWho5cCVgIpLkh6VGb8 Fan@outlook.com
The key's randomart image is:
+---[RSA 2048]----+
|   .+... .       |
|   +o.  o        |
| o.. oo..        |
|+o.   +*.o       |
|+..  E.=So .     |
|..    o== =      |
|     .=..+oo     |
|       +=o+= .   |
|      .++=.o*    |
+----[SHA256]-----+

公钥是一串很长的字符;为了便于肉眼比对和识别,所以有了指纹这东西;指纹位数短,更便于识别且与公钥一一对应。

公钥加密指纹fingerprint有两种形式:

  • 之前的十六进制形式:16:27:ac:a5:76:28:2d:36:63:1b:56:4d:eb:df:a6:48
  • 现在使用sha256哈希值并且使用base64进行编码:SHA256:nThbg6kXUpJWGl7E1IGOCspRomTxdCARLviKw6E5SY8

指纹的用处之一是在使用SSH第一次连接到某主机时,会返回该主机使用的公钥的指纹让你识别。示例:

1
2
3
The authenticity of host '某主机名' can't be established.
RSA key fingerprint is SHA256:nThbg6kXUpJWGl7E1IGOCspRomTxdCARLviKw6E5SY8.
Are you sure you want to continue connecting (yes/no)?

公钥用于给别人用来加密文件。公钥就是一把锁,你把锁给别人,他用锁锁住东西后,除了你自己外其他人是没有钥匙(私钥)的,都无法打开。配对的私钥就是钥匙。

必须保证使用你的公钥的人明确知道这个公钥一定是你的。你可以在网站或通过其它方式公布你的公钥,以便他人进行对照确认。由于公钥很长,所以有了对应的指纹(指纹更易辨别,位数更少),可以通过指纹进行对照(公布指纹)。

对于生成的公钥,可以通过下面的命令生成对应的指纹:

1
ssh-keygen -E md5 -lf id_rsa.pub

其中的-E指定生成指纹的类型,可以通过ssh-keygen --help查询其支持的选项。(“md5” and “sha256”. The default is “sha256”.)

为不同服务器的同一用户配置不同SSH key

访问不同的服务器时,用不同的秘钥对的配置方法。

比如:你在GitLab上粘贴的公钥(Public SSH keys)不是默认的密钥对;此时要想让你的ssh client正常与GitLab服务器通信,必须对ssh client进行配置,当通信对象为GitLab服务器主机时,使用哪个私钥(SSH private key)。

对于OpenSSH客户端(Linux默认安装),需要在 ~/.ssh/config 文件中进行配置(如果没有该文件则自行创建一个)。

1
2
3
4
5
6
7
8
9
10
# GitLab.com server
Host gitlab.com
# 如果提示: Unsupported option "rsaauthentication",则可以选择注释掉该行
RSAAuthentication yes
IdentityFile ~/.ssh/private-key-filename-01

# Private GitLab server
Host gitlab.company.com
RSAAuthentication yes
IdentityFile ~/.ssh/private-key-filename

配置完成后可以使用如下命令测试连接:

1
2
3
4
5
6
# 测试时替换掉 example.com
ssh -T git@example.com
# 例如 gitlab
ssh -T git@gitlab.com
# 例如 github
ssh -T git@github.com

配置多个账户

譬如在github上拥有多个账号,可以分别配置秘钥对,配置方法如下:

1
2
3
4
5
6
7
8
9
10
11
# coding
Host git.coding.net
User your_email@example.com
PreferredAuthentications publickey
IdentityFile ~/.ssh/id_rsa  //默认的私钥

# second
Host git.coding.net
User youre_secondemail@example.com
PreferredAuthentications publickey
IdentityFile ~/.ssh/second_rsa  // 生成的第二个私钥

ssh-agent

ssh-agent命令是一种控制用来保存公钥身份验证所使用的私钥的程序。在Linux中ssh-agent 在X会话或登录会话之初启动,所有其他窗口或程序则以客户端程序的身份启动并加入到ssh-agent程序中。通过使用环境变量,可定位代理并在登录到其他使用ssh机器上时使用代理自动进行身份验证。

下面两种情况,我们需要ssh代理:

  1. 使用不同的秘钥连接到不同的主机,需要手动指定对应的秘钥。
  2. 当私钥设置了密码,又需要频繁使用私钥进行认证,ssh代理可以免去重复的输入密码。

使用 ssh-agent 管理秘钥,需要将秘钥添加到代理中:

1
ssh-add ~/.ssh/id_rsa_custom

ssh-agent可以免去手动指定秘钥的过程,选择对应的私钥认证。

对于配置了密码的私钥,在添加到 ssh-agent 的时候,需要输入密码,在后续认证的过程中,不需要输入密码。

管理ssh代理中的私钥

通过 ssh-add命令可以管理添加到代理总的私钥。

1
2
3
4
5
6
ssh-add -l		# 列出已管理的私钥
ssh-add -L		# 列出对应的公钥
ssh-add -d $dir	# 移除私钥
ssh-add -D		# 清空所有私钥
ssh-add	-x		# 对代理加锁,需输入密码
ssh-add -X		# 对代理解锁,需输入对应密码

ssh-agent 有不同的软件实现:

  • ssh-agent 是 OpenSSH 自带的一个 SSH agent
  • GnuPG agent也许想要 GnuPG 来缓存您的私钥。当然咯,有些用户比较喜欢在 GnuPG 对话框来输入 PIN 码,这样子管理密码短语也是不错的选择。

manual

除了前文中描述的使用ssh-agent的方式外,还可以在命令行中为ssh指定私钥,登录远程主机。

1
ssh -i .ssh/id_rsa root@remote_host

配置ssh免密登录

将本机的公钥配置到远端服务器中,可以实现免密登录。可以有两种方法:

1
$ ssh-copy-id -i .ssh/id_rsa.pub USER_NAME@USER_ADDRESS

另外一种方法是:

  1. 将公钥手动拷贝到服务器;
  2. 将公钥内容追加到.ssh/authorized_keys:
1
$ cat id_rsa.pub >> .ssh/authorized_keys

参考资料

  • https://www.jianshu.com/p/1246cfdbe460
  • http://www.zsythink.net/archives/2407/
  • http://man7.org/linux/man-pages/man1/ssh-agent.1.html
  • https://superuser.com/questions/421997/what-is-a-ssh-key-fingerprint-and-how-is-it-generated