Linux-使用ssh免密码登录

Linux-使用ssh免密码登录

ssh登录的认证方式

我们能用ssh登录服务器,是因为服务器中运行着一个叫sshd的守护进程,它默认监听着22端口,该进程的配置文件在/etc/ssh/sshd_config,在里面我们可以看到sshd的认证方式大概有:

PubkeyAuthentication    公钥认证
RSAAuthentication   RSA认证
PasswordAuthentication  密码认证
PAM authentication  PAM认证
GSSAPIAuthentication    GSSAPI认证

其中注释的都是默认使用注释的值,最常用的认证就是公钥认证密码认证,我们平时登录时要输入密码,就是用的密码认证,而免密码登录就是使用公钥认证了,其他的我也不太懂(好像也是可以免密登录),以后用到再说吧。

方法一:使用公钥免密登录

生成RSA公钥/私钥对

首先你要检查一下你的~/.ssh目录下,有没有id_rsaid_rsa.pub两个文件,如果有,那就不用执行ssh-keygen了,因为你以前已经执行过了,id_rsa就是私钥,id_rsa.pub就是公钥。

如果没有这两个文件,那么执行下面命令,无论提示什么,你都闭着眼晴一路回车即可,最后会在~/.ssh目录下生成id_rsaid_rsa.pub两个文件。

ssh-keygen

如图所示(该命令也可以写成ssh-keygen -t rsa,如果不写,默认就是-t rsa,t表示type,即类型)
Xnip2018-11-04_00-43-06.png

ssh-keygen输出的内容翻译:

Generating public/private rsa key pair.
翻译:正在生成rsa公/私密钥对
Enter file in which to save the key (/Users/bruce/.ssh/id_rsa):
翻译:输入你要保存的密钥文件名(直接回车表示使用默认文件名`/Users/bruce/.ssh/id_rsa`)
Enter passphrase (empty for no passphrase):
翻译:输入密码(如果不输入则默认为空,公钥认证方式还可以再加一层密码,这样更安全,但是一般没必要)
Enter same passphrase again:
翻译:再次输入密码(还是直接回车表示使用空密码)
Your identification has been saved in /Users/bruce/.ssh/id_rsa.
翻译:你的私钥已经保存到`/Users/bruce/.ssh/id_rsa`文件中
Your public key has been saved in /Users/bruce/.ssh/id_rsa.pub.
翻译:你的公钥已经保存到`/Users/bruce/.ssh/id_rsa.pub`文件中(注意,公钥文件名都是在私钥文件名后面加上`.pub`,pub表示public,公共的)
The key fingerprint is:
翻译:密钥指纹是:
SHA256:IPOJPYk+xqkqn11pCX8Jn/WVHjIUqf5wjevNxLliL3Q [email protected]

自动把公钥拷贝到服务器中

我们可以使用ssh-copy-id命令,把上一步中生成的公钥拷贝到需要免密登录的服务器中,一个公钥可以多个服务器使用,所以你需要免密登录的服务器都可以往那拷(记得把 [email protected] 换成你的服务器的账号密码哦)。

ssh-copy-id [email protected]

这一步会把你用户目录中的id_rsa.pub拷贝到服务器中的~/.ssh/authorized_keys文件中(这个文件默认是不存在的,会自动创建)。

这一步操作完成后,你可以去服务器的~/.ssh目录下看,是不是多了一个authorized_keys,如果有多个用户想用公钥认证方式登录这台服务器,同样,只要把它们的公钥放到authorized_keys文件中即可,一个公钥占一行(如果你用vi/vim查看是多行,那是因为软换行,实际上还是一行,显示行号即可看出来)。

ssh-copy-id默认是拷贝你电脑上的~/.ssh/id_rsa.pub公钥文件到服务器,那如果你的公钥不在这个路径,或者说不是这个名字呢?比如有可能是你帮新员工开账户,让它们把公钥发你,你来上传,要怎么上传呢?

其实是可以通过-i来指定你要上传的公钥文件的,比如

ssh-copy-id -i ~/Downloads/zhangsan.pub [email protected]

这样就会把公钥文件上传到zhangsan的家目录下的/.ssh/authorized_keys文件中。

手动把公钥拷贝到服务器

事实上,除了用前面说的ssh-copy-id命令外,你也可以用常规的传文件的方法(如scp、sftp、rsync等)手动把公钥文件传到服务器后,自己新建~/.ssh/authorized_keys文件,并把公钥文件中的内容复制到该文件中,也可以手动直接复制内容粘贴到~/.ssh/authorized_keys文件中,这种方法尤其常见于只能用密钥登录而不允许密码登录的机器。

但需要注意~/.ssh/authorized_keys文件的权限必须为600,且~/.ssh目录的权限为700,这是Linux为了安全而规定的,如果这两个权限有一个不对,则公钥认证会失败,但由于~/.ssh目录默认就存在,所以它的权限无需你去设置,默认就是700,而用ssh-copy-id命令往服务器传公钥自动生成的~/.ssh/authorized_keys的权限自动就是600,所以也无需你去修改,所以只有你自己新建的才需要修改。

在本地执行以下命令,输入密码后即可把公钥文件id_rsa.pub文件上传到123.8.12.135服务器的xiebruce用户的家目录下

scp ~/.ssh/id_rsa.pub [email protected]:~

注意: 这个本地未必是你自己的电脑,有可能是另一台服务器,比如A要免密登录到B,那么A就是我说的本地,但它实际上可能是一台服务器。

然后在服务器操作

# 在服务器123.8.12.135进入xiebruce家目录中的.ssh目录(注意此时你是以xiebruce这个用户登录的,并且没有切换到其它用户)
cd ~/.ssh/

# 把xiebruce家目录下的id_rsa.pub文件中的内容追加到authorized_keys文件中
cat ~/id_rsa.pub >> ~/.ssh/authorized_keys

# authorized_keys文件有可能之前不存在,我们先看看它的权限
ls -l ~/.ssh/authorized_keys

# 如果是权限不是600,即不是“-rw-------”,那前面说属于首次添加,这时我们要设置一下它的权限为600,如果是600我们就不用设置了
chmod 600 ~/.ssh/authorized_keys

操作完后,你就可以用xiebruce这个用户免密登录123.8.12.135这台服务器了(但其它用户还是不行)。

如果你们公司是你管理着这台服务器,很明显其他人(新员工)想要用公钥认证的方式登录,必须把它们的公钥发给你(让他们用ssh-keygen生成),你来放到这台服务器里他们的账户家目录下对应authorized_keys文件中。

试试免密登录是否正常

如果正常的话,会直接进入登录用户的家目录(记得把 [email protected] 换成你自己服务器的账号密码哦)

ssh [email protected]

解决SSH连接自动断开的问题

编辑服务器的sshd的配置文件/etc/ssh/sshd_config,把ClientAliveInterval改成60,这样每隔60秒服务器会跟客户端通讯一次,然后客户端会回复,这样就不会断,把ClientAliveCountMax修改成3,表示如果3次(3*60=180秒)以后还是没有人操作客户端,那就自动断开(毕竟不能长时间开着,这样不安全):

ClientAliveInterval 60
ClientAliveCountMax 3

或者还可以在客户端(就是你自己的电脑上),编辑vim ~/.ssh/config,在里面添加:

ServerAliveInterval 60

表示每60秒与服务器通信一次,这样就不会断开,这个比较厉害一点,因为我是mac,晚上睡眠了都没断开,所以如果没必要,还是别用这个了,毕竟一直开着不是太安全。

此外,客户端还可以设置当空闲时,每隔一定时间自动往服务器发送一个任意字符(默认是0),比如我用的iTerm2就可以这样设置:
Xnip2018-11-07_16-20-57.png

奇怪的是,以前用密码登录的时候,只需要客户端这样设置即可,但换成了公钥认证免密码登录,客户端这个不灵了,所以才需要在服务器修改配置。

公钥认证免密登录原理

假设你想用自己的电脑A去登录服务器B(以下是自己网上查找并加上个人理解,如有不对恳请大佬指出!)

  • 1)A向B发送一个连接请求,信息包括自己的用户名,ip等;
  • 2)然后B得到A信息后,去.ssh下的authorized_keys文件中查找,如果有该用户的用户名和主机名,B会随机生成一个字符串STR;
  • 3)然后B利用A的公钥对字符串STR进行加密,然后发送给A,A得到B发过来的消息用自己的私钥进行解密,然后将解密后的字符串用自己私钥签名后发送给B;
  • 4)B接收到A发过来解密的字符串并用公钥验签,验签通过说明A发过来的数据中途未被篡改,然后比较STR是否跟刚才发过去的一致,如果一致就会允许免登陆(此时命令行界面将跳转到登录服务器后的界面)。

方法二:使用expect免密登录

expect自动登录原理

除了前面的上传公钥,还可以使用expect工具,是自己写一个脚本,来样模拟用户的输入,本质上还是要密码,只不过expect工具可以自动识别终端弹出的输入密码提示,自动帮你输入你事先给好的密码并帮你回车确定(当然其实回车也是自己写的)。

使用这种方式是因为遇到有阿里云跳板机只能用ls命令查看服务器列表,什么也做不了,更别说上传你的公钥了。

编写expect脚本

以下命令即为自动登录脚本

#!/usr/bin/expect
set timeout 30
spawn ssh -l xiebruce 12.34.56.78
expect "password:"
send "123578\r"
interact

先把上边命令复制到你本地随便一个编辑器中,修改以下值

  • xiebruce是登录用户名,请先换成你的登录用户名;
  • 12.34.56.78是要登录的服务器ip,请先换成你要登录的服务器ip;
  • send "123578\r"中的123578是登录密码,请换成你服务器的登录密码,注意不要把\r删掉

修改好之后,在你电脑上新建autologin.sh文件,把刚刚修改好的内容粘贴进去,保存(因为是ssh用于自动登录的,我建议直接放到~/.ssh/目录下)。

然后给它执行权限

chmod u+x ~/.ssh/autologin.sh

在iTerm2上使用

这里我演示配置iTerm2终端使用,其它的终端应该也有类似自动执行shell脚本的功能。

打开iTerm2终端,按快捷键cmd+o,点击右下角的Edit Profiles
image.jpg

然后点击左下角的+号可以新增一个配置,如下图,填一下Name,还有在Command里选择Custom Shell,在右侧框填入刚刚创建的autologin.sh的绝对路径(绝对路径就不要用~这种符号),这样就行了,也不用点保存,直接点左上角的关闭按钮即可(自动保存)
image.jpg

以后要登录你那个服务器,直接在iTerm2上按cmd+o,用上下方向键选中前面添加的那个配置,回车,即可自动登录。

:其实我平时都是用公钥免密方式的,后来为了测试这种方式,我专门给我的一个服务器设置了用这种方式登录,后来在使用中发现,只要是用这种方式登录的,它会“记住”登录时窗口的大小。

比如,我小窗口的时候登录,你用vim打开文件,再放大窗口,vim打开的内容还是只会占用原来小窗口大小,不会像正常编辑器那样把内容铺满整个窗口,

如果我大窗口的时候登录,再用vim打开文件,文件内容能铺满窗口,但是,如果你把窗口缩小后再用vim打开文件,它内容会乱,显示不出来,放大窗口后再按上/下(即j/k键)才能让内容显示出来。

也就是说,你在大窗口的时候登录,就只能在大窗口的时候打开,如果你换成小窗口打开,它显示就会乱;同理,小窗口的时候登录,虽然在大窗口也能打开,但它显示还是在那个小窗口中显示。

参考:Linux使用expect实现免手工密码输入

方法三:使用sshpass免密登录

本质上还是要密码,只不过sshpass帮我们输入了。

brew无法安装sshpass

我们知道,macOS的包管理工具是Homerew,macOS下大多数命令都可以通过brew install xxx来安装,但是如果你这种方法安装sshpass,它会提示

We won’t add sshpass because it makes it too easy for novice SSH users to
ruin SSH’s security.
翻译:我们不会添加sshpass,因为它会让很多SSH新手用户毁掉SSH的安全性。

提示如下图
image.jpg

我们知道Homebrew是一个第三方开发者编写的开源包管理工具,其代码开源在github上,可能Homebrew的开发者认为,这个命令会导致SSH新手用户滥用SSH,因为新手本身就不太懂,它也不了解什么安全性,这样会导致SSH失去它的安全性优势,所以Homebrew的开发者就没有把sshpass加入官方的核心库中。

虽然我们可以通过一些第三方库来安装,但质量也是参差不齐,我建议还是直接源码编译吧,也不难,非常简单。

源码编译安装sshpass

与大多数开源代码都放在github上不同,sshpass的源代码是放在sourceforge上的,我们直接在sourceforge里下载它的源码包就可以。

当然github上也有,只不过是从sourceforce同步过去的(是sourceforce的一个镜像),版本可能不是最新的。

以下命令编译(每行分别执行):

#解压
tar -zxf sshpass-1.08.tar

#进入解压后的源码文件夹
cd sshpass-1.08

#运行configure命令进行编译前配置
./configure

#编译并安装
make && make install

编译安装完之后它是自动安装到/usr/local/bin/下的,然后就可以使用了。

使用sshpass登录

sshpass的使用非常简单,在原有的ssh登录命令前面,加上sshpass -p "登录密码"即可自动登录。

例(-p指定的密码可以不加双引号,但最好加上,因为有时候密码有些特殊字符,比如“星号”、“括号”之类的,不加双引号就会导致报错):

sshpass -p "sifs329i" ssh [email protected]

也可以把这个命令放到一个.sh文件里(注意sshpass要写全路径),然后像前面的expect那样添加到iTerm2(或者你喜欢的终端)里,使用的时候,选择它,回车,即可快速不需要密码进入服务器

sshpass -p "sifs329i" ssh [email protected]

其它命令

#查看sshpass版本
sshpass -V

#帮助
sshpass -h
打赏

订阅评论
提醒
guest

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据

0 评论
内联反馈
查看所有评论
0
希望看到您的想法,请您发表评论x

扫码在手机查看
iPhone请用自带相机扫
安卓用UC/QQ浏览器扫

Linux-使用ssh免密码登录