设置SSH密钥登录
前言
本篇博客是学习ssh中windows端ssh服务器是如何使用密钥来代替传统密码登录的记录
步骤
一、首先在访问者(windows)端生成密钥
- 在~目录下创建.ssh文件夹并切换过去
1
2
3cd ~
mkdir .ssh
cd .ssh - 在服务器端创建自己的ssh密钥对[2]
1
ssh-keygen -t ed25519 -C "your_email@example.com
如果你使用的是不支持 Ed25519 算法的旧系统,请使用以下命令:
1 |
|
默认密钥保存位置在~/.ssh
目录下,当然在接下来会提示输入别的保存路径,是否设置密码短语(用于加密私钥),建议密码短语不要留空(回车),否则私钥被窃取别人就可以直接获得访问权限。
因为我本机已经有密钥了,所以下面这张图是以服务器执行ssh-keygen -t rsa
为例,实际上windows端是要在cmd中执行这个命令的
生成后的密钥在c:/users/<your username>/.ssh
目录下,有以下两个文件,.pub对应的是公钥,没有后缀的是私钥
二、将公钥拷贝到服务器要访问的账户的~/.ssh/authorized_keys文件中
~/.ssh/authorized_keys
保存已经认证的公钥,这样当访问者访问服务器时会经过密钥验证,从而实现免密登录。
我们可以手工在被访问者(服务器)中创建~/.ssh文件夹,然后将
访问端(windows)的id_ras.pub里的内容拷贝进去实现免密登录。
要将.ssh文件夹权限修改为700,authorized_keys文件权限修改为600,否则会导致ssh服务访问失败从而无法认证。
那有没有更方便快捷的方法呢,答案是有的,ssh为我们提供了ssh-copy-id
命令,只要在访问者(windows)上执行
1 |
|
就可以指定执行以上操作,包括创建.ssh文件夹和authorized_keys文件并拷贝公钥,然后设置权限等。
ssh-copy-id 用来将本地公钥复制到远程主机。如果不传入 -i 参数,ssh-copy-id 使用默认 ~/.ssh/identity.pub 作为默认公钥。如果多次运行 ssh-copy-id ,该命令不会检查重复,会在远程主机中多次写入 authorized_keys 。[1]
在windows上cmd和git cmd不支持该命令,需要在git bash里输入。
三、测试
在命令行正常使用ssh连接
1 |
|
这时会提示输入passphrase,输入即可。如果没给访问者(windows)设置passphrase的话就无需输入,实现免密登录了
四、给公钥设置了passphrase的小伙伴们需要额外的一步
由于设置了passphrase,在ssh登录服务器时虽然免于输入密码,但为了解密私钥,需要输入passphrase,这样不还是很麻烦吗?那有没有什么方法可以方便一点呢,其实ssh-agent就是为了解决这个问题而生的。
什么是ssh-agent
这里参考[3]的解释
SSH 只是一种协议,其开源实现有 OpenSSH,并且存在服务端(sshd) 和 客户端 (ssh),Windows 中的客户端有 PuTTY;而这两种客户端都有各自的 ssh agent:
ssh-agent 命令:是客户端 ssh 的默认代理
Pageant : 是 客户端 PuTTY 的代理。Pageant是用于PuTTY,PSCP,PSFTP和Plink的SSH身份验证代理。 Pageant会存储您的私钥,只要它正在运行,它就会为PuTTY或其他工具(如IntelliJ IDEA)提供解锁的私钥。(当然ssh-agent也能做)
把私钥交给 ssh agent 管理的好处:
当 其他程序 需要身份验证的时候 可以将验证申请交给 ssh-agent 来完成整个认证过程 。如 git
避免重复输入密码:如果您的私钥使用密码短语来加密了的话,每一次使用 SSH 密钥对 进行登录的时候,您都必须输入正确的密码短语。而 SSH agent 程序能够将您的已解密 的私钥缓存起来,在需要的时候提供给您的 SSH 客户端。
总之,ssh-agent 就是为程序提供ssh服务的代理,这里的程序包括ssh自己的客户端。
(推荐)windows上使用原生ssh-agent
那么怎么使用ssh-agent呢? 其实在windows上,windows10自带的Open-ssh客户端就有一个ssh-agent,并且已经以服务形式注册在系统里的,但是默认是禁用状态,可以在服务里查看一下。
服务禁用的话是无法运行的。那么首先我们需要把服务改为手动状态首先我们需要打开这个服务[2]
1 |
|
在无提升权限的终端窗口中,将 SSH 私钥添加到 ssh-agent。 如果使用其他名称创建了密钥,或要添加具有其他名称的现有密钥,请将命令中的 id_ed25519 替换为私钥文件的名称。
1 |
|
接下来会提示你输入passphrase,输入之后就会自动由ssh-agent保存了,并且重启电脑也不需要重新输入。
windows上使用git-bash自带的ssh-agent
因为git是基于ssh的,例如对远程git仓库执行git push等会首先调用ssh连接仓库。安装了Git for windows后,git会自带两个终端工具分别是git-bash和git-cmd,其中git-cmd经测试调用的是windows的原生ssh-agent,所以无需重新配置;而git-bash里的ssh-agent是单独的,并且无法实现随windows自动启动,但是我们可以通过在.bashrc/.profile里写入脚本实现随git-bash自动启动。[4]
复制以下行并将其粘贴到 Git bash 中的 ~/.profile
或 ~/.bashrc
文件中:
1 |
|
这段脚本的原理是,每次打开git bash时先载入~/.ssh/agent.env
,此时如果里面有socket信息则可以复用上一次启动的ssh-agent进程,防止启动多个ssh-agent。然后使用ssh-add -l检查ssh-agent进程信息是否有效(是否已经启动)。如检查ssh-agent是否已经启动,agent_run_state=2代表没启动,则启动ssh-agent并且把该线程的socket信息写入~/.ssh/agent.env
;若agent_run_state=0,表示已经启动,不做任何操作。agent_run_state=1表示进程启动但还没有将passphrase纳入ssh-agent管理,则执行ssl-add添加管理。这样做可以实现每次git-bash启动是自动启动ssh-agent并且复用已经存在的ssh-agent进程。
然而这种方式来自动启动ssh-agent有两个缺点。
第一是无法实现真正意义的随windows自动启动,而只能在首次打开git-bash时启动ssh-agent。
第二是无法实现真正意义的持久化,git-bash并不是完整的unix系统,虽然能执行unix命令,启动unix进程但只要重启windows后信息就会丢失,除非像上面那样写入agent.env那样自己手动写入文件里。但windows重启,ssh-agent进程被终止,所保存的passphrase信息会丢失,所以每次重启后打开git-bash都会需要重新输入pasphrase。而windows自带的Open-ssh里的ssh-agent则完全没有这个问题。
第三是写入.profile/.bashrc只对login shell有效,对于non-login shell或者直接第三方程序调用ssh服务时时不会运行.profile/.bashrc的,从而仍然需要输入passphrase。例如部署hexo博客时的git-deployer插件就是直接调用的git-bash。所以会出现始终需要重新输入的情况,目前本人也没找到合适的办法解决这个问题。
其他
一、如何修改/删除passphrase
通过输入以下命令,您可以更改现有私钥的密码而无需重新生成密钥对:[4]
1 |
|