免密ssh登录原理与方法实践(ssh免密登录不起作用)
ssh是我们常用的远程登录方式,尤其在管理和维护linux,unix系统中更是不可或缺,ssh的使用主要由两个角色: ssh server--提供安全的shell服务 ssh-client--连接到服务器上进行操作,中间的传输过程由服务器和客户端实现加密传输。
本次不讨论中间的加密环节,只要知道使用了加密技术,这些数据就算被人截获到了,也很难还原成明文,从而实现了安全。
ssh登录的基本逻辑
所有的登录过程,基本逻辑都是接近的,客户端的用户提供一个凭据,这个凭据可以是用户名密码,证书对(公钥和私钥),保存在智能卡里面的数字证书(也是公钥的一种),指纹,甚至是声纹、面容等等能辨别用户身份的任何特征信息。(只要有一种驱动能把这些特征解析数字化,表达唯一都行),服务器根据提供的信息在本地服务器或认证系统比对,只要对上了,就认为是许可的,否则就是禁止的。以上就是ssh的基本逻辑。下面只讨论两种最常见的用户名密码方式和证书方式。
基本过程
我们常用的ssh登录方式主要有密码登录和证书登录方式:
1、密码方式主要有两种:
一种是交互式登录,也就是相当于现用现输入,这种方式一般用命令行实现,在客户端上用 root@ssh [host] -p [port num],接下来会提示输入用户名密码,用户此时可以输入或用粘贴的方式提供密码,并回车,如果正确,将会正常登入系统,下面是输入错误的示例:
另外一种密码是利用软件,使用存储在软件里预先存储好的用户名和密码,省去了现输现找的麻烦。当然这种情况下虽方便但,安全性不好。登录界面大同小异,在此不再截图。
2.证书登录
证书登录一般会分为三个步骤:I.生成密钥对 II.分发密钥对 III.使用密钥对
Step1: 生成密码对的过程,都是用工具来生成的,常用的工具有:windows和Linux自带的ssh-keygen程序、PuTTYgen、SecureCRT、MobaXterm、Xshell等等。这些工具都能生成一对密钥,密钥有很多种规格的,必须用工具生成,手搓肯定是不行的,就和你不能拿刻刀刻出一张光盘是同样的道理。以win10自带的ssh-keygen,为例:
不要被密密麻麻的参数吓到,通常我们只需要用不带参数的ssh-keygen就可以,会有提示给我们:
一路回车,你就会发现c:\users\[你的用户名]/.ssh目录下面生成了两个文件: id_ed25519和id_ed25519.pub,我们管id_ed25519叫私钥,id_ed25519.pub叫公钥。顾名思义,私钥只能自己留着,公钥可以给别人共享。如果你想用这台Win10终端免密登录到另外一台ssh服务器上,就需要执行下一步,分发密钥到服务器上。
Step2:
首先,要明确分发的密钥一定是一个公钥,私钥要留好,谁也不能给,比喻一下,私钥更像一把钥匙,公钥像一把锁,你把锁安装到外面好多的地方,拿着钥匙就能打开锁(这种情况下同样的锁可以装多把,钥匙只有一枚)。
分发密钥有个前提,就是你要有远程系统登录的权限,或者你让对方的管理员把公钥放到它的系统里。到底公钥应该放到哪里呢?这要看你的目的是什么,你想用哪个用户名的身份登录远程系统(终究密钥认证也没能绕开用户名),不要管你生成密钥时用了哪个用户身份,用了哪个登录环境,只要公钥在手,你放到哪个用户环境里,哪个环境就可以远程免密了。以一般的Linux或Unix系统为例,这个是用户的家目录-->.ssh目录-->authorized_keys,正常情况下,你想免密登录到root用户,这个目标就是/root/.ssh/authorized_keys,普通用户是/home/[login name]/.ssh/authorized_keys.
分发密钥的方式很简单,就是把公钥里的内容(一个公钥就只有一行内容,你用文本编辑器看到的换行只是因为文本编辑器为了显示好看给你断开的,实际就是一行你不要误会,请直接复制不要画蛇添足的加换行符)。这是最笨的方法,当你没有工具可用时,你就用这一招。还有个问题,有时候你会发现authorized_keys文件没有,怎么办?那就直接创建一个,如果这个文件存在,但是它有内容怎么办?那就打开文件,在最后一行后面加上你的新公钥。
最专业的方式还是要用工具,一条命令(只有Linux和Unix下面有)ssh-copy-id [login name]@[remote host] -p [port num]然后他会提示你输入密码,只要密码正确,你就已经完成了分发密钥的步骤。
说到这里常听到有杠精说,Windows里装上openssl + cygwin就能有ssh-copy-id,我自己用源码编译一个ssh-copy-id,云云,我只想说杠赢了又能如何,照样受到鄙视。
不喜欢杠精,这篇文章我是写给我自己的,我们言归正传,
Step3:
密钥分发完成之后,就需要用了,怎么使用呢?你是否还记得我们当初生成key的那台电脑,他生成的私钥我们还不知怎么用呢。还是那句话,保存好它别到处乱拷,就像不能把钥匙乱丢一个道理。让我印象最深刻的用法还是命令行用法,还以win10为例:
从上面的例子可以看到,根本不需要再提供密码了,直接就可以进到远程系统。另外用xshell,putty,secure crt等软件时,如果需要免密登录,你也可以让密钥通用,解决办法就是把私钥导入到这些软件里面去,也可以从这些软件里导出来给windows的ssh命令用。具体就不贴图了,主要是理解原理。
常见问题
I.免密有什么用?
免密最大的好处不是不安全了,而是更安全了,你可能注意到了,key的长度其实是很长的,这么一串密码没有规则,不能被反算,而且还是成对出现的,所以安全级别是很高的,这有一个前提条件,就是被控方ssh-server的管理员懂安全,他可以把用户名密码的登录方式禁用掉,避免了暴力破解的情况。拿一个实际的例子,在公网上的云主机在没有vpn保护的情况下ssh换了端口暴露在公网上,除非做了访问白名单,否则难免遭到外来的扫描和撞库,一个不小心,主机就被攻破了(这也有一个前提,你的sshd没有那个严重的心脏出血漏洞)。看一下公网上做了端口映射的ssh server每天要应对多少攻击。
像上面的例子那样,如果不加以调整,如何能确保安全?有人会说了,你买个安全服务,配置一个加黑的脚本不就完了,我想我的安全观和他不一样,我只要确保系统安全运行就行了,那个脚本我也写过,配置了免密认证就够用了,何必再多此一举。再说你说的轻巧,你怎么自己不买呢,让别人花钱自己不心疼是吧,shame of you.
II.为什么要保护好私钥?
原因很简单,因为它是真正的钥匙,如果别人知道你要登录哪台ssh server拷走了你的私钥,那样就等于把系统权拱手与人了。如果你乐意分享,让同事共同管理主机,进行协作,当然你可以自由分享到可控范围内,他们连key是什么都不知道就能访问远程系统工作了。所以保管好私钥是必要的,但不是教条和绝对的。但是如果你的私钥让坏人拿到了,那你肯定就完了。比如你把公网服务器的私钥内容粘贴到博客上,发到群里,那你绝对完了,提前想好后路。对于企业级来讲,一般不会把服务器暴露在公网上的,大部分都会用VPN进行隔离,所有的事情不要绝对化,也不要一概而论。
如果你想在内部传播私钥怎么办呢,能不能更安全一些呢,答案是肯定的,还记得生成密钥ssh-keygen这个工具吗?它在生成私钥时会要求你输入密码,这个密码一定要记好,你在使用这个私钥时密码和私钥会配套使用,这时候有私钥也不能免密了,实质是免了ssh server的登录密码,但是免不了使用私钥的密码。虽然本质是不一样的,但对于用户来说用法基本差不多,有人就很嫌弃这种方式。还是要说,你忘记了密钥对给你带来的安全好处了,形式一样,安全性真的不是一个级别的。
III.各种类型的key有啥不一样的?
生成key的过程刚才的描述中简单带过了,我们使用时默认的ed25519目前接近被废弃,所以我们再回顾一下我们要用哪些规格的key,其实我们常用的key更多的是rsa生成时只要指定-t rsa就可以了,生成的文件比较大,但是但是但是,ed25519安全性更高,速度更快。Ed25519 基于椭圆曲线密码学,其密钥长度较短但安全性较高,抵抗量子计算攻击的能力强。 RSA 则基于大整数因子分解,其密钥长度需相对较长才能保证较高的安全性,且在量子计算攻击面前相对脆弱。你知道该选哪个了么?
写在最后
在普通的os中做ssh免密其实是基本操作,我写了上面的主要是想给自己留下一个记录,以后想不起来的时候翻翻看看。
目前我有时候会考虑我的几台锐捷交换机如何用key进行免密ssh登录,教我使用用户名和密码保存在变量里的,用ansible-playbook的,我先谢谢您,我不是那个意思,您还是浅薄了,不懂就不要瞎bb。