8

SSH 公钥登录配置详解(iTerm2 为例)

 2 years ago
source link: https://jiayu0x.com/2017/11/22/ssh-pubkey-auth/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

SSH 公钥登录配置详解(iTerm2 为例)

Posted on 2017-11-22

| In system

| 3 Comments

SSH 服务的远程登录服务方式,通常有密码登录公钥登录两种。公钥登录方式的好处就不赘述了,本文详解 SSH 公钥登录的配置过程,以及其中常见的坑。
Note:本文所有实验均在 Mac 下的 iTerm2 中操作。

配置单个主机的 SSH 公钥登录,步骤非常简单,三步即可:

  1. 生成密钥对
  2. 拷贝公钥文件到服务器
  3. SSH 直接公钥登录服务器

ssh-keygen 生成密钥对

ssh-keygen 命令可以按照指定的参数生成密钥对,其常用的参数有以下几个:

-t : 加密算法,可选 [dsa | ecdsa | ed25519 | rsa];
-b :密钥长度(256/512/1024/2048……),建议至少1024;
-f : 输出的密钥对文件名;
-N :密钥口令。

比如我要为 test 主机生成一对密钥文件,密钥长度 2048、加密算法 RSA,就可以用以下命令:

~ ➜ ssh-keygen -f test -t rsa -b 2048

执行此命令会提示 Enter passphrase (empty for no passphrase):,如果需要密钥口令,就要填上并记下来,如果不需要就直接摁回车键直到结束。命令执行完成后,会在当前目录生成两个文件:私钥文件 test 和 公钥文件 test.pub 。如果不指定 ssh-keygen 命令的 -f 参数,则会默认生成 ~/.ssh/id_ras~/.ssh/id_ras.pub 两个文件 。

ssh-copy-id 拷贝公钥到服务器

ssh-copy-id 命令负责把上述步骤生成的公钥文件内容拷贝到服务器,确切说,是把 xxx.pub 文件中的内容附加到服务器端的 ~/.ssh/authorized_keys 文件中。

ssh-copy-id 命令使用方式如下:

~ ➜ ssh-copy-id [-i <identityfile>] [-p <port>] [username@]hostname

其中 -i 即指定上述步骤生成的密钥对中的 公钥文件,意思是把公钥文件 xxx.pub 传到服务端 hostname,把 xxx.pub 中的内容附加到 hostname:/home/username/.ssh/authorized_keys 文件中。如果不用 -i 指定公钥文件,则默认指定 id_ras.pub

举例来说,我想通过公钥登录我 192.168.1.2 上的 jiayu 账户,那么只需把上述步骤中生成的 test.pub 文件上传到该服务器即可:

~ ➜ ssh-copy-id -i test [email protected]

运行这条命令会让输入一次账户密码,然后才能成功上传到服务端。

另外,还有好多人在这一步会舍弃 ssh-copy-id 命令,转而手动上传公钥文件到服务端,然后 cat xxx.pub >> ~/.ssh/authorized_keys ,个人不提倡这种做法, ssh-copy-id 这条专用命令就是为了免去麻烦又容易失误的手动操作。

直接登录远程服务器

经过上面两步骤,没什么意外的话就可以用密钥登录远程服务器了。不过这里还有个小细节需要说一下,我们平时用密码 SSH 登录远程服务器,是用 ssh username@host -p <port> 命令然后输入密码。如果我们只有一台远程服务器需要用 SSH 公钥登录的方式,那么最初执行 ssh-keygen 命令的时候就可以不指定 -f 参数,默认生成密钥对文件 id_ras/id_isa.pub ,然后执行命令 ssh username@host -p <port> 不用输入密码即可登录,SSH 命令会默认调用 id_rsa 尝试连接。

但如果执行 ssh-keygen 命令的时候指定了 -f test 参数,那么这时要登录远程服务器就要在 SSH 命令中也指定私钥文件:

~ ➜ ssh -i test [email protected]

成功登录,配置完成,即可删除本地的公钥文件 xxx.pub,只留下相应的私钥文件。

有的朋友会发现,严格按照上述步骤操作,也无法成功连接服务端。此处常见的坑有 2 个:

  1. 服务端 ~/.ssh/ 目录和 ~/.ssh/authorized_keys 文件的权限问题;
  2. 服务端 ~/.ssh/authorized_keys 文件内容格式问题。

服务端相关目录和文件权限

个人见过的情况,把服务端 ~/.ssh/ 目录权限设置为 700 ,把 ~/.ssh/authorized_keys 文件权限设置为 600 即可。

authorized_keys 中 pubkey 内容要换行

有时候,服务端 SSH 目录和文件权限都没问题,仍然连接失败。此时给 SSH 命令启用 -v 选项打出连接时的详细信息,会发现客户机已经把私钥发送到服务器端,但在服务器端没有验证成功。

并且,在服务端的 SSH 服务日志 /var/log/secure 文件中可以查到类似以下内容的错误信息:

error: key_read: uudecode AAAAB3N failed

此时就是服务端 ~/.ssh/authorized_keys 文件内容格式出了问题。根源在于 ssh-copid 命令默认把公钥文件内容直接附加到服务端 authorized_keys 末尾,而没有换行

解决方案也很简单:Vim 打开服务端 ~/.ssh/authorized_keys 文件,为每个 pubkey 内容手动隔开一行即可。

配置多服务器多公钥登录

前面举的例子都是针对单一服务器 SSH 公钥登录配置,如果我有多台服务器都需要配置成 SSH 公钥登录,该怎么配置?

这里有个便捷的方式,两步即可完成配置:

  1. 为每台服务器按照上面的 三步走 生成密钥对文件,配置 SSH 公钥登录后,整理好本地所有的私钥文件,最好所有的私钥文件统一放到同一目录下,比如 ~/.ssh/priKeys/
  2. 编写本地 SSH 配置文件: ~/.ssh/config

假如我的服务端主机与主机别名(方便自己记忆而起的别名)列表如下:

192.168.120.1 jiayu1
192.168.120.2 jiayu2
192.168.110.3 jiayu3
192.168.110.4 jiayu4

那么我的本地 ~/.ssh/config 文件配置如下:

Host jiayu1 #别名
Hostname 192.168.120.1 #服务器地址
Port 22 #服务器 SSH 服务端口
User root #服务端的用户名
IdentityFile ~/.ssh/priKeys/jiayutest1 #对应本地的私钥文件路径
Host jiayu2
Hostname 192.168.120.2
Port 22
User root
IdentityFile ~/.ssh/priKeys/jiayutest2
Host jiayu3
Hostname 192.168.110.3
Port 22
User root
IdentityFile ~/.ssh/priKeys/jiayutest3
Host jiayu4
Hostname 192.168.110.4
Port 22
User root
IdentityFile ~/.ssh/priKeys/jiayutest4

各配置项的意义见上面的注释内容,这样一来,我就可以用 主机别名 直接登录远程服务器了。比如通过 SSH 公钥登录 [email protected] ,以下命令即可:

~ ➜ ssh jiayu4

这样,ssh 命令会自动根据 ~/.ssh/config 中的配置项,寻找到 jiayutest 这一个私钥文件,然后拿它去登录 [email protected]


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK