在日常的服务器运维和开发中,我们经常需要在 Ubuntu 服务器上拉取或推送 Git 仓库的代码。但如果服务器处于特定的网络环境下(比如需要走代理),或者对接的是近年来更新了安全策略的 GitLab,就很容易遇到网络不通和鉴权失败的连环报错。
今天这篇博客,就带大家复盘一次经典的 Git 踩坑过程:从修改 Git 代理,到解决 GitLab 密码访问被拒,再到配置 Ubuntu 自动保存凭据。
场景一:代理 IP 变更导致的 “No route to host”
问题现象
在使用 sudo git push 提交代码时,终端抛出了如下网络报错:
fatal: unable to access 'https://gitlab.com/xxx/xxx.git/': Failed to connect to 172.30.129.12 port 63106: No route to host
原因分析
这说明 Git 还在尝试连接一个已经失效的旧代理 IP(172.30.129.12)。需要注意的是,因为命令中带了 sudo,Git 实际上是以 root 用户的身份在运行。它读取的是 root 用户的全局配置(/root/.gitconfig)或当前项目的本地配置(.git/config),而不是你普通用户的配置。
解决方案
我们需要清除旧的代理,并配置新的可用代理(假设新代理 IP 为 192.168.61.61,端口不变)。
第一步:清除残留的旧代理
为了保险起见,建议把全局和项目本地的旧代理都清空:
# 清除 root 用户的全局代理
sudo git config --global --unset http.proxy
sudo git config --global --unset https.proxy
# 清除当前仓库的本地代理
sudo git config --local --unset http.proxy
sudo git config --local --unset https.proxy
第二步:设置新代理
建议直接设置在当前仓库的本地配置中(--local),避免影响服务器上的其他项目:
sudo git config --local http.proxy http://192.168.61.61:63106
sudo git config --local https.proxy http://192.168.61.61:63106
通过 sudo git config -l | grep proxy 确认配置生效后,网络打通,但紧接着可能就会遇到第二个坑。
场景二:GitLab 报错 “HTTP Basic: Access denied”
问题现象
网络畅通后,再次执行 sudo git push,输入了正确的 GitLab 账号和密码,却得到了如下报错:
remote: HTTP Basic: Access denied. If a password was provided for Git authentication, the password was incorrect or you're required to use a token instead of a password...
fatal: Authentication failed for 'https://gitlab.com/...'
原因分析
这个错误并非你记错了密码。近年来,为了提高安全性,GitLab(以及 GitHub、Gitee 等)已经全面废弃了通过 HTTPS 直接使用账户原密码进行 Git 操作的支持。我们必须使用“个人访问令牌(Personal Access Token, 简称 PAT)”来代替传统的密码。
解决方案
我们需要去 GitLab 后台生成一个 Token。
- 登录 GitLab 网页端。
- 点击右上角头像 -> Preferences (偏好设置) -> 左侧导航栏 Access Tokens (访问令牌)。
- 点击 Add new token。
- 填写 Token 名称(如 "Ubuntu-Server-Push")。
- 核心步骤: 在 Scopes (权限范围) 中,务必勾选
read_repository和write_repository。 - 点击创建。立刻复制生成的 Token 字符串(以
glpat-开头),因为离开页面后它将永远隐藏。
回到终端再次运行 sudo git push:
- Username: 输入你的 GitLab 用户名。
- Password: 粘贴你刚才生成的 Token,不要再输入原密码!
验证通过,代码推送成功。
场景三:如何让 Ubuntu 记住这个长 Token?
Token 虽然安全,但是一长串毫无规律的字符,每次推送都要手动复制粘贴显然反人类。既然验证已经跑通,我们需要让服务器记住这个凭据。
这里提供两种主流的持久化配置方式,注意都需要带上 sudo 运行以匹配我们推送时的执行环境。
方式 A:开启 Git 凭据存储(推荐方案)
这种方式会将输入的账密保存在服务器的本地文件中,适用于信任度较高的个人或内部服务器。
运行以下命令,开启全局 credential store:
sudo git config --global credential.helper store
开启后,手动执行一次 sudo git push,Git 会最后一次要求你输入用户名和 Token。验证成功后,Git 会自动将这些信息明文保存到 /root/.git-credentials 文件中。以后的推送将如丝般顺滑,不再弹窗。
方式 B:将 Token 嵌在项目 URL 中(免全局配置)
如果你不想在全局保留凭据,或者只想让当前项目生效,可以直接把账号和 Token 写入当前仓库的远程地址中。
在当前项目目录下执行:
sudo git remote set-url origin https://<你的GitLab用户名>:<你的Token>@gitlab.com/你的项目路径.git
(注意替换 <你的GitLab用户名> 和 <你的Token> 为真实值,并去掉尖括号)
这会将信息直接写死在当前项目的 .git/config 中,同样能达到免密推送的效果。
总结
在 Linux 环境下操作 Git,经常会因为网络和安全策略的变动遇到阻碍。回顾本次踩坑经历,有三个核心要点值得谨记:
- 警惕
sudo的上下文:sudo git读写的是 root 的配置,不要与当前普通用户的配置混淆。 - 跟进平台的安全策略: 密码鉴权已是过去式,习惯使用 Personal Access Token (PAT) 才是现代开发者应有的姿态。
- 善用凭据管理: 合理配置
credential.helper,把繁琐的重复劳动交给系统。
希望这篇复盘能帮你少走一些弯路。Happy Coding!
版权属于:soarli
本文链接:https://blog.soarli.top/archives/1100.html
转载时须注明出处及本声明。