The Complete Junior to Senior Web Developer Roadmap - SSH 筆記
前言
這部分就是我學習 「The Complete Junior to Senior Web Developer Roadmap」這堂 Udemy 線上課程的筆記,這篇是有關 SSH 的內容。
Introduction to SSH
SSH 是一種協定。
什麼意思呢?你也許聽過 HTTP、FTP、HTTPS 等協定,這些協定都是用於讓兩台電腦間溝通的協定,SSH 也是同理,是一座讓兩台機器溝通的橋樑。
舉個例子,HTTP 讓你能夠在 Browser 和 Server 兩者傳輸檔案(像 HTML、CSS、JavaScript 檔);FTP 讓你能夠傳輸檔案、在 hostgator 或 generic hostng 等平台上傳檔案;HTTPS 類似於 HTTP,但是有經過加密,這代表著第三方沒辦法讀取正在傳輸的檔案。
SSH 也是一種協議,讓兩台電腦能夠在網路連結,它讓使用者能夠透過網路控制遠端電腦,並且在連結過程中加密,使第三方的壞蛋沒辦法監控你。
這時候你可能會想,那跟 HTTPS 差在哪?畢竟他們兩個都能用於兩台機器間的溝通,過程中也會加密啊!Well,就像 web browser 透過 HTTPS 與 Server 溝通,並且呈現 Web 頁面一樣,shell 需要一個特定的協定來交換資料,或是讓兩台電腦溝通(並不只是 browser 跟 server),這也是為什麼 SSH 稱為 secure shell protocal。
SSH 最大的優點就是它用了加密的方式,讓 client 和 host 之間傳遞資訊的時候能夠保持安全。
SSH Command
接下來要開始實作了!首先我們要買虛擬機器,這邊課程選擇的是 Digital Ocean,最便宜的方案是 $5 美金/月,但其實有其他免費的平台可以買虛擬機器,比如 AWS、GCP 等,但這邊我就用 Digital Ocean 了。
首先點擊 Navbar 的 product 中的 Droplet。
接著會進入到 console 面板中,點擊 New Droplet。
點擊後會進入到 Create Droplet 頁面,裡面可以調整一些像是作業系統、使用方案等等的選項,這邊我作業系統選擇 Ubuntu,plan 選擇最便宜的 $5 /月的方案。
datacenter region 我就隨便選,離自己所在地近一點應該會比較好。
create 成功後,可以點擊進去自己剛剛買的機器,看詳細的資訊,此時我們順便複製機器的 IPv4,並且將我們目光轉移到自己的 Terminal 上,我們要開始連接到自己剛剛創建的機器裡了!
在 Terminal 輸入這行:
ssh sudo@剛剛複製的 IPv4
此時它會要求你輸入密碼,密碼可以在 digital ocean 寄給你的 email 中看到 password,成功進入機器後,又會要求你更改密碼,再次輸入 email 中的密碼後,就可以改成自己想要的密碼了~
當你看到這樣的畫面時,就代表成功連進去遠端的機器了!
說明一下剛剛的 command line
ssh {user}@{host}
透過 ssh,我們可以遠端連線到任何允許 ssh 連線的電腦中,酷吧!
ssh
代表你要使用 ssh 加密的方式連線,
user
代表你要登入的帳戶,舉例來說,你想要使用 root 來登入,root 代表你是系統的管理者,有完整的權限可以更改系統。
host
代表你想要登入的電腦,可以是 IP 名稱或者是 domain name。
為何要學 SSH
在工程師的生涯中,你很可能會遇到各種需要用到 SSH 的情況,像課程中的老師過去就發生已經部署好的 App 不小心被刪除,所以需要重新用 SSH 連線到遠端電腦,重新 install 的狀況。
Saving The Day Through SSH
安裝 nodejs
首先 ssh 連線進虛擬機器後,輸入:
sudo apt-get update
此時會 update 一些有的沒的,我也不太確定實際上在 update 什麼,但如果不先 update 的話,會說找不到 Nodejs 的 package。
update 結束後,接著輸入:
sudo apt-get install nodejs
複製本機的檔案到遠端機器中
接著試試看把本機的資料夾透過 ssh 複製到遠端機器裡吧!
首先我在 Desktop 創建一個叫 emptyFolder
的資料夾,接著進入 emptyFolder
中,此時的 terminal 長這樣:
接著輸入
rsync -av . @機器的IPv4 ~/路由
就可以成功把本機的檔案傳送到遠端機器囉。
How SSH Works
SSH 當中有三項技術
- Symmetrical Encryption (對稱性加密)
- Asymmetrical Encryption (非對稱性加密)
- Hashing (雜湊)
Symmetrical Encryption
對稱性加密提供一把 secret key 讓加密/解密兩方使用,
運作的方式像是以下的圖片
client 端把想要傳遞的內容經過 secret key 加密後,會變成一串奇妙的文字,讓第三方沒辦法看懂, host 端再藉由那把 secret key 解密,得到 client 端傳遞的資訊。
此時能注意到的問題是,看來只要能有這把鑰匙的人,就能得到資訊的內容,那鑰匙被幹走怎辦呢? 看來問題就會出現在「交換鑰匙的方式」是否安全了,因此,這個安全交換鑰匙的方式我們就稱為 key exchange algorithm。
Asymmetrical Encryption
延續前面提及的 key exchange algorithm,它需要透過一個叫做 asymmetrical encryption(非對稱性加密)的方式執行。
至於非對稱性加密是什麼,以下取自網路安全(1) - 基礎密碼學一文:
非對稱式加密,就是每個鑰匙 pair 有兩個鑰匙,一個公鑰一個私鑰。
可以公鑰加密私鑰解密,也可以私鑰加密公鑰解密。
可以公鑰加密私鑰解密,也可以私鑰加密公鑰解密。
可以公鑰加密私鑰解密,也可以私鑰加密公鑰解密。
傳訊之前呢,A 跟 B 都先生成一組公私鑰的 pair,A 把 A 的公鑰傳給 B,B 把 B 的公鑰傳給 A。
好現在 A 有他自己的私鑰跟 B 的公鑰,B 有他自己的私鑰跟 A 的公鑰。
A 要傳東西給 B 就用 B 的公鑰加密,然後 B 拿到之後用 B 自己的私鑰解密。一切搞定,即使在中途被攔截,只要 B 的私鑰沒有流出就完全不會有事。反之亦然。
中心思想就是利用公鑰可以用來加密的特性,而如果你是用公鑰加密你必須要用私鑰解密。所以我根本不怕公鑰流出(公開給所有人也沒差),只要我私鑰保存好就好,我私鑰根本就沒傳過,也不可能被攔截。
參考資料
Secret Key Exchange (Diffie-Hellman) - Computerphile
Diffie Hellman -the Mathematics bit- Computerphile
Hashing
透過 Symmetrical Encryption + Asymmetrical Encryption 的搭配,看起來 client 和 host 溝通是挺安全的,沒什麼問題對吧!
但此時又有一個問題,就是如果有個中間人可以偽造他自己的身份,讓 host 相信對面是 client,讓 client 相信對面是 host,偽造了身份並且在當中做手腳,就會很不妙,因此需要 hash 來做相關處理。
以下取自SSH原理与运用(一):远程登录:
SSH之所以能够保证安全,原因在于它采用了公钥加密。
整个过程是这样的:(1)远程主机收到用户的登录请求,把自己的公钥发给用户。(2)用户使用这个公钥,将登录密码加密后,发送回来。(3)远程主机用自己的私钥,解密登录密码,如果密码正确,就同意用户登录。
这个过程本身是安全的,但是实施的时候存在一个风险:如果有人截获了登录请求,然后冒充远程主机,将伪造的公钥发给用户,那么用户很难辨别真伪。因为不像https协议,SSH协议的公钥是没有证书中心(CA)公证的,也就是说,都是自己签发的。
可以设想,如果攻击者插在用户与远程主机之间(比如在公共的wifi区域),用伪造的公钥,获取用户的登录密码。再用这个密码登录远程主机,那么SSH的安全机制就荡然无存了。这种风险就是著名的”中间人攻击”(Man-in-the-middle attack)。
SSH Into a Server
根據前面連線到遠端機器的經驗,應該會發現每次輸入 ssh root@IPv4
都必須輸入 password 才能連線,那更方便的辦法是什麼呢?
就是用前面提到的 ssh key 來進行登入!
至於要怎麼做呢?
第一步 - 進入 ssh 資料夾
首先在 terminal 輸入 cd ~/.ssh
,此時可以進入到隱藏的 .ssh
資料夾中,這邊是存放你電腦各種 ssh key 的地方。
第二步 - 產生 ssh key
接下來,我們要輸入 command line 產生 public 和 private 的 ssh key for Digital Ocean。
輸入ssh-keygen -C "你的email"
,-C 代表 comment,按下 enter 後可以看到 terminal 出現「Generating public/private rsa key pair.」,代表產生了一對 public/private key。
接著要輸入你想儲存的檔案名,因為是為了 digital ocean 的 server 而創建的,我就把名稱取為 id_rsa_digitalocean
再來會問你 passphrase,這是為了額外的安全設定而出現的,可以直接按 Enter 略過,它就會是 empty。
連按兩次 Enter 後,我們就成功產生 ssh key 了!
第三步 - 把 public key 內容放進遠端機器中
首先在 .ssh
資料夾內,輸入這個 command line:
pbcopy < ~/.ssh/id_rsa_digitalocean.pub
這個指令的用途是可以把檔案內的內容複製。
接下來輸入 ssh root@IPv4
連線到你的遠端機器裡,再輸入 cd .ssh
進入 ssh 資料夾中,輸入 ls
可以發現裡面會有一個叫做 authorized key
的檔案,這份檔案用途就是記錄 public key 的 rsa 內容,所以輸入 nano authorized_key
把剛剛複製的內容貼到檔案裡面後,按下 CTRL + X 並且保存退出。
第四步 - 在本機做 ssh-add
接著要進入最後一步了!
如果沒有做最後一步的話,連線到遠端機器的時候應該會出現 permission denied
。
因此要回到剛剛本機的 .ssh
資料夾中,輸入 ssh-add ~/.ssh/id_rsa_digital_ocean
,把 private key 的內容加進去,這樣就能不用輸入密碼,利用 ssh key 快速來往自己租用的機器啦!
也可以試試看把本機裡面 .ssh 檔案的 digital ocean private key 刪掉試試看,會發現被 permission denied 喔,因為你不再有 private key 了。
Digital Ocean
其實 Digital Ocean 也有提供更快速的方式用 ssh key 連線,進入到 console 控制台點擊 add ssh key,把產生的 public key 複製貼上後就能使用,超級快速!
Github 練習
為了練習,接著就用 Github 來實作吧!
你可以發現,一般在 clone 別人的 repo 時,是用 HTTPS 的方式來 clone,麻煩的是每次都要重複輸入自己 Github 帳密,但我們現在學了 ssh key 的使用方式,當然就是要讓自己生活方便點啦。
至於怎麼實作,其實和前面 digital ocean 使用 ssh key 的方式大同小異,Github 文件也寫得很完整,就附上連結自行練習了~
Generating a new SSH key and adding it to the ssh-agent