Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

为什么git clone ssh地址输入密码总是失败 #103

Open
willson-wang opened this issue Feb 22, 2022 · 0 comments
Open

为什么git clone ssh地址输入密码总是失败 #103

willson-wang opened this issue Feb 22, 2022 · 0 comments

Comments

@willson-wang
Copy link
Owner

目录

背景

公司自研了脚手架,用于项目的快速创建,基于架构设计,模版与脚手架是分离的,模版物料库放置在一个单独的gitlab仓库,而脚手架内通过git clone的方式将物料库中的模版clone下来,生产最终的模版项目

为了避免让小伙伴通过脚手架创建模版的时候输入用户名与密码,所以clone选择的是ssh链接地址,而不是https地址,默认公司每个小伙伴电脑上都配置了ssh key,理想是丰满的,现实是骨感的,总是有一些小伙伴,是没有配置ssh key的,所以就不得不重新考虑git clone的方式,解决思路是,先判断是否配置了ssh key,如果没有配置,再让小伙伴输用户密码

判断是否配置ssh key的方式

ssh -T git@对应的gitlab地址

如果有配置则会返回welcome xxx;

如果没有设置,则会出现无法确认host主机的真实性,只知道它的公钥指纹,问你还想继续连接吗?这样的提示,我们选择确认之后,则会提示输入密码,然后我们输入gitlab密码,残酷的是密码是对的,但是没法登录成功

image-20220222102442165

一开始一直以为是自己密码记错了,然后试一下https链接来clone,是会出现输入用户名,然后在输入密码的过程,最终输入账号密码之后成功clone了下来

问题来了,git clone ssh链接,没有提示输入用户名的这一个步骤,只有输入密码的步骤,而https链接是有输入用户名步骤的,为什么会有这样的差异,于是找了下相关的资料

SSH与HTTPS的区别

git可以使用四种主要的协议来传输内容: 本地协议(Local),HTTP 协议,SSH(Secure Shell)协议及 git 协议。其中,本地协议由于目前大都是进行远程开发和共享代码所以一般不常用,而git协议由于缺乏授权机制且较难架设所以也不常用

最常用的便是SSH和HTTP(S)协议。git关联远程仓库可以使用HTTP协议或者SSH协议。

HTTPS优缺点

  • 优点1: HTTPS 更简单,只需要输入用户名与密码就可以进行代码的clone、push、pull
  • 优点2: 不需要为多个不同的git服务,配置不同的ssh key
  • 优点3: HTTPS使用的是443端口,基本上任何互联网的防火墙中都是开放这个端口号的
  • 缺点: 使用http/https除了速度慢以外,还有个最大的麻烦是每次推送都必须输入口令. 但是现在操作系统或者其他git工具都提供了 keychain 的功能,可以把你的账户密码记录在系统里,例如OSX 的 Keychain 或者 Windows 的凭证管理器

SSH的优缺点

  • 优点1: 架设 Git 服务器时常用 SSH 协议作为传输协议。 因为大多数环境下已经支持通过 SSH 访问

  • 缺点1: SSH服务端一般使用22端口,企业防火墙可能没有打开这个端口。

  • 缺点2: 必须先配置ssk key才能正常的进行clone、push、pull

  • 缺点3: SSH 协议的缺点在于你不能通过他实现匿名访问。 即便只要读取数据,使用者也要有通过 SSH 访问你的主机的权限,这使得 SSH 协议不利于开源的项目。 如果你只在公司网络使用,SSH 协议可能是你唯一要用到的协议。 如果你要同时提供匿名只读访问和 SSH 协议,那么你除了为自己推送架设 SSH 服务以外,还得架设一个可以让其他人访问的服务。

SSH原理与运用

什么是SSH?

SSH是一种网络协议,用于计算机之间的加密登录

基本用法

SSH主要用于远程登录。假定你要以用户名user,登录远程主机host,只要一条简单命令就可以了

$ ssh user@host

中间人攻击

SSH之所以能够保证安全,原因在于它采用了公钥加密

整个过程是这样的:(1)远程主机收到用户的登录请求,把自己的公钥发给用户。(2)用户使用这个公钥,将登录密码加密后,发送回来。(3)远程主机用自己的私钥,解密登录密码,如果密码正确,就同意用户登录。

这个过程本身是安全的,但是实施的时候存在一个风险:如果有人截获了登录请求,然后冒充远程主机,将伪造的公钥发给用户,那么用户很难辨别真伪。因为不像https协议,SSH协议的公钥是没有证书中心(CA)公证的,也就是说,都是自己签发的。

可以设想,如果攻击者插在用户与远程主机之间(比如在公共的wifi区域),用伪造的公钥,获取用户的登录密码。再用这个密码登录远程主机,那么SSH的安全机制就荡然无存了。这种风险就是著名的"中间人攻击"(Man-in-the-middle attack)。

SSH协议是如何应对的呢?

口令登录

如果你是第一次登录对方主机,系统会出现下面的提示:

image-20220218224444742

当我们选择yes,并输入正确的密码之后就登录成功了

当远程主机的公钥被接受以后,它就会被保存在文件$HOME/.ssh/known_hosts之中。下次再连接这台主机,系统就会认出它的公钥已经保存在本地了,从而跳过警告部分,直接提示输入密码。

每个SSH用户都有自己的known_hosts文件,此外系统也有一个这样的文件,通常是~/.ssh/known_hosts,保存一些对所有用户都可信赖的远程主机的公钥。

公钥登录

使用密码登录,每次都必须输入密码,很麻烦。好在SSH还提供了公钥登录,可以省去输入密码的步骤。

所谓"公钥登录",原理很简单,就是用户将自己的公钥储存在远程主机上。登录的时候,远程主机会向用户发送一段随机字符串,用户用自己的私钥加密后,再发回来。远程主机用事先储存的公钥进行解密,如果成功,就证明用户是可信的,直接允许登录shell,不再要求密码。

直接用ssh-keygen生成

ssh-keygen

运行上面的命令以后,系统会出现一系列提示,可以一路回车。其中有一个问题是,要不要对私钥设置口令(passphrase),如果担心私钥的安全,这里可以设置一个。

运行结束以后,在$HOME/.ssh/目录下,会新生成两个文件:id_rsa.pub和id_rsa。前者是你的公钥,后者是你的私钥。

更多内容参考SSH原理与运用(一):远程登录

github或者gitlab的场景怎样来配置私钥与公钥

1、生成秘钥

ssh-keygen -t rsa -f ~/.ssh/id_rsa_github -C "[email protected]" 生成上传github文件名为id_rsa_githubid_rsa_github_pub的私钥与公钥

ssh-keygen -t rsa -C "[email protected]" 生成上传gitlab默认的id_rsaid_rsa_pub的私钥与公钥

2、在ssh文件夹下配置config文件,注意mac电脑上不能有后面的//注释,不然报错

# default                                    

Host git.xxx.com.cn   // gitlab的域名

HostName git.xxx.com.cn 

User xxx // 登录名

IdentityFile ~/.ssh/id_rsa  // 对应的私钥文件

# two                                      

Host github.com // github的域名

HostName github.com // github的域名

User xxx

IdentityFile ~/.ssh/id_rsa_github

3、将id_rsa_pub内的公钥放置到gitlab的ssh内,id_rsa_github内的公钥放置到github的ssh内

4、测试ssh链接

ssh -T [email protected] // 判断github的ssh链接是否成功

ssh -T [email protected] // 判断gitlab的ssh链接是否成功

如果成功会提示welcome to gitlab/github xxx

5、设置全局的gitlab邮箱与用户名,git config --list查看当前项目的git配置信息

git config global user.email '[email protected]'

git config global user.name 'xxx'

6、在需要通过github上传的项目内设置局部的邮箱与用户名,注意不需要去取消全局的,直接在本地项目内设置即可,则会覆盖全局的邮箱和用户名配置

git config user.name 'xxx'

git config user.email '[email protected]'

现在就可以使用ssh方式操作多个不同的git服务器了

在回过来来看最开始的问题,ssh -T [email protected]为什么不用输入密码,原因是ssh -T [email protected] 这里的git就是用户名,所以我们只需要输入密码,为什么这里不能使用我们自己的用户名,而是一定要使用git用户名,先看github文档内找到这样的描述,文档里面描述我们总是要使用git作为user

image-20220222110509657

为什么git clone ssh链接不用输入用户名,同理一样,ssh地址都是[email protected]:yd/activity.git,这里的用户名还是git;

所以通过ssh 这种方式clone一定要先配置了ssh key才能过通过验证,将仓库内容clone下来

在来看,为什么git服务器,要求总是使用git用户来操作,而不允许通过注册的用户名与密码来进行操作,只找到一个相关的回答[Why does git using ssh use git as a username](Why does git using ssh use git as a username)

这里面的内容概括起来就是

  • git服务只是选择ssh方式来作为内容传输的协议
  • ssh用户检验的方式契合git服务想要的方式
  • 对于用户是不需要与git服务器进行交互式操作的,所以我们没必要登录git服务器
  • 我们只需要通过git校验,然后通过ssh的方式将git服务器上的内容下载下来就可以

所以我们使用ssh方式与git服务器进行交互的时候,使用统一的git用户就可以,而不需要使用自己注册的用户名与密码

总结

追求简单,推荐使用HTTPS方式,只需要输入账号密码即可

有命令行习惯的开发,推荐SSH KEY方式,只需要第一次花点时间配置一下,后续就不用考虑账号登录的问题

参考链接

SSH原理与运用(一):远程登录

Should You Use HTTPS or SSH For Git?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant