Help us learn about your current experience with the documentation. Take the survey.

使用 SSH 密钥与 GitLab 通信

  • Tier: Free, Premium, Ultimate
  • Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated

Git 是一个分布式版本控制系统,这意味着你可以在本地工作, 然后将你的更改分享或 推送 到服务器。在这种情况下,你推送到的服务器就是 GitLab。

GitLab 使用 SSH 协议与 Git 安全通信。 当你使用 SSH 密钥向 GitLab 远程服务器进行身份验证时, 你每次都不需要提供用户名和密码。

什么是 SSH 密钥

SSH 使用两个密钥:公钥和私钥。

  • 公钥可以分发。
  • 私钥需要保护。

上传你的公钥不可能泄露机密数据。当你需要复制或上传 SSH 公钥时, 确保不要意外复制或上传你的私钥。

你可以使用你的私钥来 签名提交, 这使你使用 GitLab 和数据的安全性更高。 然后,任何人都可以使用你的公钥验证这个签名。

详细信息请参见 非对称加密,也称为公钥加密

前置条件

要使用 SSH 与 GitLab 通信,你需要:

  • OpenSSH 客户端,它预装在 GNU/Linux、macOS 和 Windows 10 上。
  • SSH 版本 6.5 或更高版本。早期版本使用 MD5 签名,这不安全。

要查看系统中安装的 SSH 版本,运行 ssh -V

支持的 SSH 密钥类型

要与 GitLab 通信,你可以使用以下 SSH 密钥类型:

管理员可以 限制允许的密钥及其最小长度

ED25519 SSH 密钥

书籍 Practical Cryptography With Go 建议 ED25519 密钥比 RSA 密钥更安全且性能更好。

OpenSSH 6.5 在 2014 年引入了 ED25519 SSH 密钥,它们应该在大多数 操作系统上可用。

ED25519 密钥可能不被所有 FIPS 系统完全支持。更多信息请参见 issue 367429

ED25519_SK SSH 密钥

要在 GitLab 上使用 ED25519_SK SSH 密钥,你的本地客户端和 GitLab 服务器 必须安装了 OpenSSH 8.2 或更高版本。

ECDSA_SK SSH 密钥

要在 GitLab 上使用 ECDSA_SK SSH 密钥,你的本地客户端和 GitLab 服务器 必须安装了 OpenSSH 8.2 或更高版本。

RSA SSH 密钥

可用文档表明 ED25519 比 RSA 更安全。

如果你使用 RSA 密钥,美国国家标准与技术研究院在 Publication 800-57 Part 3 (PDF) 中建议密钥大小至少为 2048 位。由于 Go 的限制, RSA 密钥 不能超过 8192 位

默认密钥大小取决于你的 ssh-keygen 版本。 查看已安装 ssh-keygen 命令的 man 页面了解详细信息。

检查你是否已有现有的 SSH 密钥对

在创建密钥对之前,检查是否已经存在密钥对。

  1. 进入你的主目录。
  2. 进入 .ssh/ 子目录。如果 .ssh/ 子目录不存在, 你要么不在主目录,要么之前没有使用过 ssh。 在后一种情况下,你需要 生成 SSH 密钥对
  3. 检查是否存在以下格式的文件:
    算法 公钥 私钥
    ED25519(首选) id_ed25519.pub id_ed25519
    ED25519_SK id_ed25519_sk.pub id_ed25519_sk
    ECDSA_SK id_ecdsa_sk.pub id_ecdsa_sk
    RSA(至少 2048 位密钥大小) id_rsa.pub id_rsa
    DSA(已弃用) id_dsa.pub id_dsa
    ECDSA id_ecdsa.pub id_ecdsa

生成 SSH 密钥对

如果你没有现有的 SSH 密钥对,生成一个新的:

  1. 打开终端。

  2. 运行 ssh-keygen -t 后跟密钥类型和可选注释。 此注释包含在创建的 .pub 文件中。 你可能希望使用电子邮件地址作为注释。

    例如,对于 ED25519:

    ssh-keygen -t ed25519 -C "<注释>"

    对于 2048 位 RSA:

    ssh-keygen -t rsa -b 2048 -C "<注释>"
  3. Enter。显示如下输出:

    Generating public/private ed25519 key pair.
    Enter file in which to save the key (/home/user/.ssh/id_ed25519):
  4. 接受建议的文件名和目录,除非你正在生成 部署密钥 或想要保存在你存储其他密钥的特定目录中。

    你还可以将 SSH 密钥对专用于 特定主机

  5. 指定 密码短语

    Enter passphrase (empty for no passphrase):
    Enter same passphrase again:

    会显示确认信息,包括你的文件存储位置。

生成公钥和私钥。将公钥添加到你的 GitLab 账户 并保持私钥安全。

配置 SSH 指向不同的目录

如果你没有将 SSH 密钥对保存在默认目录中, 配置你的 SSH 客户端指向存储私钥的目录。

  1. 打开终端并运行以下命令:

    eval $(ssh-agent -s)
    ssh-add <私有 SSH 密钥的目录>
  2. 将这些设置保存在 ~/.ssh/config 文件中。例如:

    # GitLab.com
    Host gitlab.com
      PreferredAuthentications publickey
      IdentityFile ~/.ssh/gitlab_com_rsa
    
    # 私有 GitLab 实例
    Host gitlab.company.com
      PreferredAuthentications publickey
      IdentityFile ~/.ssh/example_com_rsa

有关这些设置的更多信息,请参阅 SSH 配置手册中的 man ssh_config 页面。

公钥必须对 GitLab 唯一,因为它们绑定到你的账户。 当你使用 SSH 推送代码时,你的 SSH 密钥是你唯一的标识符。 它必须唯一映射到单个用户。

更新你的 SSH 密钥密码短语

你可以更新 SSH 密钥的密码短语:

  1. 打开终端并运行以下命令:

    ssh-keygen -p -f /path/to/ssh_key
  2. 在提示符下,输入密码短语然后按 Enter

将你的 RSA 密钥对升级为更安全的格式

如果你的 OpenSSH 版本在 6.5 到 7.8 之间,你可以通过打开终端并运行 以下命令,将你的私有 RSA SSH 密钥以更安全的 OpenSSH 格式保存:

ssh-keygen -o -f ~/.ssh/id_rsa

或者,你可以使用以下命令生成具有更安全加密格式的新 RSA 密钥:

ssh-keygen -o -t rsa -b 4096 -C "<注释>"

为 FIDO2 硬件安全密钥生成 SSH 密钥对

要生成 ED25519_SK 或 ECDSA_SK SSH 密钥,你必须使用 OpenSSH 8.2 或更高版本:

  1. 将硬件安全密钥插入你的计算机。

  2. 打开终端。

  3. 运行 ssh-keygen -t 后跟密钥类型和可选注释。 此注释包含在创建的 .pub 文件中。 你可能希望使用电子邮件地址作为注释。

    例如,对于 ED25519_SK:

    ssh-keygen -t ed25519-sk -C "<注释>"

    对于 ECDSA_SK:

    ssh-keygen -t ecdsa-sk -C "<注释>"

    如果你的安全密钥支持 FIDO2 驻留密钥,你可以在 创建 SSH 密钥时启用此功能:

    ssh-keygen -t ed25519-sk -O resident -C "<注释>"

    -O resident 表示密钥应存储在 FIDO 认证器本身上。 驻留密钥更容易导入到新计算机,因为它可以通过 ssh-add -Kssh-keygen -K 直接从安全密钥加载。

  4. Enter。显示如下输出:

    Generating public/private ed25519-sk key pair.
    You may need to touch your authenticator to authorize key generation.
  5. 触摸硬件安全密钥上的按钮。

  6. 接受建议的文件名和目录:

    Enter file in which to save the key (/home/user/.ssh/id_ed25519_sk):
  7. 指定 密码短语

    Enter passphrase (empty for no passphrase):
    Enter same passphrase again:

    会显示确认信息,包括你的文件存储位置。

生成公钥和私钥。 将公钥添加到你的 GitLab 账户

使用密码管理器生成 SSH 密钥对

使用 1Password 生成 SSH 密钥对

你可以使用 1Password1Password 浏览器扩展 来:

  • 自动生成新的 SSH 密钥。
  • 使用 1Password 保险库中现有的 SSH 密钥与 GitLab 进行身份验证。
  1. 登录 GitLab。
  2. 在左侧边栏中,选择你的头像。
  3. 选择 Edit profile
  4. 在左侧边栏中,选择 SSH Keys
  5. 选择 Add new key
  6. 选择 Key,你应该会看到 1Password 助手出现。
  7. 选择 1Password 图标并解锁 1Password。
  8. 然后你可以选择 Create SSH Key 或选择现有的 SSH 密钥来填写公钥。
  9. Title 框中,输入描述,如 Work LaptopHome Workstation
  10. 可选。选择密钥的 Usage type。它可以用于 AuthenticationSigning 或两者。Authentication & Signing 是默认值。
  11. 可选。更新 Expiration date 以修改默认过期日期。
  12. 选择 Add key

有关使用 1Password 与 SSH 密钥的更多信息,请参阅 1Password 文档

将 SSH 密钥添加到你的 GitLab 账户

要使用 SSH 与 GitLab 通信,将你的公钥复制到你的 GitLab 账户:

  1. 复制你的公钥文件的内容。你可以手动复制或使用脚本。 例如,将 ED25519 密钥复制到剪贴板:

    macOS

    tr -d '\n' < ~/.ssh/id_ed25519.pub | pbcopy

    Linux(需要 xclip 包)

    xclip -sel clip < ~/.ssh/id_ed25519.pub

    Windows 上的 Git Bash

    cat ~/.ssh/id_ed25519.pub | clip

    id_ed25519.pub 替换为你的文件名。例如,RSA 使用 id_rsa.pub

  2. 登录 GitLab。

  3. 在左侧边栏中,选择你的头像。

  4. 选择 Edit profile

  5. 在左侧边栏中,选择 SSH Keys

  6. 选择 Add new key

  7. Key 框中,粘贴你的公钥内容。 如果你手动复制了密钥,确保复制整个密钥, 它以 ssh-rsassh-dssecdsa-sha2-nistp256ecdsa-sha2-nistp384ecdsa-sha2-nistp521ssh-ed25519sk-ecdsa-sha2-nistp256@openssh.comsk-ssh-ed25519@openssh.com 开头, 并可能以注释结尾。

  8. Title 框中,输入描述,如 Work LaptopHome Workstation

  9. 可选。选择密钥的 Usage type。它可以用于 AuthenticationSigning 或两者。Authentication & Signing 是默认值。

  10. 可选。更新 Expiration date 以修改默认过期日期。

    • 管理员可以查看过期日期,并在 删除密钥 时使用它们进行指导。
    • GitLab 每天在 01:00 AM UTC 检查所有 SSH 密钥。它将为所有计划在七天后过期的 SSH 密钥发送过期通知。
    • GitLab 每天在 02:00 AM UTC 检查所有 SSH 密钥。它将为所有在当天过期的 SSH 密钥发送过期通知。
  11. 选择 Add key

验证你可以连接

验证你的 SSH 密钥是否正确添加。

以下命令使用示例主机名 gitlab.example.com。将此示例主机名替换为你的 GitLab 实例的主机名,例如 git@gitlab.com。 默认情况下,GitLab 使用 git 用户名进行身份验证。如果管理员 更改了它,可能会不同。

  1. 为了确保你连接到正确的服务器,检查服务器的 SSH 主机密钥指纹。对于:

    • GitLab.com,请参阅 SSH 主机密钥指纹 文档。
    • GitLab.com 或其他 GitLab 实例,请参阅 gitlab.example.com/help/instance_configuration#ssh-host-keys-fingerprints,其中 gitlab.example.comgitlab.com(对于 GitLab.com)或 GitLab 实例的地址。
  2. 打开终端并运行以下命令,将 gitlab.example.com 替换为你的 GitLab 实例 URL:

    ssh -T git@gitlab.example.com
  3. 如果这是你第一次连接,你应该验证 GitLab 主机的真实性。如果你看到类似消息:

    The authenticity of host 'gitlab.example.com (35.231.145.151)' can't be established.
    ECDSA key fingerprint is SHA256:HbW3g8zUjNSksFbqTiUWPWg2Bq1x8xdGUrliXFzSnUw.
    Are you sure you want to continue connecting (yes/no)? yes
    Warning: Permanently added 'gitlab.example.com' (ECDSA) to the list of known hosts.

    输入 yes 并按 Enter

  4. 再次运行 ssh -T git@gitlab.example.com 命令。你应该收到一条 Welcome to GitLab, @username! 消息。

如果欢迎消息没有出现,你可以通过在详细模式下运行 ssh 进行故障排除:

ssh -Tvvv git@gitlab.example.com

为不同的仓库使用不同的密钥

你可以为每个仓库使用不同的密钥。

打开终端并运行以下命令:

git config core.sshCommand "ssh -o IdentitiesOnly=yes -i ~/.ssh/private-key-filename-for-this-repository -F /dev/null"

此命令不使用 SSH Agent,需要 Git 2.10 或更高版本。有关 ssh 命令选项的更多信息, 请参阅 sshssh_configman 页面。

查看你的 SSH 密钥

要查看你账户的 SSH 密钥:

  1. 在左侧边栏中,选择你的头像。
  2. 选择 Edit profile
  3. 在左侧边栏中,选择 SSH Keys

你现有的 SSH 密钥列在页面底部。信息包括:

  • 密钥的标题
  • 公钥指纹
  • 允许的使用类型
  • 创建日期
  • 最后使用日期
  • 过期日期

删除 SSH 密钥

你可以撤销或删除你的 SSH 密钥以永久将其从你的账户中移除。

如果你使用密钥签名提交,删除你的 SSH 密钥会有额外的影响。更多信息请参见 使用已删除 SSH 密钥的签名提交

撤销 SSH 密钥

如果你的 SSH 密钥被泄露,撤销该密钥。

前置条件:

  • SSH 密钥必须具有 SigningAuthentication & Signing 使用类型。

要撤销 SSH 密钥:

  1. 在左侧边栏中,选择你的头像。
  2. 选择 Edit profile
  3. 在左侧边栏中,选择 SSH Keys
  4. 在要撤销的 SSH 密钥旁边,选择 Revoke
  5. 选择 Revoke

删除 SSH 密钥

要删除 SSH 密钥:

  1. 在左侧边栏中,选择你的头像。
  2. 选择 Edit profile
  3. 在左侧边栏中,选择 SSH Keys
  4. 在要删除的密钥旁边,选择 Remove ( remove )。
  5. 选择 Delete

在单个 GitLab 实例上使用不同的账户

你可以使用多个账户连接到单个 GitLab 实例。你 可以通过使用 上一主题 中的命令来做到这一点。 但是,即使你将 IdentitiesOnly 设置为 yes,如果存在 Host 块之外的 IdentityFile,你仍然无法登录。

相反,你可以在 ~/.ssh/config 文件中为主机分配别名。

  • 对于 Host,使用类似 user_1.gitlab.comuser_2.gitlab.com 的别名。高级配置 更难维护,当你使用 git remote 等工具时, 这些字符串更容易理解。
  • 对于 IdentityFile,使用私钥的路径。
# User1 Account Identity
Host <user_1.gitlab.com>
  Hostname gitlab.com
  PreferredAuthentications publickey
  IdentityFile ~/.ssh/<example_ssh_key1>

# User2 Account Identity
Host <user_2.gitlab.com>
  Hostname gitlab.com
  PreferredAuthentications publickey
  IdentityFile ~/.ssh/<example_ssh_key2>

现在,要为 user_1 克隆仓库,在 git clone 命令中使用 user_1.gitlab.com

git clone git@<user_1.gitlab.com>:gitlab-org/gitlab.git

要更新别名为 origin 的先前克隆的仓库:

git remote set-url origin git@<user_1.gitlab.com>:gitlab-org/gitlab.git

私钥和公钥包含敏感数据。确保文件权限 使它们对你可读,但对他人不可访问。

配置双因素认证 (2FA)

你可以为 Git over SSH 设置双因素认证 (2FA)。你应该使用 ED25519_SKECDSA_SK SSH 密钥。

在 Eclipse 上使用 EGit

如果你正在使用 EGit,你可以 将 SSH 密钥添加到 Eclipse

在 Microsoft Windows 上使用 SSH

如果你运行的是 Windows 10,你可以使用 Windows Subsystem for Linux (WSL)WSL 2,它 预装了 gitssh,或者安装 Git for Windows 来 通过 PowerShell 使用 SSH。

在 WSL 中生成的 SSH 密钥不能直接用于 Git for Windows,反之亦然, 因为它们有不同的主目录:

  • WSL:/home/<user>
  • Git for Windows:C:\Users\<user>

你可以复制 .ssh/ 目录以使用相同的密钥,或者在每种环境中生成密钥。

如果你运行的是 Windows 11 并使用 OpenSSH for Windows,确保 HOME 环境变量设置正确。否则,你的私有 SSH 密钥可能找不到。

替代工具包括:

覆盖 GitLab 服务器上的 SSH 设置

GitLab 与系统安装的 SSH 守护进程集成,并通过一个用户 (通常名为 git)处理所有访问请求。通过 SSH 连接到 GitLab 服务器的用户由他们的 SSH 密钥而不是用户名来标识。

在 GitLab 服务器上执行的 SSH 客户端 操作作为该用户执行。 你可以修改此 SSH 配置。例如,你可以指定 一个私有 SSH 密钥供该用户用于身份验证请求。但是,这种做法 不受支持,并且强烈不建议这样做,因为它会带来重大安全风险。

GitLab 会检查此条件,如果你的服务器以这种方式配置, 它会将你引导到本节。例如:

$ gitlab-rake gitlab:check

Git user has default SSH configuration? ... no
  Try fixing it:
  mkdir ~/gitlab-check-backup-1504540051
  sudo mv /var/lib/git/.ssh/id_rsa ~/gitlab-check-backup-1504540051
  sudo mv /var/lib/git/.ssh/id_rsa.pub ~/gitlab-check-backup-1504540051
  For more information see:
  doc/user/ssh.md#overriding-ssh-settings-on-the-gitlab-server
  Please fix the error above and rerun the checks.

尽快删除自定义配置。这些自定义配置 明确不受支持,并且随时可能停止工作。

验证 GitLab SSH 所有权和权限

GitLab SSH 文件夹和文件必须具有以下权限:

  • 文件夹 /var/opt/gitlab/.ssh/ 必须由 git 组和 git 用户拥有,权限设置为 700
  • authorized_keys 文件必须具有权限 600
  • authorized_keys.lock 文件必须具有权限 644

要验证这些权限是否正确,运行以下命令:

stat -c "%a %n" /var/opt/gitlab/.ssh/.

设置权限

如果权限错误,登录应用程序服务器并运行:

cd /var/opt/gitlab/
chown git:git /var/opt/gitlab/.ssh/
chmod 700  /var/opt/gitlab/.ssh/
chmod 600  /var/opt/gitlab/.ssh/authorized_keys
chmod 644  /var/opt/gitlab/.ssh/authorized_keys.lock