常见的代码托管平台 GitHub,GitLab 和 BitBucket 等, 基本都会使用 Git 作为版本控制工具. 平台一般都提供两种认证方式 https 和 SSH. 了解该过程能够更加自由的配置和使用, 本文就来简单聊一下这两种认证方式.
1.HTTPS 与 SSH
Git 可以使用四种协议来传输数据: 本地协议 (Local),Git 协议, HTTPs 协议和 SSH(Secure Shell) 协议. 对于多人远程协作, 多用后两者.
超文本传输协议 http 运行于网络应用层, 是应用层通信协议, 使用下层的 TCP 协议进行传输控制.
位于不同网络终端的两个应用进程之间可以通过 http 进行通信, 典型的应用场景是浏览器和网站服务器, 是一种 C/S Model.
Https 可以看做是 http+ssl,ssl 协议位于网络应用层和传输层之间, 主要为应用层提供加密服务, https 即为 http 协议使用 ssl 协议加密传输数据.
SSH 为 Secure Shell 的缩写, 即安全外壳协议. SSH 为建立在应用层基础上的安全协议. SSH 是目前较可靠, 专为远程登录会话和其他网络服务提供安全性的协议.
常说的 SSH client 如 OpenSSH 等只是 SSH 协议的一种程序实现, 也就是 SSH client 程序支持 SSH 协议相关标准.
对于 code repo 的管理, 显然是需要加密进行身份认证的.
2.https 和 SSH 原理
2.1 https 原理
https 方式 clone 一个 repo 或者 pull 和 push 到远端只需要根据提示提供自己的 username 和 password 即可.
这种方式比价的简便和便于理解, 使用自己在平台的账号和密码进行授权并进行 repo 相关操作.
账号密码以及后续 repo 相关的传输均使用 ssl 加密. ssl 加密解密的过程完全透明.
ssl 认证需要首先验证服务器有有效的证书, 对服务器的认证是通过非对称秘钥的方式, 该非对称秘钥由第三方公证机构 CA 提供.
然后通过该非对称密钥对和服务器私密的协商后续数据传输使用的加密算法以及用于生成对称秘钥的一些随机数据.
ssl 握手协议结束后会产生只有 client 和 server 知道的对称加密秘钥, 而该秘钥也用后续所有传输数据的加密. 详细过程可以参考相关资料.
即两步:
username&pwd 验证对 repo 的操作权限 ;
ssl 对传输数据进行加密(server 身份验证和加密解密过程完全透明);
实际操作只需要用到第一步, Windows 和一些第三方 Git client 可以支持永久保存自己的账号和密码.
Windows 查看保存的账号信息:
Win 键 ->搜索 credential ->管理 Windows 凭据 -> 普通凭据(or 控制面板 -> 用户账户 -> 管理 Windows 凭据 -> 普通凭据)
2.2 SSH 原理
https 实际操作有一步, 但是操作权限验证和传输加密是分开的.
SSH 不仅可以压缩和加密传输数据还可以进行身份授权验证.
SSH 方式使用非对称加密所需的 key-pairs 完成身份验证和传输数据加密, Git client 和 server 分别需要持有非对称秘钥对中的一个.
出于安全和保密考虑, 通常由用户使用秘钥生成工具生成 RSA 密钥对, 并将其中的 public key 添加到服务端, 自己保留 private key.
SSH client 使用 private key 向服务端证明自己的身份.
SSH 看起来似乎更加的安全方便, 因为它将身份验证和账户密码分离开来, 可以单独使用秘钥来进行代码库的操作.
但是使用 SSH 的初始步骤可能有点麻烦, 这个后面介绍.
此外, private key 由文件保存, 存在丢失的风险, 对 private key 进行密码保护, 需要每次使用的时候都输入密码.
不管是 Git bash 还是其他的 Git client 都可以直接使用 https, 但是使用 SSH 需要单独的 SSH client.
The only requirement is to have the OpenSSH client installed on your system. This comes pre-installed on GNU/Linux and macOS, but not on Windows
并自己生成和管理秘钥对, 而且对于非默认路径下 rsa 密钥对, 需要额外相对复杂的处理.
2.3 比较
https 方式使用账号和密码授权, 简单易用, 便于进行权限细分管理, 而且防火墙一般会打开 http 和 https 协议的端口号 80 和 443. 可以进行匿名访问, 对于开源项目, 其他人即使没有任何权限也可以方便进行除提交之外的克隆和读取操作. 但是可能需要每个项目成员都有一个代码托管平台的账号, 而且缺乏凭证管理的话, 可能要频繁的进行账号密码输入.
SSH 方式单独使用非对称的秘钥进行认证和加密传输, 和账号密码分离开来, 不需要账号也可以访问 repo. 生成和管理秘钥有点繁琐, 需要管理员添加成员的 public key. 不能进行匿名访问, SSH 不利于对权限进行细分, 用户必须具有通过 SSH 协议访问你主机的权限, 才能进行下一步操作, 比较适合内部项目.
总的来说, https 方便快捷, SSH 的使用更加灵活.
3. 配置 SSH
如果 Git 使用 SSH 协议, 初始化设置需要三步:
使用秘钥生成工具 (SSH-keygen,puttygen 等) 生成 rsa 秘钥;
将 rsa 公钥添加到代码托管平台;
将 rsa 秘钥添加到 SSH-agent 中, 为 SSH client 指定使用的秘钥文件;
操作无误后, 然后便可以使用 SSH 方式操作 repo.
对于在默认路径~/.SSH/id_rsa 下生成的 id_rsa 密钥对, 任何 SSH client 是可以直接读取到. 可以忽略上面的最后一步以及下面将要介绍的内容.
对于第二步, 可以参照一下具体网站的操作, 对于 GitHub 和 GitLab, 可以在 settings 中 SSH key 相关的界面添加保存公钥.
下面主要介绍一下第一步和最后一步自定义秘钥对生成路径的情况.
3.1 生成 SSH 秘钥
生成 SSH key pairs 的工具有很多:
Git Bash 提供的仿真环境, 可以使用部分 Linux 命令;
Git GUI 自带的生成方式;
PuttyGen 提供可视化的生成过程;
Cygwin 提供的众多工具;
等等. Git bash 生成方式较为灵活, 下面以这个为例来介绍.
Git Bash 下直接使用 SSH-keygen 命令需要指定秘钥生成路径和保护密码. 下面是一种新的更为安全的 SSH 秘钥生成方式:
SSH-keygen -o -t rsa -b 4096 -C "your_email@163.com" -f ~/.SSH/new_dir/id_rsa
生成过程中设置的 passphrase 主要是为了防止别人盗用你的秘钥文件, 如果设置有保护密码, 首次添加 id_rsa 会要求输入保护密码用以证明秘钥是你的.
查看 rsa 秘钥 fingerprints 信息(standard SHA256 Key output):
- SSH-keygen -lf ~/.SSH/new_dir/id_rsa.pub
- (output) 4096 SHA256:myo......xac your_email@163.com (RSA)
- Old MD5 Format:
- $ SSH-keygen -E md5 -lf ~/.SSH/new_dir/id_rsa.pub
- (output) 4096 MD5:ba:......fb:8e your_email@163.com (RSA)
- 3.2 Git Bash
官网上下载的 Git 安装完成后会有 Git bash 和 Git gui 可以使用, 分别对应于 Git client 命令行和可视化图形界面.
Git bash 环境可以支持部分 Linux 命令, 其中 SSH client 默认使用的是 OpenSSH.
- $ SSH -V
- OpenSSH_7.7p1, OpenSSL 1.0.2o 27 Mar 2018
SSH client 运行时会默认使用~/.SSH/id_rsa, 假设该秘钥存在的情况下. 对于非默认路径下的秘钥, 需要为 SSH client 指定.
OpenSSH
OpenSSH 的参数来源主要是通过 ssh_config(OpenSSH SSH client configuration files)
对于 Openssh 配置方式以及优先级低到高依次为:
- etc/SSH/ssh_config ,# (system-wide file)
- ~/.SSH/config, # (user-specific file)
命令行配置 # (command line options)
ssh_config 文件的基本结构是: keyword arguments(参数名 参数值),# 为行注释符, 具体细节可以参考 man 5 ssh_config.
实际可以使用其中的任何一个设定 SSH client, 下面分别介绍这三种方式, 这里我们只关注非默认路径下秘钥文件的指定操作.
a). ssh_config
在 Windows 中安装完 Git for Windows 之后, Git 安装目录 / etc/SSH/ssh_config 找到 ssh_config, 该文件的大部分配置默认均被注释掉了.
通过添加下面的内容进行自定义秘钥的指定:
- Host GitHub.com
- Preferredauthentications publickey
- IdentityFile ~/.SSH/GitHub/id_rsa
- Host GitLab.com
- Preferredauthentications publickey
- IdentityFile ~/.SSH/GitLab/id_rsa
- b). config
~/.SSH / 目录下是没有 config 文件的, 需要自己添加, 内容和上面的 ssh_config 一样.
- c). command line
- eval $(SSH-agent -s)
- SSH-add ~/.SSH/other_id_rsa
直接运行 SSH-add 会添加默认的~/.SSH/id_rsa, 可以使用指令 SSH-add -l 查看命令行添加的 id_rsa.
命令行相对于另外两种配置方式, 每次打开 Git bash 都需要进行重新添加, 比较麻烦.
用上面任何一种方式添加指定的秘钥, 测试添加成功与否可以使用下面的命令:
- $ SSH -T Git@GitHub.com
- or
- $ SSH -T Git@GitLab.com
认证成功和失败分别返回:
- Welcome to GitLab, @your username!
- Git@GitLab.com: Permission denied (publickey).
相比较与命令行, 使用 SSH config 的方式更加方便, 而且配置文件也可以被 Git gui 使用.
注意:
Windows 平台上~ 表示的是 %userprofile% (e.g. echo %userprofile% ==> C:\Users\username )
上面通过在~/.SSH/config 中添加额外的密钥对是针对 SSH Client 为 OpenSSH, 每个 host 下面可以添加多个认证的密钥对, 使用 SSH 认证过程中会依次验证, 直到找到正确的秘钥.
SSH 密钥对设置的保护密码, 会在使用秘钥的时候要求输入, 主要为了证明秘钥的确是你的.
3.3 SourceTree
SourceTree 是一个较为流行 Git client. 会自动保存 https 方式认证的账户名和密码, 可在 tools -> options -> authentication 中管理.
在 sourcetree 中使用 SSH 方式只需要指定使用的 SSH client, 然后添加对应的 SSH 密钥即可.
方式一: tools -> options -> general -> SSH client configuration;
方式二: tools -> add SSH key;
第一种方法可以批量添加 SSH key, 之间使用分号; 分开.
SSH client configuration 中可以看到已经添加的所有的 SSH key, 同时这里可以指定特定的 SSH client(PuTTY/Plink or OpenSSH ).
由于 SSH-agent 会在 sourcetree 启动的时候开启并添加指定的 SSH key, 因此方式一添加的 SSH key, 可能要重启 sourcetree 才能生效.
配置完成后, 使用 SSH 方式 clone 一个库的时候, sourcetree 能够自动识别 repository type 说明配置是正确的.
4. 其他:
1. Git 全局设置
首次使用 Git 需要配置一下自己的用户名和邮箱, 作为每次提交者的身份, 会被记录在提交日志中.
- Git config --global user.name "your username"
- Git config --global user.email "your email"
这里设置的全局信息存放在~/.gitconfig 中, 可以使用 Git config -l 查看所有全局设置的信息.
2. https 方式缓存账号和密码
除了操作系统和第三方工具提供的凭证保存方案, 可以参考一下 GitHub 介绍的一种方式: Caching your GitHub password in Git.
还可以通过为 Git 指定凭据管理器的方式缓存凭证:
新建文件~/.Git-credentials, 内容为: https://{username}:{passwd}@GitHub.com
为~/.gitconfig 添加凭据地址:
- [credential]
- helper = store
可以通过执行命令 $ Git config --global credential.helper store 来完成. 建议使用系统凭据管理器, 不推荐这种方式.
3.knows_hosts 文件
文件~/.SSH/known_hosts 中存放的是所有已经安全连接过的服务器 (hosts) 的公钥.
Warning: Permanently added 'gitlab.com,35.231.145.151' (ECDSA) to the list of known hosts.
参考:
https://docs.gitlab.com/ee/ssh/
来源: https://www.cnblogs.com/yssjun/p/10145864.html