盘点对比代码推拉的若干种方式

开源其实不简单 2024-03-05 21:27:23

在日常使用代码托管平台时,多数开发者对代码推拉协议并不敏感。在实际使用中,不同协议往往会遇到不同的使用障碍。

笔者试着通过本文,对代码推拉所使用的协议、各类协议在使用过程遇到的问题进行总结梳理,帮助大家对代码推拉有一个简要的认识。

现网常见的代码推拉协议有:Git 协议、HTTP/HTTPS、SSH、SSH-over-HTTPS、SVN、SVN-over-SSH。其中,HTTP/HTTPS 和 SSH 为主流代码推拉协议,传播和使用最广。

下面,我们将详细介绍各类协议的优劣势:

Git 协议git://hostname[:port]/path/to/repository.git

Git 协议 是 Git 自带,基于 TCP 实现的轻量级原生传输协议,其默认端口是 9418 或 22。

Git 协议采用了简单的 URL 格式,不需要复杂的配置和身份验证。只需使用 git:// 或 git+ssh:// 前缀加上服务器地址和仓库路径即可访问和克隆远程仓库。

Git 协议的优劣势

在实现机制上,Git 协议使用了裸传输 (PlainText),传输过程没有额外的封装和身份验证,对网络的要求较低,在传输效率上比其他协议如 HTTP 和 HTTPS 更高。

正因为 Git 协议没有内置的身份验证和加密机制,Git 协议不被主流的代码托管平台所采纳,一般只用于各类业务系统内部服务的数据传输。

HTTP / HTTPS 超文本传输协议http://hostname[:port]/path/to/repository.git

HTTP(Hypertext Transfer Protocol,超文本传输协议)的默认端口是 80 端口。只需要使用 http:// 前缀加上服务器地址和仓库路径就可以完成代码仓库的访问和推送拉取。

作为当下互联网使用最为广泛的协议,简单易用和广泛兼容的特点,让其得到了几乎所有的工具软件的支持。同时,HTTP 协议作为 Web 基础协议,代码仓库的 HTTP 协议地址既可以作为推送拉取地址,又能作为网页访问地址。用户可以通过浏览器直接访问对应的代码仓库,极大降低了用户使用代码托管系统的学习成本。

主流的代码托管平台都支持 HTTP 协议。

由于 HTTP 是无状态的协议,每次请求和响应之间相互独立,没有记忆能力。所以传输过程中发生任何错误,都需要重新传输全部或部分数据。

随着技术发展,HTTP 协议由于其通信过程的数据传输不加密,存在安全风险,HTTPS(Hyper Text Transfer Protocol Secure,安全的超文本传输协议)应运而生。HTTPS 的默认端口是 443。

https://hostname[:port]/path/to/repository.git

HTTPS 在传输层使用了 SSL/TLS 协议(Secure Sockets Layer/Transport Layer Security),通过对 HTTP 进行加密和身份验证来保护数据的传输。可以防止敏感信息(如帐号密码等)被恶意篡改或窃取。简而言之,HTTPS 协议是在 HTTP 协议基础上加了一层加密,以达到其安全保护的目的。

主流的代码托管平台同时提供 HTTP 和 HTTPS 支持,并将 HTTP 默认重定向到 HTTPS 协议地址。但在多数本地部署的代码托管服务,HTTP 仍被广泛的采纳。

伴随 SSL/TLS 协议的设计,HTTPS 在每次通信中都需要进行加密和认证操作。这也带来了新问题:

每次通信中都要进行加密和认证操作,会产生一定的带宽和性能损耗,导致使用 HTTPS 推送和拉取时间变长。HTTPS 是 HTTP 的升级封装,在传输过程中发生任何错误,都需要重新传输全部或部分数据。即便主流浏览器和互联网巨头致力推送 SSL 加密的普及,维护 HTTPS 证书对大多数企业和个人依然是复杂的,这也是大部分本地部署的代码托管服务仍在采用 HTTP 的主要原因。

从协议实现上,HTTPS 继承了 HTTP 协议几乎所有的特性。两者本身没有提供对单次传输数据大小的严格限制,但实际上 Git 客户端和大多数云服务和 Git 服务商都会对每次 HTTP 请求的数据包大小进行限制,以避免超出其资源的处理能力或出现滥用的情况。

当 Git 客户端 HTTP/HTTPS 请求超出大小限制时,一般会出现推送/拉取超时的情况。这时可以通过调整 Git 客户端的 http.postBuffer 配置进行改善。

在 Git 中,http.postBuffer 配置项的默认值是 1MB。意味着如果没有主动设置 http.postBuffer 的值,Git 会将请求主体缓冲区大小限制在 1MB 以内。

git config --global http.postBuffer <size>

其中,<size> 表示希望设置的缓冲区大小,大小单位可以是 K、M 或 G。例如,要将缓冲区大小设置为 100MB,可以执行以下命令:

git config --global http.postBuffer 100M

使用 HTTPS 协议推拉仓库,可能会因为服务端限制导致传输失败。建议更换使用 SSH 协议。

SSH 协议git@hostname[:port]:path/to/repository.git

SSH(Secure Shell)是一种带身份鉴权的加密网络协议,其默认端口是 22。使用 git@hostname[:port]:path/to/repository.git 格式的 SSH URL,例如:git@gitee.com:sdk/typescript-sdk-v5.git。

由于通信过程使用了 SSH 的加密技术,安全性较高。此外,SSH 协议也支持端口转发功能,在防火墙后面的 Git 仓库也可以通过 SSH 进行访问。

作为当下安全性较高的仓库推拉协议,SSH 协议被大部分主流托管平台所推荐。

伴随安全的提升,SSH 协议的使用也带来了新的学习成本。用户需要使用 ssh-keygen 命令生成公私钥,在托管平台(如 Gitee)上配置公钥以满足身份验证要求。一般场景下,你可能会用到以下命令:

生成 SSH 密钥对(默认情况下保存在用户的 ~/.ssh/ 目录下):

ssh-keygen -t ed25519 -b 4096 -C "your_email@example.com"

加密算法一般有 RSA 和 ED25519 两种。与 RSA 相比,ED25519 长度更短,性能更高,生成和验证签名更快,同时提供了与RSA相当的安全性。如果你还需要考虑与旧版本 SSH 客户端和服务器的兼容性问题,或者需要更高的密钥长度,那么 RSA 仍然是一个可靠的选择。

查看公钥内容,此命令将显示你生成的公钥内容:

➜ cat ~/.ssh/id_rsa.pub───────┬──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── │ File: /Users/normal/.ssh/id_rsa.pub───────┼──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── 1 │ ssh-rsa AAAAB3NzaC1yc2EAAAADA*************ZLZztWbEwd6******Jn1UEQU/93+*****/**************************//**************************/************************** │ WkBtNXJgtbG4gLQX1wcjD65YQGoIihjZq++**************************/y9DOAW+*************/**************************/***************+*********/**** xxxxx@example.com───────┴────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

使用 SSH 命令验证配置你的 SSH Key 配置是否正确(当鉴权失败时,可通过 -vvv 参数查看加载的 SSH 密钥配置详情进行排查):

ssh -T [-p port] git@hostname

以 Gitee 为例,当你正确的配置了 SSH 公钥,命令将输出你对应配置了公钥的 Gitee 帐号信息(默认无须加端口,即无须带上 -p 22):

➜ ssh -T git@gitee.comHi 诺墨(@normalcoder)! You've successfully authenticated, but GITEE.COM does not provide shell access.SSH-over-HTTPS

在某些网络环境下,网络服务供应商可能会限制或屏蔽 SSH 的 22 端口,以达到提升安全等级和防范攻击的目的。

常见 22 端口被限制或屏蔽的场景有:

国内部分的教育网(校园网络) 部分云服务厂商网络 部分代理服务器 带有网络防火墙管制要求的网络环境

为了绕过对 SSH 标准端口(22 端口)的限制,我们可以使用 SSH-over-HTTPS 来推送和拉取代码,将 SSH 流量通过 HTTPS 端口(默认 443 端口)进行传输可以绕过这些限制,让 SSH 流量能够顺利地穿越网络边界和屏蔽设备。

Gitee 提供 SSH-over-HTTPS 支持,你可以使用 ssh.gitee.com 的 443 端口(注意不是 gitee.com 的 443 端口)来实现 SSH-over-HTTPS。

以 Clone 仓库为例,可以使用以下命令:

git clone ssh://git@ssh.gitee.com:path/to/repository.git

当你使用 SSH-over-HTTPS 时,你可能需要为 ssh.gitee.com 配置对应的 SSH 私钥,可以通过编辑 ~/.ssh/config 实现,具体配置参考如下:

Host ssh.gitee.comHostName ssh.gitee.comPreferredAuthentications publickeyHostkeyAlgorithms +ssh-rsaPubkeyAcceptedAlgorithms +ssh-rsaIdentityFile ~/.ssh/id_rsa# 此处的 ~/.ssh/id_rsa 对应你的 SSH 私钥文件

当你正确的配置了 SSH 公钥,使用 ssh -T -p 443 git@ssh.gitee.com 命令可以验证 SSH 配置是否正确:

➜ ssh -T -p 443 git@ssh.gitee.comHi 诺墨(@normalcoder)! You've successfully authenticated, but GITEE.COM does not provide shell access.

当你使用 SSH 通过 443 端口第一次与 ssh.gitee.com 交互时,你可能会收到一条警告提醒,告知你在 SSH 的 known_hosts 中找不到主机的 SSH 指纹,此时通过输入 Yes 即可解决。

➜ ssh -T -p 443 git@ssh.gitee.comkey_load_public: invalid formatThe authenticity of host '[ssh.gitee.com]:443 ([180.76.198.242]:443)' can't be established.ECDSA key fingerprint is SHA256:FQGC9Kn/eye1W8icdBgrQp+KkGYoFgbVr17bmjey0Wc.ECDSA key fingerprint is MD5:27:e5:d3:f7:2a:9e:eb:6c:93:cd:1f:c1:47:a3:54:b1.Are you sure you want to continue connecting (yes/no)?

在使用 SSH 的时候,为保证你所连接的远端代码仓库是真实可信的 Gitee.com 代码仓库,我们可以通过对比 Gitee.com 的 SSH 密钥指纹来确认你所访问的远端代码仓库的真实性。相关资料可以参考:https://help.gitee.com/account/gitees-ssh-key-fingerprints

总的来说,SSH Over HTTPS 提供了一种对复杂网络下保证代码仓库安全推拉的思路,通过 SSH 加密传输数据,利用 HTTPS 端口进行通信,解决了特定的网络环境限制,但整体的设置和使用会比 HTTPS 和 SSH 复杂。

除了上述的仓库推拉协议,Gitee 也是国内最早实现对 SVN 仓库协议兼容的平台。以下将介绍两种 SVN 仓库协议。

SVNsvn://hostname[:port]/path/to/repository

SVN 协议是 SVN(Subversion,一种集中式版本控制系统)的传输协议。其 URL 格式以 svn:// 开头,默认端口为 3690。支持通过命令行和 GUI 客户端进行拉取。

由于 SVN 属于集中式版本控制工具,而不是分布式版本控制,笔者强烈建议在工作或学习环境中使用 Git 而不是 SVN。对于协议的过往和技术细节,仅作学习了解足矣。

相比于 Git,SVN 的学习和使用的门槛较低。

与 SVN 的设计理念相匹配,SVN 具有丰富的文件/目录权限控制能力,对二进制文件的友好程度也比较高。这也让其局限性也颇为明显突出:

由于 SVN 其中心化的管理模式,限制了 SVN 大规模协作场景的效率,开发者需要频繁处理各种冲突和同步问题。由于 SVN 不支持分布式操作和离线工作模式,对服务器稳定性和可靠性要求高,存在较大的局限。随着过去数年,开源理念盛行,Git 的大规模普及,SVN 的优势也在逐步的被弱化。Git 和 SVN GUI 客户端的操作基本大同小异。Git 本身的学习成本不再是阻断工具使用的重要因素。SVN-over-SSH

SVN-over-SSH 是基于 SSH 的 SVN 协议包装,与 SVN 相比,多了一层安全加密,其端口和 SSH 默认 22 端口保持一致。整体配置过程同样较为复杂。

如果你的项目使用了 SVN over SSH,建议可以考虑将 SVN 转换为 Git,通过 Gitee 实现平滑过度。

Gitee 对 SVN 协议的兼容,其底层还是基于 Git 进行存储与维护。在 Gitee 上。开发者可以很轻松的从 SVN 切换到 Git。此外,Gitee 提供基于 Git 的 文件只读 功能,扩展了 Git 的能力支持,让 SVN 的用户能够很轻松的切换到 Git 的使用。

小结

基于上述的内容,笔者总结了常见的代码推拉协议,并对其做了一个简要的评估,供大家参考。

0 阅读:0

开源其实不简单

简介:感谢大家的关注