在受限网络下把 Git 用起来:代理、HTTPS/SSH、PAT 保存、系统密钥环(libsecret)完整指南

适用读者:公司/校园网络封 22 端口、需要走代理访问 GitHub/GitLab 的开发者;希望用 HTTPS + 系统密钥环长期保存个人访问令牌(PAT),并解决诸如
ssh: connect to host github.com port 22: Connection timed out
git: 'credential-manager-core' 不是一个 git 命令
git: 'credential-libsecret' 不是一个 git 命令
等问题。


TL;DR(可直接按这套操作)

  1. 用 HTTPS 远端替代 SSH(最省事,受代理支持)

  2. 设置 Git 代理(只影响 HTTPS,不影响 SSH)

  3. 安装并启用系统密钥环助手 git-credential-libsecret,把 PAT 安全保存到 Keyring

  4. 触发一次认证git push --dry-run)后就不再反复输入账号/令牌

文末附带排障清单与“一键脚本”。


1. 先搞清楚:Git 的两条传输路线 & 代理差异

  • HTTPS 路线https://github.com/owner/repo.git

    • git config http(s).proxy 与环境变量 http_proxy/https_proxy 影响

    • 支持使用 PAT(个人访问令牌)+ 凭据助手 保存

  • SSH 路线git@github.com:owner/repo.gitssh://...

    • 不走 http(s).proxy;要么 直通 22 端口,要么自己给 OpenSSH 配代理

    • 可改成 SSH over 443ssh.github.com:443)规避 22 端口封锁

你之前报 port 22 timeout,就是走了 SSH;而你设置的 http(s).proxy 只对 HTTPS 生效,所以无效。最简单的做法是把远端改为 HTTPS


2. 配置 Git 代理(HTTPS 场景)

查看当前代理:

git config -l --show-origin | grep -i proxy
env | grep -i _proxy

设置代理(示例):

# HTTP/HTTPS 统一走公司代理(如有账号:user:pass@)
git config --global http.proxy  http://proxy.example.com:8080
git config --global https.proxy http://proxy.example.com:8080
 
# 仅对特定域生效
git config --global http.https://github.com.proxy  http://proxy.example.com:8080
 
# 直连内网域名
git config --global http.noProxy 'localhost,127.0.0.1,.intranet.local'

注意:这些只影响 HTTPS,不影响 SSH。


3. 把远端从 SSH 切到 HTTPS(推荐)

git remote -v
# 若看到 git@github.com:owner/repo.git(SSH),改成 HTTPS:
git remote set-url origin https://github.com/owner/repo.git

4. 在 Linux 使用“系统密钥环”保存 PAT(libsecret 方案)

4.1 背景

  • Git 通过“凭据助手 (credential helper)”把用户名/PAT 存进 系统密钥环(Secret Service / GNOME Keyring)

  • Linux 对应的助手叫 git-credential-libsecret

  • 有些发行版不自带二进制包,需要从 Git 的 contrib/credential/libsecret 源码编译——很快

4.2 一键安装(优先走系统包;没有就编译)

A. 如果系统能装到同名包(有些发行版提供):

sudo apt update
sudo apt install -y git-credential-libsecret gnome-keyring
git config --global --replace-all credential.helper libsecret

B. 如果提示 “无法定位软件包 git-credential-libsecret”(常见):从 contrib 源码编译

方式 B-1:系统自带了 contrib 源码(多数情况下有)

sudo apt update
sudo apt install -y build-essential libsecret-1-0 libsecret-1-dev libglib2.0-dev git
 
# 进入 contrib/credential/libsecret
cd /usr/share/doc/git/contrib/credential/libsecret || { echo "未找到 contrib 目录,改用 B-2"; exit 1; }
 
sudo make   # 生成 git-credential-libsecret
 
# 安装到 Git 的 exec-path,确保 Git 能找到它
sudo install -m 0755 git-credential-libsecret "$(git --exec-path)/"
 
# 配置使用系统密钥环
git config --global --replace-all credential.helper libsecret

方式 B-2:如果系统没有带 contrib 源码:从与本机 Git 版本匹配的源码包获取

ver=$(git --version | awk '{print $3}')
wget "https://www.kernel.org/pub/software/scm/git/git-$ver.tar.xz"
tar xf "git-$ver.tar.xz"
cd "git-$ver/contrib/credential/libsecret"
 
sudo apt update
sudo apt install -y build-essential libsecret-1-0 libsecret-1-dev libglib2.0-dev
make
sudo install -m 0755 git-credential-libsecret "$(git --exec-path)/"
 
git config --global --replace-all credential.helper libsecret

验证助手就位:

git --exec-path
ls -l "$(git --exec-path)/git-credential-libsecret"
git config -l --show-origin | grep -i 'credential.helper'

如果仍然报 “git: 'credential-libsecret' 不是一个 git 命令”,一般是 Git 的 exec-path 与安装位置不一致

  • 直接指定绝对路径最稳:

    git config --global --replace-all credential.helper "$(git --exec-path)/git-credential-libsecret"
  • 或者把助手软链到当前 Git 的 exec-path:

    sudo ln -sf /usr/lib/git-core/git-credential-libsecret "$(git --exec-path)/git-credential-libsecret"

4.3 触发一次认证并保存

# 需要 HTTPS 远端;公开仓库可能不需要认证,推荐如下方式更容易触发:
git push --dry-run origin HEAD
# 用户名:GitHub 用户名
# 密码:PAT(个人访问令牌)

成功一次后,凭据即保存到系统密钥环,之后 fetch/push 不再反复输入。

桌面环境通常自动运行 gnome-keyring-daemon。纯终端会话可临时启动:
gnome-keyring-daemon --start --components=secrets >/dev/null


5.(备选)如果坚持用 SSH:走 443 + 代理

HTTP 代理(CONNECT)示例:

# ~/.ssh/config
Host github.com
  HostName ssh.github.com
  Port 443
  User git
  ProxyCommand connect -H proxy.example.com:8080 %h %p   # 需安装 connect-proxy

SOCKS5 代理示例:

Host github.com
  HostName ssh.github.com
  Port 443
  User git
  ProxyCommand nc -X 5 -x 127.0.0.1:1080 %h %p           # 需 netcat-openbsd

测试:

ssh -T github.com    # 预期输出 Hi <username>...

6. 常见问题 & 排障清单

6.1 port 22: Connection timed out

  • 说明 SSH 被拦。两种解法:

    • 改用 HTTPS 远端(最简单):git remote set-url origin https://...

    • SSH over 443 + ProxyCommand(见上节)

6.2 设置了 credential.helper 但“没有触发认证”

  • git config 只是在指定助手,不会主动认证。

  • 只有在 需要凭据 的操作(私有仓库 fetch/push、或 push --dry-run)时才会触发。

  • 远端如果是 SSH不会走 HTTPS 助手(GCM/libsecret)。

6.3 credential.helper 有多个取值

git config --global --replace-all credential.helper libsecret
# 或先清后设:
git config --global --unset-all credential.helper
git config --global --add credential.helper libsecret

必要时清理 local/system 作用域:

git config --local  --unset-all credential.helper  # 在仓库里执行
sudo git config --system --unset-all credential.helper

6.4 git: 'credential-manager-core' 不是一个 git 命令

  • 说明配置里残留了 manager-core,但机器上没装 GCM。

  • 两种修复

    • 改用系统密钥环:清理后设为 libsecret(见第 4 节)

    • 或正确安装 GCM(见下一节,可选)

6.5 git: 'credential-libsecret' 不是一个 git 命令

  • 说明 Git 找不到 git-credential-libsecret

    • 没装 → 按 4.2 编译并安装

    • 装了但不在 exec-path → 用绝对路径或软链到 $(git --exec-path)/

6.6 代理相关

  • 查看 HTTPS 细节:

    GIT_CURL_VERBOSE=1 git ls-remote https://github.com/git/git.git
  • 407 需要认证 → 代理地址加上 user:pass@;或配置 http.proxyAuthMethod basic|negotiate|ntlm|digest

  • 自签发/抓包代理证书 → 更安全做法是给 Git 指定 http.sslCAInfo 指向代理的 CA 证书(不建议关校验)


7.(可选)改用 Git Credential Manager(GCM)

如果你更喜欢 GCM 的图形/设备码登录体验:

# 安装(以 .deb 为例;从官方 Release 下载最新版)
sudo dpkg -i gcm-linux_amd64.X.Y.Z.deb || sudo apt -f install -y
 
# 接入 Git
git-credential-manager configure
 
# 验证
git-credential-manager --version
git config -l | grep credential.helper
 
# 仍想把凭据保存在系统密钥环(而非 GCM 内置存储),可指定:
git config --global credential.credentialStore secretservice

记得把远端改成 HTTPS 才会触发 GCM。


8. 速查指令合集(拷贝即用)

切 HTTPS + 设置代理 + 启用系统密钥环(优先尝试 A,若失败用 B)

A. 系统包存在的情况:

# 代理(按需)
git config --global http.proxy  http://proxy.example.com:8080
git config --global https.proxy http://proxy.example.com:8080
git config --global http.noProxy 'localhost,127.0.0.1,.intranet.local'
 
# 远端切 HTTPS(替换 owner/repo)
git remote set-url origin https://github.com/owner/repo.git
 
# 安装助手 + 启用
sudo apt update
sudo apt install -y git-credential-libsecret gnome-keyring
git config --global --replace-all credential.helper libsecret
 
# 触发一次保存(只需一次)
git push --dry-run origin HEAD

B. 系统包不存在时(从 contrib 编译安装):

sudo apt update
sudo apt install -y build-essential libsecret-1-0 libsecret-1-dev libglib2.0-dev git
 
# 优先找系统自带的 contrib;若失败,走源码包
if cd /usr/share/doc/git/contrib/credential/libsecret 2>/dev/null; then
  sudo make
else
  ver=$(git --version | awk '{print $3}')
  wget "https://www.kernel.org/pub/software/scm/git/git-$ver.tar.xz"
  tar xf "git-$ver.tar.xz"
  cd "git-$ver/contrib/credential/libsecret"
  make
fi
 
sudo install -m 0755 git-credential-libsecret "$(git --exec-path)/"
git config --global --replace-all credential.helper libsecret
 
# 切 HTTPS(替换 owner/repo)
git remote set-url origin https://github.com/owner/repo.git
 
# 首次触发认证保存
git push --dry-run origin HEAD

检查与排错

# 看 helper 最终值与来源
git config -l --show-origin | grep -i 'credential.helper'
 
# 助手位置 & Git exec-path
git --exec-path
ls -l "$(git --exec-path)/git-credential-libsecret"
 
# 当前远端(是否 HTTPS)
git remote -v
 
# 代理是否生效(HTTPS)
GIT_CURL_VERBOSE=1 git ls-remote https://github.com/git/git.git

结语

  • 首选方案HTTPS + 系统密钥环(libsecret),简单稳妥、受代理支持、跨环境一致

  • 网络封锁严重又想用 SSH:SSH over 443 + ProxyCommand

  • 凭据保存报错,多半是助手未安装/路径不对/配置重复,按第 6 节清理与定位即可

有了这套配置,后续拉取/推送都会走代理且自动用密钥环里的令牌,再也不用每次输入用户名和 PAT 了。