多 SSH Key 管理技巧与 Git 多账户登录问题
对很多开发者,尤其是手握几台甚至几十台机器的同学而言,登录到远程机器处理事务应该是家常便饭。如果你也是其中一员,悄悄问一句,你平时是如何记住一堆帐号、机器地址以及一些附加登录选项的呢?或许你也是这么干的:
倘若你有一个远程服务器,地址为 test.server.com
, 防止人为攻击,你将 ssh 的端口号从 22 改成了 8892,当你需要登录到这台机器时,需要这么做:
➜ ~ ssh YOURNAME@test.server.com -p 8892 |
尚好。如果你先前已经将已经注册了一个公钥/私钥对,并且正确的部署到了远程机器,你可以省却输入密码这个环节(推荐学习 ssh-copy-id
命令)。
为了可以再懒一点,索性将这一串代码添加一个 alias:
➜ ~ aliastest='ssh YOURNAME@test.server.com -p 8892' |
一条 test
命令即可让你登录到服务器,对于只有一两台远程机器的你,应该算是特别便捷了。
多 SSH Key 的管理
SSH 连接建立之前,会在系统中寻找它的配置,一般有两个位置。
/etc/ssh/ssh_config
这里是对所有用户适用的全局配置~/.ssh/config
或者$HOME/.ssh/config
这是用户的个人配置,这些配置会覆盖全局配置
注意:一般来说,我们给 ~/.ssh
文件夹赋予的权限为 0700
。
配置格式比较简单,以下配置等同于上面我们的登录命令设置:
Host test |
可以是 param value
也可以为 param=value
,其中 param 对大小写不敏感,value 对大小写敏感。
使用 ssh test
即可完成登录,当我们有稍微麻烦点配置的时候,如数据库的 3306 端口对外不开放,可以开放另一个接口,然后内部跳转到 3306,使用命令行的写法是:
ssh -f -N -L 8999:127.0.0.1:3306test@database.server.com |
大串的命令行,过多的参数,实在是有点不好记。而在 config 文件中的配置就一目了然:
Hosttest |
当你有多台远程终端的时候,config 文件的优势就更加明显了:
# serverlist |
这里常用的的 param 也不是很多:
Host
,SSH 连接名HostName
,如上所示,可以是通配符,可以是 IP,也可以是域名等User
,登录的用户名IdentifyFile
,version 1 协议下默认是~/.ssh/identify
,version 2 协议下,默认是依次匹配:~/.ssh/id_dsa
,~/.ssh/id_ecdsa
,~/.ssh/id_rsa
,还有 version 2 兼容模式。LocalForward
端口的内部跳转Port
,端口设置,默认 SSH 的端口是 22Protocal
,协议版本号,1 或者 2
Git 多账户登录问题
向仓库 push 代码之前,我们都会做一番设置,简单归纳为如下几步:
注册获取用户名 barretlee
创建仓库
barretlee/test.git
创建密钥,
ssh-keygen -t rsa -C "barret.china@gmail.com"
将公钥 id_rsa.pub 填到 Git Server 上(如果没有可视化界面,还需要登录到 Server 命令行操作推送)
本地通过 ssh-agent 将密钥添加到 session 中,
ssh-add id_rsa
,部分终端中还需要手动开启 ssh-agent然后测试连接,如 github 中,
ssh -T git@git.github.com
看到了 ‘welcome barretlee…’ 的提示,开始 push 你的代码
突然有一天,你又注册了一个帐号 xiaohuzige,也走了一遍上面的流程,发现死活也连接不上,服务器总是提示:You have no permission to access this repo
,这是怎么回事呢?
这个时候,你可以输入这个命令,看看是哪个环节出了问题:
➜ ~ ssh -vT git@github.com |
不加 v 参数,输出的内容很简洁:
➜ ~ ssh -T git@github.com |
好吧,我知道你看不懂上面一长串的内容,也没心情看下去,但是你可以把焦点落到重复的那几段:
debug1: ... |
之前我们提到了 Protocal Version 1 和 Version 2,不同的版本号,默认的私钥地址不一样,所以程序会不断去尝试寻找默认的地址,如果没找到,最后会提示,授权失败,禁止访问。
我们可以在 push 代码之前,使用 ssh-agent 来管理私钥的 session,如:
➜ ~ ssh-add .ssh/coding_barretlee |
那么当程序寻找私钥的时候,就会优先到 ssh-agent 添加的 session 中寻找。session 的生命周期不是很长,当你重启电脑之后它就没了。如果你有遇到了 Permission Denied
的提示,请重新执行 ssh-add 命令。
当你在某个 Git 服务器上有多个帐号的时候,可能某个帐号总是提示:Permission Denied
。拿 coding.net
上来说,我有两个账户,一个是 barretlee,另一个是 taobaofed,由于先前我一直用的 barretlee 账户,后来者 taobaofed 的代码死活推不上去。反反复复地检查配置,反反复复地检查上传的公钥,反反复复地使用 ssh -T git@git.coding.net
测试,没看到哪里不对,然而 taobaofed 的代码就是推不上去,这是怎么回事呢?
当然,上面 SSH 介绍了那么多,其简明易懂的配置在这里也是可以用上的:
### default for all ## |
使用这种配置,我们可以避免使用 ssh-agent 添加 session 操作。可是,我就是按照上面的方式配置的呀,依然不行!
这里的问题在于,我们的 User 项不正确,每次推送代码的时候,git 会读取上次的的 User 配置,而我的配置是 barretlee,那么下次提交代码的时候虽然 IdentityFile 用对了,但是 User 不是 taobaofed,所以死活也推不动代码。
解决的方案很简单,如果在下载代码之前就已经设置好了两个帐号,你可以通过如下命令克隆代码:
➜ ~ git clone git@coding-taobaofed:taobaofed/blog.git |
如果是在已有的仓库中,其默认 origin 配置会是:https://git.coding.net/taobaofed/blog.git
或者 git@git.coding.net:taobaofed/blog.git
,你可以将仓库下的 .git/config
文件修改下:
[remote "origin"] |
防止克隆其他仓库代码也出现问题,我们可以将 ~/.ssh/config
稍加修改:
## barretlee coding ## |
那么,通过正常的 clone(如git clone git@git.coding.net:barretlee/blog.git
)就不会出现 Permission Denied
的提示了。
最后
撰写本文之前,我已经踩坑三小时,花了三个小时,摸索出来这么些东西,感觉以后妈妈再也不用担心我的 Git/SSH 的配置问题了。
最主要的手段依然是通过 ssh -vT
查看 SSH 交互过程中出现了什么障碍,debug 信息还是很有考究价值的!
建议继续学习:
- Git常用命令备忘 (阅读:53235)
- Git log diff config高级进阶 (阅读:23808)
- Git subtree 要不要使用 –squash 参数 (阅读:22338)
- 我的git笔记 (阅读:18851)
- Zend Studio集成Git使用 (阅读:8068)
- Linux shell脚本使用while循环执行ssh的注意事项 (阅读:6738)
- Git commit 注释格式 (阅读:5753)
- GIT和SVN之间的五个基本区别 (阅读:4923)
- 在ssh服务里使用chroot (阅读:4927)
- 为什么要用公钥/私钥而不是密码去做SSH身份验证 (阅读:4766)
扫一扫订阅我的微信号:IT技术博客大学习
- 作者:小胡子哥的个人网站 来源: 小胡子哥的个人网站
- 标签: Git SSH 多账户
- 发布时间:2016-03-10 00:08:53
- [70] IOS安全–浅谈关于IOS加固的几种方法
- [69] Twitter/微博客的学习摘要
- [64] 如何拿下简短的域名
- [63] android 开发入门
- [62] Go Reflect 性能
- [61] find命令的一点注意事项
- [59] 流程管理与用户研究
- [58] 图书馆的世界纪录
- [57] 读书笔记-壹百度:百度十年千倍的29条法则
- [57] Oracle MTS模式下 进程地址与会话信