1. 这条报错到底在说什么
如果你在命令行里往远端仓库推送代码时,突然看到这么一行提示:remote: Support for password authentication was removed on August 13, 2021.,然后推送被拒绝,别慌,这不是你的仓库坏了,也不是网络抽风,而是远端平台在几年前就彻底关掉了“用账号密码直接推送”这条老路。很多刚接触版本控制的朋友第一次遇到这个报错时,第一反应是“我密码没输错啊”,第二反应是“是不是账号被封了”,其实都不是。这条提示的核心含义非常直白:从 2021 年 8 月 13 日起,远端平台不再接受用登录密码作为推送凭据,你必须换成一种更安全的凭据方式。
我先把结论摆在前面:这个问题的本质是身份认证方式变了,不是权限没了,也不是仓库地址写错了。你要做的就是把原来“输账号密码”的那套流程,替换成基于令牌或者密钥的认证方式。听起来好像很麻烦,但实际操作下来,快的话五分钟就能搞定,而且配好之后比原来还省事,不用每次推送都手动输密码。
这篇文章我打算按从业者的视角,把这件事从头到尾讲透。包括为什么会发生这个变化、几种主流解决方案怎么选、每一步具体怎么操作、参数怎么填、配好之后怎么验证、以及我自己踩过的那些坑。不管你是刚学会git push的新手,还是用了好几年但一直靠密码混日子的老手,看完都能直接照着做。关键词就三个:远端认证、访问令牌、SSH 密钥,围绕它们展开。
先说清楚适用人群。如果你平时只是本地提交、从不往远端推,那这条报错跟你没关系;如果你用的是图形化客户端并且已经登录过,可能暂时没遇到,但迟早会碰上;如果你在命令行里手动推送,那基本百分之百会撞上。所以这篇文章对绝大多数需要和远端仓库打交道的人都适用。
2. 为什么密码认证会被彻底移除
2.1 密码认证的历史包袱
要理解这个变化,得先知道早期的远端仓库认证是怎么工作的。最早的时候,你在本地推送代码,远端会弹出一个提示,让你输入用户名和密码,验证通过就允许推送。这套机制在互联网早期很常见,几乎所有网站都这么干。但问题在于,密码这种凭据一旦泄露,攻击者就能拿到你账号的完整控制权,而且用户往往在多个平台复用同一个密码,一处泄露、处处遭殃。
更麻烦的是,很多自动化脚本、持续集成流程里,人们会把密码明文写在配置文件里,或者用环境变量传进去。这些密码散落在各种地方,审计困难、轮换困难、撤销也困难。一旦某个脚本的日志被泄露,密码就跟着暴露了。远端平台每天要处理海量的推送请求,这种粗放的认证方式带来的安全风险越来越大。
2.2 令牌机制到底解决了什么问题
访问令牌的思路和密码完全不同。它是一串由平台生成的随机字符串,你可以给它设定有效期和权限范围。比如你只让它有读仓库的权限,那即使这串令牌泄露了,攻击者也只能读、不能改;你可以给它设 30 天有效期,到期自动失效;你还可以随时在后台手动撤销某一个令牌,而不影响其他设备的使用。
这就好比原来你家只有一把万能钥匙,丢了就得换锁;现在你可以给每个访客配一把只能开特定房间、且几天后自动失效的临时钥匙。安全性和可控性完全不是一个量级。远端平台推动这个变化,本质上是在逼着所有人从“一把万能钥匙”升级到“按需分配、可撤销、可过期”的凭据体系。
2.3 时间节点与影响范围
2021 年 8 月 13 日这个时间点,是平台正式关闭密码认证的日子。在此之前有很长一段过渡期,平台会发邮件提醒、在推送时给出警告。过渡期结束后,任何尝试用密码认证的请求都会被直接拒绝,返回的就是你看到的那条提示。影响范围包括所有通过 HTTPS 协议进行的推送、拉取操作,SSH 协议不受影响,因为 SSH 本来就不用密码。
这里有个容易混淆的点:HTTPS 和 SSH 是两种不同的传输协议。HTTPS 走的是 443 端口,认证靠令牌或密码;SSH 走的是 22 端口(或自定义端口),认证靠密钥对。很多人看到报错里提到“password authentication”,就以为所有认证都废了,其实只是 HTTPS 这条路上的密码认证废了,SSH 那条路一直好好的。
提示:如果你现在还在用 HTTPS 加密码的方式推送,建议直接切换到 SSH 密钥,一劳永逸,后面会详细讲怎么配。
3. 方案选型:令牌还是密钥
3.1 两种方案的核心差异
遇到这个报错,你有两条路可以走:一是继续用 HTTPS 协议,但把密码换成访问令牌;二是彻底切换到 SSH 协议,用密钥对认证。这两条路都能解决问题,但适用场景不太一样。
访问令牌方案的特点是:配置简单,不用生成密钥文件,直接在平台后台点几下就能拿到一串字符,然后把它当密码用就行。缺点是令牌本质上还是一串明文凭据,你得妥善保存,而且推送时可能还是需要输入(除非配合凭据缓存)。SSH 密钥方案的特点是:一次配置、长期使用,推送时完全不用输任何东西,安全性也更高,因为私钥永远留在你本地,不会通过网络传输。缺点是需要生成密钥对、把公钥传到平台、配置 SSH 代理,步骤稍微多一点。
3.2 什么情况选令牌
如果你只是临时用一下、或者在一台你不常使用的机器上操作、又或者你所在的环境不允许配置 SSH,那访问令牌是更快的选择。比如你在一个临时的容器环境里要推一次代码,生成密钥对再配置代理就显得太重了,直接拿个令牌填进去,推完就走,干净利落。
另外,如果你需要给某个自动化脚本配置推送权限,令牌也更合适,因为你可以给它设定最小权限和短有效期,脚本用完就撤销,风险可控。SSH 密钥给脚本用的话,私钥文件的管理反而更麻烦。
3.3 什么情况选密钥
如果你是在自己的主力开发机上长期工作,那 SSH 密钥几乎是唯一正确的选择。配好之后,你推送、拉取、克隆全都不用输任何凭据,体验丝滑。而且私钥可以加密码保护,即使文件被拷走,没有密码也用不了。对于每天都要推送多次的人来说,省下的输入时间累积起来很可观。
我个人的建议是:主力机器一律用 SSH,临时环境用令牌。两者不冲突,可以同时存在。你甚至可以在同一台机器上,对不同的仓库用不同的认证方式,Git 会根据仓库地址的协议自动选择。
3.4 一张表看清两种方案
| 对比维度 | 访问令牌(HTTPS) | SSH 密钥 |
|---|---|---|
| 配置难度 | 低,后台生成即可 | 中,需生成密钥并上传公钥 |
| 推送时是否需输入 | 配合缓存可免输入 | 完全免输入 |
| 安全性 | 中,令牌需妥善保存 | 高,私钥不出本地 |
| 有效期管理 | 可设过期时间 | 密钥长期有效,需手动轮换 |
| 适用场景 | 临时环境、自动化脚本 | 主力开发机、长期使用 |
| 撤销方式 | 后台删除令牌 | 后台删除公钥 |
这张表不是让你二选一,而是帮你判断当前场景下哪个更合适。实际工作中,我见过很多人两个都用:主力笔记本配 SSH,服务器上的部署脚本用令牌。
4. 访问令牌方案完整实操
4.1 生成令牌的具体步骤
登录远端平台的网页端,进入账号设置,找到开发者设置里的个人访问令牌页面。点击生成新令牌,平台会让你填几个关键信息。第一个是令牌名称,随便起个能让你认出来的名字,比如“家用笔记本”或者“部署脚本”,方便以后管理。第二个是有效期,建议不要选永久,选 30 天或 90 天,到期重新生成,降低泄露风险。第三个是权限范围,这是最关键的一步。
权限范围里有很多选项,你不需要全勾。如果只是推送代码,勾选仓库内容的读写权限就够了。如果还涉及流水线、议题等操作,再按需勾选。原则是最小权限,用不到的绝不勾。很多人图省事全选上,结果令牌一旦泄露,攻击者能操作的东西就太多了。
生成之后,平台会显示一串字符,这就是你的令牌。注意,这串字符只会显示一次,关掉页面就再也看不到了。所以一定要当场复制下来,存到安全的地方,比如密码管理器里。如果没存就关了页面,只能重新生成一个。
4.2 把令牌当密码用
拿到令牌后,你下次推送时,当系统提示输入密码,直接把这串令牌粘贴进去就行。用户名还是你的账号名,密码位置填令牌。这样就能成功推送了。
但这样每次推送都要输一遍,太麻烦。解决办法是配置凭据缓存。在命令行里执行一条配置命令,把凭据缓存时间设长一点,比如一小时或一天。这样在缓存期内,你只需要输一次,后续操作自动复用。
# 设置凭据缓存,单位为秒,这里设为一天 git config --global credential.helper 'cache --timeout=86400'如果你用的是较新的系统,还可以用系统级的凭据管理器,把令牌加密存储起来,比内存缓存更持久也更安全。具体用哪个 helper,取决于你的操作系统,可以查一下对应平台的推荐配置。
4.3 令牌的日常管理
令牌生成之后不是就完事了,你得定期检查。我建议每个月花两分钟看一眼后台的令牌列表,把不再使用的、过期的、或者你记不清用途的令牌删掉。特别是那些给了宽权限的令牌,更要重点盯防。
如果某天你怀疑某个令牌泄露了,第一反应应该是立刻去后台撤销它,而不是改密码。因为改密码不影响已经生成的令牌,令牌该能用还是能用。撤销令牌才是真正切断访问的手段。撤销之后,用这个令牌的地方会立刻失效,你需要重新生成一个替换上去。
注意:令牌的权限范围一旦设定就不能修改,要改权限只能重新生成。所以生成时想清楚用途,别嫌麻烦。
5. SSH 密钥方案完整实操
5.1 生成密钥对
打开命令行,执行生成密钥的命令。这里推荐用较新的密钥算法,比老的算法更安全、性能也更好。命令执行后,系统会问你密钥保存到哪里,直接回车用默认路径就行。然后会问你设不设密码短语,这个密码短语是用来保护私钥文件的,即使私钥被拷走,没有密码短语也用不了。
# 生成密钥对,推荐使用较新的算法 ssh-keygen -t ed25519 -C "你的邮箱或备注"我强烈建议设一个密码短语。虽然每次使用时要输一下,但配合 SSH 代理,你只需要在开机后输一次,之后整个会话期间都不用再输。安全性和便利性兼顾。如果你实在嫌麻烦,也可以留空,但那样私钥文件就等于裸奔,任何能读到这个文件的人都能冒充你推送代码。
生成完成后,你的密钥目录下会出现两个文件:一个是私钥,一个是公钥。私钥绝对不能给任何人,公钥是可以随便传的。很多人搞反了,把私钥传到平台上,那就等于把钥匙插在门上还贴了张纸条告诉别人地址。
5.2 把公钥传到平台
登录远端平台网页端,进入账号设置的密钥管理页面,点击添加新密钥。标题随便起,方便你识别是哪台机器的。然后把公钥文件的内容完整复制粘贴进去。注意是公钥,不是私钥。公钥文件通常以.pub结尾,内容是一行较长的字符串。
粘贴后保存,平台会记录这个公钥。之后你用对应的私钥进行认证时,平台就能识别出是你。一个账号可以添加多个公钥,比如你有台式机、笔记本、服务器,每台机器一个公钥,互不干扰。哪台机器不用了,删掉对应的公钥即可,不影响其他机器。
5.3 配置 SSH 代理
为了让密码短语只输一次,你需要启动 SSH 代理并把私钥加进去。在命令行里执行启动代理和添加私钥的命令。添加时会让你输一次密码短语,输完之后,在当前会话内就不用再输了。
# 启动 SSH 代理 eval "$(ssh-agent -s)" # 把私钥加入代理 ssh-add ~/.ssh/id_ed25519如果你希望每次开机自动启动代理并加载私钥,可以把这几条命令写进你的 shell 配置文件里。这样开机后第一次用到密钥时输一次密码短语,之后全程免输。不同系统的配置方式略有差异,但思路是一样的。
5.4 验证配置是否生效
配置完成后,执行一条测试命令,看看能不能和远端平台建立认证连接。如果看到欢迎信息,说明配置成功。如果提示权限被拒绝,说明公钥没传对或者代理没加载私钥,需要回头检查。
# 测试 SSH 连接 ssh -T git@远端平台地址测试通过后,你还需要确认仓库地址用的是 SSH 协议而不是 HTTPS。如果原来克隆时用的是 HTTPS 地址,需要把远端地址改成 SSH 格式。改完之后再推送,就不会再出现密码认证的报错了。
# 查看当前远端地址 git remote -v # 改成 SSH 地址 git remote set-url origin git@远端平台地址:用户名/仓库名.git6. 常见问题与排查技巧
6.1 推送仍然提示密码认证失败
这是最常见的情况。原因通常是你虽然配了 SSH 密钥,但仓库的远端地址还是 HTTPS 的,所以 Git 仍然走 HTTPS 那条路,自然还是要求密码认证。解决办法就是上面说的,把远端地址改成 SSH 格式。改完之后用git remote -v确认一下,地址开头应该是git@而不是https://。
还有一种可能是你的凭据管理器里缓存了旧的密码。系统看到缓存里有凭据,就直接拿去用了,根本没走 SSH。这时候需要清掉缓存的凭据。不同系统的清除方式不一样,可以查一下对应平台的凭据管理工具怎么删。
6.2 令牌明明是对的却提示无效
如果你用的是令牌方案,确认令牌复制完整了。令牌通常比较长,复制时容易漏掉开头或结尾的字符。另外确认令牌没有过期,后台看一眼有效期。还要确认令牌的权限范围包含了你要做的操作,比如你只勾了读权限,那推送肯定失败。
还有一种情况是用户名填错了。用令牌认证时,用户名还是你的账号名,不是邮箱,也不是令牌本身。有些人把令牌填到用户名位置,密码位置留空,那肯定不行。
6.3 SSH 连接超时或拒绝
如果 SSH 测试命令卡住不动或者提示连接被拒绝,可能是网络环境限制了 22 端口。有些网络环境会屏蔽 22 端口,这时候可以尝试用平台提供的 443 端口 SSH 地址。平台通常支持通过 443 端口走 SSH 协议,这样就能绕过端口限制。
配置方法是在 SSH 配置文件里加一段,指定访问特定主机时使用 443 端口。这样既走了 SSH 认证,又避开了端口屏蔽。具体的主机名和端口号,平台文档里有说明。
6.4 多账号或多密钥管理
如果你在同一台机器上要管理多个远端账号,或者同一个账号有多个密钥,就需要配置 SSH 配置文件来区分。在配置文件里为每个账号指定不同的主机别名和对应的私钥文件。这样你在克隆时用不同的别名,Git 就知道该用哪个密钥。
这个配置稍微复杂一点,但一旦配好,多账号切换非常顺畅。核心思路是:给每个账号起一个别名,在配置文件里把别名映射到真实主机和对应私钥,克隆时用别名代替真实主机名。
6.5 常见问题速查表
| 现象 | 可能原因 | 解决方向 |
|---|---|---|
| 推送提示密码认证被移除 | 远端地址是 HTTPS 且用密码 | 改用令牌或切换 SSH |
| 令牌无效 | 复制不全、过期、权限不足 | 检查令牌状态和权限 |
| SSH 测试超时 | 22 端口被限制 | 改用 443 端口 SSH |
| 推送仍要输密码 | 远端地址未改成 SSH | 修改远端地址 |
| 多账号冲突 | 未配置 SSH 别名 | 配置 SSH 配置文件 |
7. 我踩过的坑和实操心得
7.1 别把令牌当密码存
我见过有人把令牌直接写在脚本里,然后脚本上传到了公开仓库。结果令牌泄露,仓库被人恶意推送了一堆垃圾提交。虽然最后撤销令牌、回滚提交解决了,但折腾了大半天。令牌一定要存在环境变量或密码管理器里,绝不能硬编码在代码中。如果脚本需要令牌,用环境变量传入,并且给令牌设最小权限和短有效期。
7.2 密钥密码短语别偷懒
有些人生成密钥时直接回车不设密码短语,觉得方便。但私钥文件一旦被恶意软件扫描到,攻击者就能直接冒充你。设了密码短语,即使文件被拿走,没有密码短语也用不了。配合 SSH 代理,你每天只需要输一次,成本极低,收益极高。这个习惯我建议所有人都养成。
7.3 定期轮换凭据
不管是令牌还是密钥,都不建议用一辈子。令牌设个 90 天有效期,到期重新生成;密钥每年换一次,旧密钥删掉。轮换听起来麻烦,但真做起来就是几分钟的事。比起凭据泄露后的事故处理,这点时间投入太值了。我自己的做法是在日历上设个提醒,每季度检查一次所有凭据的状态。
7.4 先测试再批量改
如果你有多台机器、多个仓库需要改认证方式,别一次性全改。先拿一台机器、一个仓库做测试,确认推送、拉取都正常,再把方案推广到其他机器。我见过有人一口气把所有仓库的远端地址都改了,结果某个仓库的地址格式特殊,改完推不上去,又得一个个回滚。小步验证,稳妥推进。
7.5 保留一个备用方案
主力用 SSH 的同时,我建议你在密码管理器里存一个权限最小的令牌作为备用。万一某天 SSH 出问题(比如密钥文件损坏、代理异常),你可以临时用令牌顶一下,不至于卡住工作。备用令牌权限只给读,有效期设短一点,平时不用,关键时刻能救急。
7.6 注意凭据缓存的安全
凭据缓存虽然方便,但缓存期间凭据是存在内存或磁盘上的。如果你在共享机器上操作,用完记得清掉缓存。命令行里执行清除缓存的命令,把缓存的凭据删掉。在个人机器上问题不大,但在公共环境里一定要养成用完即清的习惯。
# 清除凭据缓存 git credential-cache exit8. 从认证方式看版本控制的演进
这件事往大了说,反映的是整个行业对凭据管理的认知升级。早期大家觉得“能认证就行”,后来发现密码泄露的代价太大,于是有了令牌、有了密钥、有了多因素认证。再往后,短期凭据、动态凭据、基于身份的认证会越来越普及。作为开发者,跟上这些变化不是可选项,而是必修课。
我个人的体会是,每次认证方式升级,短期内都会带来一点迁移成本,但长期看都是在降低风险、提升效率。当年从密码切到令牌时,我也觉得麻烦,但配好之后发现推送体验反而更好了,因为不用记密码、不用手动输入。后来切到 SSH 更是如此,一次配置、长期受益。
如果你现在还在用密码认证,别拖了,今天就花十分钟把它换掉。令牌也好、密钥也好,选一个适合你当前场景的方案,照着上面的步骤走一遍。配好之后你会发现,这条报错再也不会出现了,而且你的账号安全性上了一个台阶。后续如果平台再推出新的认证方式,你也能更快适应,因为底层逻辑是相通的:凭据要可管理、可撤销、可过期,权限要最小化。记住这个原则,不管认证方式怎么变,你都能从容应对。