简述
您需要设置ssh配置。请参见以下内容。
详细说明
通常情况下,URL(或更准确地说是URI)的语法如下:
<scheme>:[//<authority>]<path>[?query][#fragment]
更详细的描述可以在维基百科上找到。使用ssh
URL时,scheme
是ssh
,冒号:
和双斜杠//
后面跟着user@host
和另一个斜杠:
ssh://user@github.com/user/repo.git
例如。这样可以避免交互的必要性:用户名在命令中直接提供。由于ssh使用公钥加密,因此不需要密码,虽然在某些设置中可能需要提供密码短语以访问私钥。这意味着ssh可以在没有人类交互的情况下工作,这对于自动化计算机更新非常重要。(我们将在下面更详细地讨论这个问题。)
另一方面,要使用HTTPS URL,通常会编写以下内容:
https://github.com/user/repo.git
因为HTTPS身份验证通常是交互式的。因此,这里假设系统可以弹出某种身份验证交互器,用户在其中输入用户名和令牌或密码。
无论哪种情况,URI都可以容纳用户名(甚至是明文密码),但预期的使用情况不同:ssh不需要具有手和眼睛的用户,而http(s)需要。因此,它们的默认值不同。
值得注意的是,Git本身并不通过将认证部分推到另一个程序(ssh)或库(libcurl)以及用于https的单独凭据助手(外部程序)来进行身份验证,从而使其自己变得更加干净。通过这样做,它将细节留给操作系统处理,因为ssh、libcurl和各种凭据助手都针对每个操作系统进行了定制。
Git有自己特殊的伪URL语法:
[user@]host:path
是以下缩写:
ssh://[user@]host/path
这与命令行ssh如何处理可选用户和主机部分相匹配。
您可以通过选择适当的(针对您的操作系统)凭据助手来自动化https的某些或所有内容。由于它们在不同的操作系统上差异很大,因此很复杂。如果仅考虑ssh,那么它会更简单,因为它花费的时间较短,没有分散到不同的操作系统上(即使在这种情况下,它也可能变得复杂)。
如何使用ssh自动化所有或几乎所有事情
至少需要了解ssh的工作原理,至少要了解高级别的内容。(除非出现问题,否则您不需要知道密钥交换操作的所有细节。)ssh系统“希望”是安全的,这意味着不仅要向GitHub保证您确实是您本人,而且还要向您保证您连接到的计算机(认为它是GitHub)确实是GitHub。
后者通过一种常被缩写为TOFU的系统运作,即首次使用时信任。这与HTTPS/SSL截然不同(并且更简单),因为HTTPS/SSL使用认证机构和信任链,而不是TOFU:第一次您让计算机调用GitHub的计算机时,GitHub的计算机会向您的计算机提供一个秘密。您的计算机会说:“嗯,这是我第一次看到这个。您是否想信任他们是他们所说的人?”具体来说:
The authenticity of host ... can't be established. ...
Are you sure you want to continue connecting (yes/no)?
如果你回答“是”,ssh默认会记录密码,下一次当你再次访问相同的主机并提供相同的密码时,它会认为你正在访问同一个主机。这在实践中非常有效。(你可以调整此设置,但通常最好让它自动处理。)
假设你已经确认github.com是他们所声称的人,而不是由于某些奇怪的故障而被篡改成了usurper.evil,那么你的ssh现在告诉他们的ssh,你想以某个用户名登录到他们的主机。这就是Git变得有点奇怪的地方,因为大多数托管服务器让“全世界的每个人”都使用用户git登录。
为了实现这一点,您可以每次设置URL时编写
git@host
,例如
ssh://git@github.com/user/repo.git
,或者您可以使用您的ssh配置文件——在
~/.ssh/config
或
$HOME/.ssh/config
或类似位置找到,具体取决于您的操作系统和shell——将
git@
设置为该主机或某些主机的默认值。这样,如果您不提供用户名——例如只输入
ssh github.com
——您的ssh将提供用户名
git
。要做到这一点,您需要编写:
Host github.com
User git
在你的.ssh/config
中。
但是,如果你声称在github.com上是用户git
,那么github.com怎么知道你真正的身份呢?这就是公钥和私钥的作用。
值得一提的是,ssh并不一定需要在此处使用公钥。你可以使用“键盘交互”方法登录到某个主机。在这里,你提供正确的用户名在user@host
部分,然后他们要求你的ssh提供密码。你的ssh从你那里读取密码,使用会话密钥加密它,以使其不以明文形式发送,然后他们使用该密钥解密它并尝试它。但是对于Git与GitHub的使用,我们从一开始就不使用此方法。
要使用公钥/私钥对,您需要在尝试使用ssh与GitHub通信之前运行
ssh-keygen
。 ssh-keygen程序有许多可选参数,这些参数因您的ssh版本和操作系统而异,请查阅相应的文档以获取详细信息。 ssh-keygen的输出是其中之一:有一个可以提供给任何人的公钥,以及一个保持私密的私钥。
您的公钥将进入一个文件,该文件的名称以
.pub
结尾,例如,如果您将特定的GitHub密钥存储在文件中,则为
~/.ssh/id_rsa.github.pub
(就像我一样)。 这个文件中有一行相当长的内容,它将以
ssh-rsa
或
ecdsa-sha2
-something开头,通常以您告诉
ssh-keygen
放在其中的电子邮件地址结束(但此电子邮件地址仅供参考)。
你的私钥放在另一个文件中,文件名与没有.pub
结尾的文件名相同。这个文件要长得多,由许多较短的行组成,例如,如果是RSA密钥,则以-----BEGIN RSA PRIVATE KEY-----
开头。这个密钥只有你自己知道:它是秘密的。
现在,你通过GitHub的网页和Web浏览器使用你的GitHub帐户和密码(而不是ssh的任何公钥/私钥)登录GitHub,并导航到存储ssh密钥的页面。然后,在此处输入你的公钥。请参见GitHub文档中的此处和此处;请注意,GitHub会进行一些神奇的浏览器检测,试图为你提供特定于操作系统的指示,但并不总是有效,因此有时你可能需要单击Mac / Windows / Linux选择器,以获取你打算使用的操作系统的说明,而不是你正在浏览的操作系统的说明。
要声明在GitHub上的身份,你需要将之前存储在GitHub上的公钥发送到GitHub,以证明这是你的身份。由于公钥非常庞大且独一无二,GitHub可以通过查看谁先前提供了这个特定的公钥来确定你的身份。但由于这是一个公钥,GitHub还不能完全信任你所声称的身份。因此,GitHub会生成一组随机字节作为秘密,并使用公钥对其进行加密后发送给你。
如果你能轻松解密这些字节,那就意味着你拥有相应的私钥。没有私钥,至少理论上而言,解密将需要多年的计算时间。因此,如果你的计算机可以将字节返回给GitHub,那么你就是你自己,拥有与你发送的公钥相对应的私钥。
这就是GitHub如何知道你是谁。你是你自己,因为:
- 你向他们提供了公钥,声称你是Jeanluca(或其他人),并且
- 你正确地解密了他们发送的字节作为回复,表明你也拥有相应的私钥。
你拥有密钥对的两个部分:当你发送公共部分时,你就是之前所声称的那个人。你只需发送公共部分即可作出这一声明:GitHub忽略(嗯... 实际上忽略)git@github.com
中的git@
部分(但你仍然需要发送它)。
在复杂情况下使其工作
有些人需要以两个或更多不同的身份验证到单个Web托管系统(如GitHub)。例如,拥有“工作ID”——公司身份,并且想要使用工作ID访问与工作相关的存储库,同时使用个人ID访问个人存储库,这是非常普遍的。
有一种使用ssh的“虚拟主机名”约定的简单方法来实现这一点。您仍然像往常一样生成普通的密钥对,但是您让ssh-keygen
将它们保存在具有易于区分名称的文件中,例如:
.ssh/id_rsa.github.work .ssh/id_rsa.github.work.pub
.ssh/id_rsa.github.play .ssh/id_rsa.github.play.pub
你需要在GitHub上安装两个公钥,分别对应工作和娱乐的“你”。现在你需要让ssh提供正确的密钥。Ssh有能力尝试多个密钥,这是一种处理方法,但并不是最好的方法,因为这意味着你可能会意外使用错误的密钥对,这通常会在安全日志中显示,并引起安全人员的警报。(GitHub的运营商可能不会介意,但如果你在公司服务器上使用同样的技术,他们可能会介意。)你还可能触发攻击防御软件:如果你拿着一百万个密钥来到一个服务器,然后开始尝试所有的密钥,服务器软件可能会决定你不好,将你转移到一个假系统上,让你忙碌而试图追踪你。因此,理想情况下,你应该让ssh提供正确的密钥,这可以很容易地实现!在你的.ssh/config文件中,你可以列出:
Host gh-work
Hostname github.com
User git
IdentityFile ~/.ssh/id_rsa.github.work.pub
IdentitiesOnly yes
Host gh-play
Hostname github.com
User git
IdentityFile ~/.ssh/id_rsa.github.play.pub
IdentitiesOnly yes
例如。在这里,您告诉ssh如果运行
ssh gh-work
,ssh应连接到
github.com
,尝试作为用户
git
登录,并仅提供
~.ssh/id_rsa.github.work.pub
中的身份验证。(根据您的ssh设置和其他项目,您可能需要在此处列出私钥文件而不是公钥文件。首先尝试公钥文件。)同样,如果运行
ssh gh-play
,ssh应像以前一样连接到
github.com
,但这次使用“play”身份。
现在,您只需要使用伪造的URL配置您的Git存储库:
git clone ssh://gh-play/me/myrepo.git
要克隆您的“play user”存储库,并且:
git clone ssh://gh-work/corp/corprepo.git
要克隆一些企业“工作”存储库。存储库的URL控制你声称的身份,你声称的身份控制你是否有访问权限。一旦你克隆了存储库,你就拥有了所需的URL,它以名称“origin”存储,从此一切都可以正常运行。
请注意,在使用ssh-keygen时,必须使用真实主机名(在本例中为github.com),而不是假名如gh-work或gh-play。ssh-keygen代码不读取.ssh/config文件,并不知道gh-work代表github.com。
测试所有这些
运行:
ssh -Tv git@github.com
或者:
ssh -Tv gh-play
例如,将测试过程的
ssh部分。这里不涉及Git。
-v
选项告诉ssh打印详细的调试信息,以便您可以观察密钥是否传输到GitHub(或其他地方)。这个初始测试还记录了主机指纹在您的
~/.ssh/known_hosts
文件中,以便Git进行的未来连接不会问您是否信任GitHub。
-T
选项(也包括
-v
选项)并不是必需的:它只是告诉您的ssh不需要尝试使用伪终端,这将避免某些错误消息。如果一切顺利,GitHub将打印以下形式的消息:
Hi _______! You've successfully authenticated, but ...
(填入空白并完善...
)。 填好的空白显示了您的ssh密钥对成功声明的GitHub账户。
如果事情进行得不顺利,在这里,-v
的调试输出可以帮助找出原因。请注意,它非常长; 如果它不够长或详细,请使用-vv
或-vvv
使其更长更详细。
摘要
要使用与GitHub或类似服务的ssh:
- 配置您的ssh。
- 生成一个或多个密钥对,并将公共密钥存储在GitHub或类似网站上,如有必要,进一步配置您的ssh。
- 使用
ssh -Tv git@github.com
或类似命令进行测试。不同的托管网站有不同的方式告诉您是否成功;大多数网站都会有某种方式告诉您。
- 现在尝试使用包含您选择用于访问托管站点的主机名的ssh URL(s)和您设置的ssh ID(s)来克隆
git clone
。请记住,您只能克隆现有存储库;如果您需要在托管网站上创建新的存储库,则通常必须通过其Web界面进行操作。
请务必使用
ssh URL。这些URL以
ssh://
开头,或者您可以使用
user@host:path/to/repo.git
语法,但这只是为了让您少输入六个字母;比较
ssh://github.com/me/repo.git
(28个字母)和
github.com:me/repo.git
(22个字母)。一旦您输入了URL,之后就只需使用
origin
(六个字母)即可。
ssh
的问题。我把它改成了https
,然后它就能工作了(可能是因为我有个个人访问令牌)。但是这使我想知道,我该怎么解决ssh
的问题呢? - Jeanluca Scaljeri