有必要先來了解什么是SSH和什么是SSH key稚矿。
SSH
Secure Shell (SSH) 是一個允許兩臺電腦之間通過安全的連接進行數(shù)據(jù)交換的網(wǎng)絡(luò)協(xié)議。通過加密保證了數(shù)據(jù)的保密性和完整性掂之。SSH采用公鑰加密技術(shù)來驗證遠程主機咆爽,以及(必要時)允許遠程主機驗證用戶球拦。
傳統(tǒng)的FTP、Telnet是再網(wǎng)絡(luò)中明文傳送數(shù)據(jù)续搀、用戶帳號和密碼塞琼,很容易受到中間人攻擊。
SSH是目前較可靠禁舷,專為遠程登錄會話和其他網(wǎng)絡(luò)服務(wù)提供安全性的協(xié)議彪杉。利用SSH協(xié)議可以有效防止遠程管理過程中的信息泄露問題。通過SSH可以對所有傳輸?shù)臄?shù)據(jù)進行加密牵咙,也能夠防止DNS欺騙和IP欺騙派近。
ssh客戶端(ssh) ssh服務(wù)端(sshd)
+----------+ +---------+
| | | |
| | | |
| | | |
| | | |
+---+---+--+ +-+---+---+
| | | |
| | | |
| +----------------------------+ |
| |
| ssh加密了的TCP通信 |
+------------------------------------+
SSH連接
SSH只是一種協(xié)議,其開源實現(xiàn)有OpenSSH程序洁桌。
首發(fā)于: SSH-key的生成與在Git中的使用
SSH服務(wù)端和客戶端程序
OpenSSH (OpenBSD Secure Shell) 是一套使用ssh協(xié)議渴丸,通過計算機網(wǎng)絡(luò),提供加密通訊會話的計算機程序另凌。
如果需要作為ssh的服務(wù)端谱轨,則需要安裝openssh。
如果僅是作為ssh客戶端途茫,在Linux中直接使用ssh
命令即可碟嘴。
Windows中的ssh客戶端程序有:
- Putty
- PuTTY Tray(Putty的加強版)
- Bitvise 的 ssh client (功能多溪食,免費)
- Xshell (2017年被爆多版本存在后門)
- SecureCRT(算了吧)
- Cmder(開源的命令行工具囊卜,并且集成了Git for Windows和多個Unix命令,cmder的使用可參考 Cmder - 簡書 里面有講到ssh agent的配置)
SSH Key
SSH 密鑰對 最直觀的作用:讓你方便的登錄到 SSH 服務(wù)器,而無需輸入密碼栅组。由于你無需發(fā)送你的密碼到網(wǎng)絡(luò)中雀瓢,SSH 密鑰對被認為是更加安全的方式。
原因是:SSH利用SSH Key來進行前面提到的基于密鑰的安全驗證玉掸。
使用SSH key的步驟:
- 在客戶端生成SSH key(密鑰對:公鑰和私鑰)
- 在服務(wù)端的配置文件中加入你的公鑰刃麸。(比如我們需要再GitHub中粘貼你的公鑰)
生成密鑰對
ssh-keygen命令用于為ssh生成、管理和轉(zhuǎn)換認證密鑰司浪,它支持RSA和DSA兩種認證密鑰泊业。
該命令的選項:
-b:指定密鑰長度;
-e:讀取openssh的私鑰或者公鑰文件啊易;
-C:添加注釋吁伺;
-f:指定用來保存密鑰的文件名;
-i:讀取未加密的ssh-v2兼容的私鑰/公鑰文件租谈,然后在標準輸出設(shè)備上顯示openssh兼容的私鑰/公鑰篮奄;
-l:顯示公鑰文件的指紋數(shù)據(jù);
-N:提供一個新密語割去;
-P:提供(舊)密語窟却;
-q:靜默模式;
-t:指定要創(chuàng)建的密鑰類型呻逆。
生成密鑰對時夸赫,有一個選項要求你設(shè)置密碼(passphrase),該密碼是用來保護你的私鑰的密碼咖城。如果設(shè)置了則在使用私鑰時會要求你輸入這個密碼憔足;一般不設(shè)置,記不住【之后還可更改此密碼酒繁,使用ssh-keygen -p
】滓彰。
生成后最好將私鑰進行備份。另還有-C
選項州袒,用于為指定注釋揭绑,通常使用自己的郵件名作為注釋。
-b
bits選項 Specifies the number of bits in the key to create. For RSA keys, the minimum size is 1024 bits and the default is 2048 bits. Generally, 2048 bits is considered sufficient. DSA keys must be exactly 1024 bits
示例:為了安全考慮使用RSA加密方式并指定密鑰長度 -b 2048
(1024的密鑰長度能夠被破解郎哭,建議指定為2048或4096)他匪。
$ ssh-keygen -t rsa -C "your_email@example.com" -b 2048
Generating public/private rsa key pair.
Enter file in which to save the key
(/Users/your_user_directory/.ssh/id_rsa): 按回車鍵 (如果需要生成多對key,則輸入/home/users/.ssh/filename)
Enter passphrase (empty for no passphrase): 輸入密碼(一般不輸入密碼夸研,直接回車)
Enter same passphrase again: 再次輸入密碼
...
# 查看公鑰文件中的內(nèi)容
$ cat ~/.ssh/id_rsa.pub
ssh-rsa "公鑰內(nèi)容" your_email@example.com
# 注意在其他地方導(dǎo)入公鑰時一定要將公鑰文件中的*全部內(nèi)容*都導(dǎo)入邦蜜,包括末尾你的郵箱。
實際操作的一次示例:
$ ssh-keygen -t rsa -C "Fan@outlook.com" -b 2048
Generating public/private rsa key pair.
Enter file in which to save the key (/home/fan/.ssh/id_rsa): /home/fan/.ssh/FDGitHub_rsa
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/fan/.ssh/FDGitHub_rsa.
Your public key has been saved in /home/fan/.ssh/FDGitHub_rsa.pub.
The key fingerprint is:
SHA256:GcK7ORvFzH6fzA7qPmnzBr1DOWho5cCVgIpLkh6VGb8 Fan@outlook.com
The key's randomart image is:
+---[RSA 2048]----+
| .+... . |
| +o. o |
| o.. oo.. |
|+o. +*.o |
|+.. E.=So . |
|.. o== = |
| .=..+oo |
| +=o+= . |
| .++=.o* |
+----[SHA256]-----+
公鑰是一串很長的字符亥至;為了便于肉眼比對和識別悼沈,所以有了指紋這東西贱迟;指紋位數(shù)短,更便于識別且與公鑰一一對應(yīng)絮供。
公鑰加密指紋fingerprint有兩種形式:
- 之前的十六進制形式:
16:27:ac:a5:76:28:2d:36:63:1b:56:4d:eb:df:a6:48
- 現(xiàn)在使用sha256哈希值并且使用base64進行格式:
SHA256:nThbg6kXUpJWGl7E1IGOCspRomTxdCARLviKw6E5SY8
指紋的用處之一是在使用SSH第一次連接到某主機時衣吠,會返回該主機使用的公鑰的指紋讓你識別。示例:
The authenticity of host '某主機名' can't be established.
RSA key fingerprint is SHA256:nThbg6kXUpJWGl7E1IGOCspRomTxdCARLviKw6E5SY8.
Are you sure you want to continue connecting (yes/no)?
簡單介紹一下:
公鑰用于給別人用來加密文件壤靶。公鑰就是一把鎖缚俏,你把鎖給別人,他用鎖鎖住東西后贮乳,除了你自己外其他人是沒有鑰匙(私鑰)的忧换,都無法打開。配對的私鑰就是鑰匙向拆。
必須保證使用你的公鑰的人明確知道這個公鑰一定是你的包雀。你可以在網(wǎng)站或通過其它方式公布你的公鑰,以便他人進行對照確認亲铡。由于公鑰很長才写,所以有了對應(yīng)的指紋(指紋更易辨別,位數(shù)更少)奖蔓,可以通過指紋進行對照(公布指紋)赞草。
如何創(chuàng)建多個ssh key而不是覆蓋默認文件
在創(chuàng)建ssh key時自行輸入路徑和文件名稱,而非使用默認路徑和文件名即可吆鹤。
或者使用 -f
來指定文件名
ssh-keygen -t rsa -C "your_secondemail@email.com" -f ~/.ssh/second-rsa
使用非默認的SSH key
對于OpenSSH客戶端(Linux默認安裝)厨疙,需要在 ~/.ssh/config
文件中進行配置(如果沒有該文件則自行創(chuàng)建一個)。
分為如下兩種情況疑务。
1.為不同服務(wù)器的同一用戶配置不同SSH key
好吧沾凄,這里同一用戶在不同服務(wù)器上是可以使用同一個SSH key
Working with non-default SSH key pair paths
比如:你在GitLab上粘貼的公鑰(Public SSH keys)不是默認的密鑰對;此時要想讓你的ssh client正常與GitLab服務(wù)器通信知允,必須對ssh client進行配置撒蟀,當通信對象為GitLab服務(wù)器主機時,使用哪個私鑰(SSH private key)温鸽。
注意:這里使用公鑰也是可以的
示例:
# GitLab.com server
Host gitlab.com
# 如果提示: Unsupported option "rsaauthentication"保屯,則可以選擇注釋掉該行
RSAAuthentication yes
IdentityFile ~/.ssh/private-key-filename-01
# Private GitLab server
Host gitlab.company.com
RSAAuthentication yes
IdentityFile ~/.ssh/private-key-filename
對于GitLab等:上傳到GitLab服務(wù)器中的SSH公鑰只能屬于單個用戶,你的SSH密鑰是您通過SSH推送代碼時的標識符涤垫;它需要唯一映射到單個用戶姑尺。也就是說,一個公鑰在該服務(wù)器上只能被一個賬戶使用蝠猬;但是你可以在不同的服務(wù)器上使用同一個密鑰對切蟋,也可以在不同服務(wù)器上分別使用不同的密鑰對。
GitHub使用非默認密鑰對:
Host github.com
RSAAuthentication yes
# 也可以使用公鑰
IdentityFile ~/.ssh/FDGitHub_rsa.pub
配置完成后可以使用如下命令測試連接:
# 測試時替換掉 example.com
ssh -T git@example.com
# 例如 gitlab
ssh -T git@gitlab.com
# 例如 github
ssh -T git@github.com
# 例如 coding
ssh -T git@git.coding.net
# 例如 碼云
ssh -T git@gitee.com
# bitbucket
ssh -T git@bitbucket.org
# 也可以使用下面的命令來調(diào)試連接
ssh -Tv git@example.com
如果測試時出現(xiàn)如下提示:
Unsupported option "rsaauthentication"
榆芦,則可以選擇忽略或注釋掉配置文件中的RSAAuthentication yes
行柄粹。
2.配置多個賬戶
為同一服務(wù)器配置不同賬戶,比如說你在coding上有兩個賬戶喘鸟,那么可以這樣在config文件中配置:
# coding
Host git.coding.net
User your_email@example.com
PreferredAuthentications publickey
IdentityFile ~/.ssh/id_rsa //默認的私鑰
# second
Host git.coding.net
User youre_secondemail@example.com
PreferredAuthentications publickey
IdentityFile ~/.ssh/second_rsa // 生成的第二個私鑰
SSH agent
ssh-agent命令是一種控制用來保存公鑰身份驗證所使用的私鑰的程序。在Linux中ssh-agent 在X會話或登錄會話之初啟動镰惦,所有其他窗口或程序則以客戶端程序的身份啟動并加入到ssh-agent程序中。通過使用環(huán)境變量犬绒,可定位代理并在登錄到其他使用ssh機器上時使用代理自動進行身份驗證旺入。
其實ssh-agent就是一個密鑰管理器,運行ssh-agent以后凯力,使用ssh-add命令將私鑰交給ssh-agent保管茵瘾,其他程序需要身份驗證的時候可以將驗證申請交給ssh-agent來完成整個認證過程。
另外如果您的私鑰使用密碼短語來加密了的話咐鹤,每一次使用 SSH 密鑰對進行登錄的時候拗秘,您都必須輸入正確的密碼短語。而 SSH agent 程序能夠?qū)⒛囊呀饷艿乃借€緩存起來祈惶,在需要的時候提供給您的 SSH 客戶端雕旨。這樣子,您就只需要將私鑰加入 SSH agent 緩存的時候輸入一次密碼短語就可以了捧请。這為您經(jīng)常使用 SSH 連接提供了不少便利凡涩。
有不少的 SSH agent 供您選擇,我們將為您介紹幾種常用的 SSH agent疹蛉,您可以根據(jù)您的需要進行選擇活箕。
- ssh-agent 是 OpenSSH 自帶的一個 SSH agent
- GnuPG agent也許想要 GnuPG 來緩存您的私鑰。當然咯可款,有些用戶比較喜歡在 GnuPG 對話框來輸入 PIN 碼育韩,這樣子管理密碼短語也是不錯的選擇。
ssh agent帶來的問題
在Linux中我并沒有遇到過因 ssh-agent 而帶來的問題闺鲸,這里說一下Windows中使用ssh時遇到的相關(guān)問題筋讨。
嘗試通過SSH進行身份驗證時,您可能會看到以下錯誤消息 :
當嘗試使用Git并通過SSH協(xié)議進行 clone, push,或 pull時摸恍,如果Github無法使用SSH agent提供的密鑰進行身份驗證版仔,則可能會收到下面的某一條消息:
- Permission denied (publickey)
- No suitable response from remote
- repository access denied
可能的原因:
你的 公鑰 并沒有添加到服務(wù)器端。
-
您的密鑰未加載到ssh agent中 误墓。(如果您的SSH代理不知道為Bitbucket提供密鑰蛮粮,則連接將失敗。如果您最近重新啟動了系統(tǒng)谜慌,則可能會遇到此問題然想。 )解決方法:
-
檢查相應(yīng)的 ssh key 是否被加載:
ssh-add -l
-
如果沒有被加載,則使用下面的命令加載私鑰
#后面可以同時跟多個私鑰 ssh-add ~/.ssh/<private_key_file>
-
如果提示 "Could not open a connection to your authentication agent." 說明你的ssh agent并沒有運行欣范;使用下面的命令運行ssh agent变泄,再使用
ssh-add
命令添加你的ssh key令哟。# macOS/Linux $ eval `ssh-agent` # 在Windows中的git-bash中 $ eval $(ssh-agent)
-
還有個注意點,就是不要同時運行多個 ssh agent妨蛹,可通過任務(wù)管理器或 ps
命令進行查看屏富。
Github/GitLab中使用SSH
Github/GitLab中為什么會用到SSH?
Using the SSH protocol, you can connect and authenticate to remote servers and services. With SSH keys, you can connect to GitHub without supplying your username or password at each visit.
使用SSH協(xié)議,您可以連接和驗證遠程服務(wù)器和服務(wù)蛙卤。
使用SSH密鑰狠半,您可以連接到GitHub,而無需在每次訪問時提供用戶名或密碼颤难。
GitHub/GitLab 中導(dǎo)入SSH Key
SSH Key導(dǎo)入:導(dǎo)入過程比較簡單神年。
GitHub: 點擊用戶頭像 > Setting > SSH and GPG keys > New SSH key > 粘貼你生成的公鑰(簡單的方法是用文本編輯器打開公鑰文件然后復(fù)制)。
訪問遠程倉庫時可以選擇 SSH 或者 HTTPS協(xié)議進行訪問行嗤。
(比如已日,與gitlab 遠程倉庫進行進行安全認證可選擇使用ssh或者https),兩者的表現(xiàn)形式:
SSH git@gitlab.com:faner/test01.git
HTTPS https://gitlab.com/faner/test01.git
當你選擇HTTPS時栅屏,會看到它有下面的一段提示"Create a personal access token on your account to pull or push via Https"簡單的翻譯一下就是"在您的帳戶上創(chuàng)建個人訪問令牌飘千,以通過Https進行pull或push",并且在你第一次將本地倉庫push到遠程倉庫時會要求你輸入gitlab的用戶名和密碼栈雳。
經(jīng)驗:由于我的ssh的config文件出現(xiàn)配置錯誤占婉,并且ssh-agent也未運行,當我選擇
git@gitlab.com:faner/test01.git
時提示有有誤(當時的情況就是使用ssh無法認證)我就嘗試使用了https的
https://gitlab.com/faner/test01.git
路徑甫恩,之后就讓我輸入密碼并成功連接逆济。
那么現(xiàn)在您已經(jīng)設(shè)置了SSH密鑰,在下次克隆存儲庫時可以使用SSH 的 URL磺箕。如果您已經(jīng)擁有通過HTTPS克隆的存儲庫奖慌,可以將存儲庫的遠程URL更改為其SSH URL 。
從用戶操作上來看松靡,HTTPS需要用戶輸入遠程倉庫的用戶名和密碼简僧,比如需要輸入gitlab的帳號和密碼;SSH無需輸入用戶和密碼雕欺。
問題:生成ssh key所使用的郵箱是否需要和本地git設(shè)置的郵箱相同岛马?
本地git中配置的用戶名和郵箱會隨同提交日志被公開到GitHub上,而非生成ssh key時使用的郵箱屠列。
學習資料
了解SSH的最好方式是參見維基百科中的條目:Secure Shell - 維基百科啦逆,自由的百科全書
這里是部分引用:
中間人攻擊:就是存在另一個人或者一臺機器冒充真正的服務(wù)器接收用戶傳給服務(wù)器的數(shù)據(jù),然后再冒充用戶把數(shù)據(jù)傳給真正的服務(wù)器笛洛。
SSH協(xié)議框架中最主要的部分是三個協(xié)議:
- 傳輸層協(xié)議(The Transport Layer Protocol):傳輸層協(xié)議提供服務(wù)器認證夏志,數(shù)據(jù)機密性,信息完整性等的支持苛让。
- 用戶認證協(xié)議(The User Authentication Protocol):用戶認證協(xié)議為服務(wù)器提供客戶端的身份鑒別沟蔑。
- 連接協(xié)議(The Connection Protocol):連接協(xié)議將加密的信息隧道復(fù)用成若干個邏輯通道湿诊,提供給更高層的應(yīng)用協(xié)議使用。
在客戶端來看瘦材,SSH提供兩種級別的安全驗證:
- 第一種級別(基于密碼的安全驗證)厅须,知道帳號和密碼,就可以登錄到遠程主機食棕,并且所有傳輸?shù)臄?shù)據(jù)都會被加密朗和。但是,可能會有別的服務(wù)器在冒充真正的服務(wù)器宣蠕,無法避免被“中間人”攻擊例隆。
- 第二種級別(基于密鑰的安全驗證)甥捺,需要依靠密鑰抢蚀,也就是你必須為自己創(chuàng)建一對密鑰,并把公有密鑰放在需要訪問的服務(wù)器上镰禾∶笄客戶端軟件會向服務(wù)器發(fā)出請求,請求用你的密鑰進行安全驗證吴侦。服務(wù)器收到請求之后屋休,先在你在該服務(wù)器的用戶根目錄下尋找你的公有密鑰,然后把它和你發(fā)送過來的公有密鑰進行比較备韧。如果兩個密鑰一致劫樟,服務(wù)器就用公有密鑰加密“質(zhì)詢”(challenge)并把它發(fā)送給客戶端軟件。從而避免被“中間人”攻擊织堂。
在服務(wù)器端叠艳,SSH也提供安全驗證:
在第一種方案中,主機將自己的公用密鑰分發(fā)給相關(guān)的客戶端易阳,客戶端在訪問主機時則使用該主機的公開密鑰來加密數(shù)據(jù)附较,主機則使用自己的私有密鑰來解密數(shù)據(jù),從而實現(xiàn)主機密鑰認證潦俺,確保數(shù)據(jù)的保密性拒课。 在第二種方案中,存在一個密鑰認證中心事示,所有提供服務(wù)的主機都將自己的公開密鑰提交給認證中心早像,而任何作為客戶端的主機則只要保存一份認證中心的公開密鑰就可以了。在這種模式下肖爵,客戶端必須訪問認證中心然后才能訪問服務(wù)器主機扎酷。
必看: Secure Shell - 維基百科,自由的百科全書
如果要詳細了解遏匆,請認真參考:SSH keys (簡體中文)
實戰(zhàn):Connecting to GitHub with SSH
Readme · Ssh · Help · GitLab
配置 SSH 公鑰訪問代碼倉庫 – CODING 幫助中心
Bitbucket上列出了各種ssh相關(guān)問題和解決方法:Troubleshoot SSH issues - Atlassian Documentation強烈建議學習的幾篇SSH文章:
阮一峰:
SSH原理與運用(一):遠程登錄
SSH原理與運用(二):遠程操作與端口轉(zhuǎn)發(fā)
Asrchlinux wiki:
Secure Shell (簡體中文)
SSH keys (簡體中文)