利用 SSH 的用户配置文件 Config 管理 SSH 会话
通常我们如果需要连接远程服务器,一般都会是下面的命令:
1 |
|
但是如果我们有许多台服务器,而且需要记住很多的密码,非常的繁琐。
幸好ssh
提供了一个非常优雅的方式来解决这个问题。那就是通过配置ssh
的配置文件config
来管理ssh
会话。
使用SSH配置文件
ssh 配置文件一般分为两种:
- 用户的配置文件,一般在
${HOME}/.ssh/config
, 如果该文件不存在,可以手动创建。 - 系统全部用户的配置文件,一般在
/etc/ssh/ssh_config
。
配置文件可分为多个配置区段,每个配置区段使用”Host”来区分。我们可以在命令行中输入不同的Host来加载不同的配置段。
配置项
Host
别名HostName
主机名Port
端口User
用户名IdentityFile
密钥文件的路径IdentitiesOnly
只接受SSH key 登录PreferredAuthentications
强制使用Public Key
验证
示例:
1 |
|
然后,就可以直接用一下命令登录:
1 |
|
但是,对于我这种在自己电脑上,不想输入密码,直接输入别名就可以登录可不可以呢,也是可以的。这里就需要介绍一下ssh远程登录的流程:
SSH 远程登录的流程
当本机发起登录请求时,SSH 会依次执行以下几个主要步骤:
- 通过远程主机公钥 hash,确认远程主机身份;
- 若通过,远程主机验证登录身份,例如:提示输入远程主机目标用户的口令;
- 本地主机将用户键入的口令,使用远程主机的公钥加密,并发送给远程主机;
- 远程主机使用上述公钥对应的私钥,对得到的密文进行解密;
- 远程主机验证解密后的口令;
- 若通过,则建立 SSH 连接,成功登录。
下面我们来验证这一过程,我们通过ssh来登录一下本机:
1 |
|
ssh提会示我们验证远程主机的身份,翻译一下大概就是:
1 |
|
我们直接输入yes,回车:会出现下面警告
1 |
|
为了下次自动地验证远程主机的身份,本地主机会将远程主机的公钥指纹保存下来。新出现的提示,翻译如下。
1 |
|
在输入远程主机目标用户的口令之后(无终端回显),本地主机会将输入的口令以远程主机提供的密钥加密并发送给远程主机。待远程主机解密并验证通过后,即提示成功登录。
那么,具体来说,本地主机将这一信息保存在哪里了呢?答案是当前用户的 ${HOME}/.ssh/known_hosts
文件当中。我们可以执行 exit 命令,退出远程主机;而后使用 cat 命令可以查看${HOME}/.ssh/known_hosts
的中远程主机信息。如下图:
使用公钥验证身份
现在我们考虑下一个问题:除去输入远程主机用户口令的方式,是否还有其他方式能够验证登录者的身份?
对于身份认证来说,通常有三种手段:
- 你知道的(例如账户口令);
- 你独有的(例如网银的 U 盾);
- 你身上的(例如指纹)。
在 SSH 协议中,信道的安全是通过非对称加密保证的。事实上,非对称加密需要持有私钥。因此,私钥这件事情本身,也可以认为是一种「你独有的」东西。考虑到,在 SSH 登录成功之前,在不完整的信道中,从本地主机向远程主机通信是安全的(因为有远程主机的公钥可用于加密),而远程主机可以用持有的私钥解密本地主机发来的信息。(例如口令登录验证的过程)。类似的过程也可以反过来用:
- 本地主机生成一对非对称密钥;
- 本地主机将公钥交付远程主机;
- 远程主机在收到登录请求时,使用上述公钥加密一串无害的随机信息;
- 本地主机将接收到的密文,以本地持有的私钥解密,而后通过远程主机的公钥再进行加密;
- 远程主机使用相应私钥解密,并与上述随机信息进行比对;
- 若一致,则认可登录者的身份,许可登录。
在这个过程中,远程主机对比一来一回前后随机信息的一致性,验证了本地主机确实持有一个安全介质——本地主机生成的私钥。因此,这就不需要输入远程主机的用户口令了。
为此,我们首先需要生成一对密钥。
1 |
|
ssh-keygen
是 OpenSSH
的一部分,它用于生成供SSH
使用的密钥。默认情况下,ssh-keygen
生成的是 RSA
密钥(本机上是 2048 位 RSA
),并将私钥保存在 ${HOME}/.ssh/id_rsa
当中。为了避免与已有的密钥冲突,这里我们另存为 id_rsa.test
。随后,ssh-keygen
要求我们为生成的私钥设置口令(passphrase
)。这一口令是对私钥进行保护的口令,可以留空。这样一来,我们就生成了一对 RSA 密钥。其中,私钥保存在 /root/.ssh/id_rsa.test
而公钥保存在 /root/.ssh/id_rsa.test.pub
。
接下来,我们需要将生成的密钥交付给远程主机。为此,我们需要使用 ssh-copy-id
这一命令。
1 |
|
ssh-copy-id
会将 ~/.ssh/id_rsa.test
对应的公钥,交付给 root@www.example.com
。在这个过程中,我们需要输入用户 root
在远程主机 www.example.com
上的口令。注意,此处我们使用了 -i 参数,指定了需要交付的密钥。若是省略 -i 参数,则 ssh-copy-id 会将默认的密钥 ~/.ssh/id_rsa 对应的公钥交付给远程主机。
之后,我们就可以「免密登录」了。同样,我们需要使用 -i 参数指定所需使用的私钥。
1 |
|
类似上面提到过的 ~/.ssh/known_hosts
,保存这类公钥也有一个特定的文件:远程主机目标用户的 ${HOME}/.ssh/authorized_keys
。登录远程主机后,我们可以查看刚刚添加的公钥和我们生成的id_rsa.test.pub
是一样的。
若是你的机器不支持 ssh-copy-id,也可以直接将公钥信息写入远程主机目标用户的 ${HOME}/.ssh/authorized_keys 当中。
回到我们之前的问题,如果我们想免密登录的话,那么我们就需要在配置文件下新增一段,新增之后的配置文件为:
1 |
|
现在直接登录就可以使用ssh example
直接登录,不再输入密码。