原文地址:https://rtyan.github.io/%E5%B7%A5%E5%85%B7/2017/09/12/ssh-keys-manager.html

引言

我有两个github账户,一个是平时正常使用的,另外一个是用来专门做博客用的,

因为之前常用的那个做博客名字不好看o(╯□╰)o。

这就引发了一个问题,我想在博客账户中添加ssh keys的时候,github会提示

我下面的信息

原来,同一个公钥只能在github系统中添加一次,重复添加的话会报这个错误,就算

是不同的账户也不能将同一个公钥添加多次。

这个问题要怎么解决呢?

暴力法——重新生成

最简单的方法,也就是直接生成一套新的公钥密钥对,然后添加到我的博客账户中,

等下次再用常用的账号时候再重新生成一套,再替换常用账号中的ssh keys就可以

了,事实上我第一次就是这么干的,没完全弄清楚怎么回事,只能按照流程重新生成

一遍了,而且确实生效了。

但用了几次之后我发现不用重新生成、只要在本地生成两份ssh keys,然后每次讲要

使用的ssh keys命名为id_rsaid_rsa.pub就可以了,不用每次替换账号中的配置了。

但用了一段时间,发现还是很麻烦,是在太难受了,于是就想着写一个半

自动化的创建、切换ssh keys的工具。

半自动化法

沿着上面的思路,我可以生成多套ssh keys,然后将他们管理起来,每次使用的时候

只需要将他们替换到id_rsaid_rsa.pub就可以了,省略了人工去切换。就像下面

这样:

➜  rtyan.github.io git:(master) git push origin master
Permission denied (publickey).
fatal: Could not read from remote repository. Please make sure you have the correct access rights
and the repository exists.
➜ rtyan.github.io git:(master) sshkeys change rtyan
切换ssh keys对,从[aizuyan]到[rtyan]...
复制/Users/ritoyan/.ssh-keys-pair/rtyan到/Users/ritoyan/.ssh/id_rsa成功
复制/Users/ritoyan/.ssh-keys-pair/rtyan.pub到/Users/ritoyan/.ssh/id_rsa.pub成功
切换到rtyan成功
➜ rtyan.github.io git:(master) git push origin master
Counting objects: 8, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (8/8), done.
Writing objects: 100% (8/8), 77.54 KiB | 0 bytes/s, done.
Total 8 (delta 5), reused 0 (delta 0)
remote: Resolving deltas: 100% (5/5), completed with 5 local objects.
To github.com:rtyan/rtyan.github.io.git
a05e55f..50b54a7 master -> master

目前已经开发完成,用shell完成的,最后面会将代码贴出来。

工具生成的所有ssh keys pairs都保存在~/.ssh-keys-pair/目录下,就下下面

这样:

-rw-------  1 ritoyan  staff  3243  9 12 21:15 backup
-rw-r--r-- 1 ritoyan staff 741 9 12 21:15 backup.pub
-rw-r--r-- 1 ritoyan staff 6 9 12 21:16 nowRecord
-rw------- 1 ritoyan staff 3243 9 12 21:15 rtyan
-rw-r--r-- 1 ritoyan staff 741 9 12 21:15 rtyan.pub

其中backupbackup.pub记录了软件安装之前的ssh keys信息(如果有的话)。

nowRecord记录了当前使用的是哪个ssh keys,里面的内容等同于~/.ssh-keys-pair/

目录下的密钥名称。

其他文件的话就是公钥密钥对了,密钥是<生成时候的名称>,公钥是<生成时候的名称>.pub

列出所有ssh keys列表的时候就是通过匹配~/.ssh-keys-pair/文件夹下面的.pub

后缀来的,匹配上了就算是一个公钥密钥对。

安装

安装的话直接把最下面的shell代码复制到/usr/local/bin/sshkeys中(或其他$PATH

目录中),然后执行chmod +x /usr/local/bin/sshkeys给脚本加上可执行权限,然后

就可以看命令使用了。

命令

这个工具一共5个命令,功能分别如下(也可以直接看代码):

sshkeys init

初始化环境,备份原来的ssh keysbackup,设置当前使用的ssh keys名称为backup

sshkeys list

列出当前所有的ssh keys名称,当前使用的前面有星号:

➜  GIT sshkeys list
aizuyan
backup
* rtyan

sshkeys create <name> [<email>]

上面的命令是创建一个名称为<name>ssh keys,后面的<email>是可选项:

➜  GIT sshkeys create aizuyan ritoyan@163.com
开始创建密钥公钥对...
执行命令[ssh-keygen -t rsa -b 4096 -f /Users/ritoyan/.ssh-keys-pair/aizuyan -q -N "" -C "ritoyan@163.com"]
创建成功

sshkeys showpub [<name>]

上面的命令是展示公钥,后面的<name>是可选的,默认展示当前正在使用的,加了参数显示

对应<name>的公钥:

➜  GIT sshkeys showpub aizuyan
ssh-rsa AA.........Vw== ritoyan@163.com

sshkeys change <name>

切换到对应<name>ssh keys

➜  GIT sshkeys change aizuyan
切换ssh keys对,从[rtyan]到[aizuyan]...
复制/Users/ritoyan/.ssh-keys-pair/aizuyan到/Users/ritoyan/.ssh/id_rsa成功
复制/Users/ritoyan/.ssh-keys-pair/aizuyan.pub到/Users/ritoyan/.ssh/id_rsa.pub成功
切换到aizuyan成功

代码

代码又长又臭,可以忽略过了,想看的看下。

还有很多地方要优化,不过现在我用是够了,哈哈。

#/bin/bash

# 存放数据的根目录
softBase="${HOME}/.ssh-keys-pair/"
sshBase="${HOME}/.ssh/"
sshIdRsaPath="${sshBase}id_rsa"
sshIdRsaPubPath="${sshBase}id_rsa.pub"
nowSshPairRecordPath="${softBase}nowRecord" action=$1 function init()
{
# 判断根目录是否存在,不存在创建
if [ -d $softBase ];then
return 1
fi
echo "初始化..." #[1] 创建目录
echo "[1]创建必要的目录..."
mkdir -p -m 700 $softBase
if [ $? != 0 ];then
echo "[1-1]创建目录${softBase}失败"
else
echo "[1-1]创建目录${softBase}成功"
fi #[2] 备份现在的sshkey
echo "[2]备份当前的ssh key pair"
if [ -f "${sshIdRsaPath}" ];then
cp $sshIdRsaPath "${softBase}backup"
if [ $? != 0 ];then
echo "[2-1]备份${sshIdRsaPath}到${softBase}backup"
else
echo "[2-1]备份${sshIdRsaPath}到${softBase}backup"
fi
else
echo "${sshIdRsaPath}文件不存在,不需要备份"
fi
if [ -f "${sshIdRsaPubPath}" ];then
cp $sshIdRsaPubPath "${softBase}backup.pub"
if [ $? != 0 ];then
echo "[2-2]备份${sshIdRsaPubPath}到${softBase}backup.pub失败"
else
echo "[2-2]备份${sshIdRsaPubPath}到${softBase}backup.pub成功"
fi
else
echo "${sshIdRsaPubPath}文件不存在,不需要备份"
fi #[3] 设置当前sshkeys
echo "[3]设置当前sshkeys记录"
if [ -f "${sshIdRsaPubPath}" ];then
echo "backup" > $nowSshPairRecordPath
if [ $? != 0 ];then
echo "[3-1]设置当前sshkeys记录为[backup],写入${nowSshPairRecordPath}失败"
else
echo "[3-1]设置当前sshkeys记录为[backup],写入${nowSshPairRecordPath}成功"
fi
fi echo "初始化成功\n"
return 0
} function nowRecord()
{
local nowRecord=`cat ${nowSshPairRecordPath}`
echo $nowRecord
return 0
} # 列出所有的公钥名称
function list()
{
local files=`ls $softBase | grep "\.pub\$"`
local file
local nowRecord=`nowRecord`
for file in ${files}
do
sshKeysName=${file%%.pub}
if [[ $nowRecord == $sshKeysName ]]; then
echo "* "$sshKeysName
else
echo " "$sshKeysName
fi
done
} # 创建一对新的密钥
# $1 密钥名称 必选
# $2 邮件 可选
function create()
{
keyPairName=$1
maybeEmail=$2
createPath="${softBase}${keyPairName}"
cmd="ssh-keygen -t rsa -b 4096 -f ${createPath} -q -N \"\""
if [[ $maybeEmail ]]; then
cmd="${cmd} -C \"${maybeEmail}\""
fi
echo "开始创建密钥公钥对..."
echo "执行命令[${cmd}]"
eval $cmd
if [ $? != 0 ];then
echo "创建失败"
else
echo "创建成功"
fi
} # 切换ssh keys
function change()
{
local keyPairName=$1
local rsaPath="${softBase}${keyPairName}"
local rsaPubPath="${rsaPath}.pub"
local preSshPairRecord=`nowRecord`
echo "切换ssh keys对,从[${preSshPairRecord}]到[${keyPairName}]..."
cp $rsaPath $sshIdRsaPath
if [ $? != 0 ];then
echo "复制${rsaPath}到${sshIdRsaPath}失败"
else
echo "复制${rsaPath}到${sshIdRsaPath}成功"
fi
cp $rsaPubPath $sshIdRsaPubPath
if [ $? != 0 ];then
echo "复制${rsaPubPath}到${sshIdRsaPubPath}失败"
else
echo "复制${rsaPubPath}到${sshIdRsaPubPath}成功"
fi
echo "${keyPairName}" > $nowSshPairRecordPath
if [ $? != 0 ];then
echo "切换到${keyPairName}失败"
else
echo "切换到${keyPairName}成功"
fi
} function showpub()
{
local keyPairName=$1
if [ -z "${keyPairName}" ]; then
keyPairName=`nowRecord`
fi
local keyPubPath="${softBase}${keyPairName}.pub"
cat $keyPubPath
} case "${action}" in
"init" )
init
;;
"list" )
list
;;
"create" )
keyPairName=$2
maybeEmail=$3
create "${keyPairName}" "${maybeEmail}"
;;
"change" )
keyPairName=$2
change "${keyPairName}"
;;
"showpub" )
keyPairName=$2
showpub "${keyPairName}"
;;
* )
echo "this is action none"
;;
esac

ssh keys管理工具的更多相关文章

  1. windows包管理工具和 ssh安装

    Chocolatey windows下的包管理工具 https://chocolatey.org/ cmd里执行 @"%SystemRoot%\System32\WindowsPowerSh ...

  2. Git 进阶指南(git ssh keys / reset / rebase / alias / tag / submodule )

    在掌握了基础的 Git 使用 之后,可能会遇到一些常见的问题.以下是猫哥筛选总结的部分常见问题,分享给各位朋友,掌握了这些问题的中的要点之后,git 进阶也就完成了,它包含以下部分: 如何修改 ori ...

  3. 源代码管理工具-GIT

    源代码管理工具-GIT ---- 一. 掌握 - git 概述 1. git 简介? 什么是git? git是一款开源的分布式版本控制工具在世界上所有的分布式版本控制工具中,git是最快.最简单.最流 ...

  4. iOS核心笔记—源代码管理工具-GIT

    源代码管理工具-GIT 一. git 概述 1. git 简介? 什么是git? > git是一款开源的分布式版本控制工具 > 在世界上所有的分布式版本控制工具中,git是最快.最简单.最 ...

  5. 使用ssh keys实现免验证登陆远程服务

    使用ssh keys实现免验证登陆远程服务========================Created 星期四 10 五月 2018 引言------------------程序员或者服务器运维人员 ...

  6. Git多个SSH KEYS解决方案(含windows自动化、TortoiseGit、SourceTree等)

    工作过程中,经常会使用到多个git仓库,每个git仓库对应一个账号,可以理解为每个git仓库对应一个ssh key,因此我们需要管理多个ssh key.   一.快速创建ssh key   1. 创建 ...

  7. IOS-源代码管理工具(Git)

    一.简介 什么是git? git是一款开源的分布式版本控制工具 在世界上所有的分布式版本控制工具中,git是最快.最简单.最流行的   git的起源 作者是Linux之父:Linus Benedict ...

  8. hadoop基础----hadoop实战(七)-----hadoop管理工具---使用Cloudera Manager安装Hadoop---Cloudera Manager和CDH5.8离线安装

    hadoop基础----hadoop实战(六)-----hadoop管理工具---Cloudera Manager---CDH介绍 简介 我们在上篇文章中已经了解了CDH,为了后续的学习,我们本章就来 ...

  9. Linux(11):期中架构(3)--- SSH远程管理服务 & ansible 批量管理服务

    SSH远程管理服务 1. 远程管理服务知识介绍 # 1.1 SSH远程登录服务介绍说明 SSH是Secure Shell Protocol的简写,由 IETF 网络工作小组(Network Worki ...

随机推荐

  1. 52. leetcode 96. Unique Binary Search Trees

    96. Unique Binary Search Trees Given n, how many structurally unique BST's (binary search trees) tha ...

  2. 之前同事问到的一道python题目

    Python面试题 之前同事问了一道Python题目如下,暂时归类为面试题 题目:把类似'123.456'的字符串转换成浮点型数据 方法一: >>> print '{:.3f}'.f ...

  3. EXT中导出表格中的数据到Excel

    { itemId: 'excel', text: '导出', iconCls: 'btnExportExcel', disabled: false, handler: function () { // ...

  4. 安徽省2016“京胜杯”程序设计大赛_F_吃在工大

    吃在工大 Time Limit: 1000 MS Memory Limit: 65536 KB Total Submissions: 51 Accepted: 15 Description      ...

  5. [BZOJ 3629][ JLOI2014 ]聪明的燕姿

    这道题考试选择打表,完美爆零.. 算数基本定理: 任何一个大于1的自然数N,都可以唯一分解成有限个质数的乘积N=P₁^a₁ P₂^a₂…Pn^an,这里P₁<P₂<…<Pn均为质数, ...

  6. tps 与 事务平均响应时间关系对答

    在网上看到一篇文章,tps 与 事务平均响应时间关系对答.可以帮助能更清楚的了解二者之间的关系. 问者:每秒处理的事务数和事务的平均响应时间 怎么个关系,有关系吗 kaku21:举个例子:一个高速路 ...

  7. SSE图像算法优化系列十:简单的一个肤色检测算法的SSE优化。

    在很多场合需要高效率的肤色检测代码,本人常用的一个C++版本的代码如下所示: void IM_GetRoughSkinRegion(unsigned char *Src, unsigned char ...

  8. Qt5.8以上版本编译Oracle数据库的OCI驱动教程

    在前一篇的文章中我已经发过一个相似的文章,详情请点击:Qt5编译oracle驱动教程. 在那一篇文章中已经可以解决了Qt5的常用版本的Oracle数据库驱动的支持,但是在新的Qt开发工具中那种方法竟然 ...

  9. Docker 搭建开发环境

    本文介绍如何将Docker集成到开发环境,自动构建应用,并使容器拥有独立的内网IP为开发人员提供服务. 术语解释 Docker镜像:一个不可修改的"模板",每个代码版本对应一个镜像 ...

  10. 浅析Java RTTI 和 反射的概念

    一.概念: RTTI(Run-Time Type Identification,运行时类型识别)的含义就是在运行时识别一个对象的类型,其对应的类是Class对象,怎么理解这个Class对象呢?如果说类 ...