1、第四部分第二課:SSH連接,安全快捷
2、第四部分第三課:文件傳輸,潇灑同步
這一課的內容肯定會讓你大呼過瘾,也許是《Linux探索之旅》中到目前為止最有意思的課之一。
我們會聊很多內容,會學習如何連接到遠程的一台安裝有Linux的機器。
在本課程的開頭,我們略微提到過:可以配置安裝Linux的機器,只要機器開著,就可以遠程連接到它。
我們不僅僅會學習如何遠程連接到Linux,還會學習其原理。
而且也會學習SSH協議,以及數據如何通過SSH加密。以及如何用SSH連接到遠程電腦。
因此,我們可以一窺網絡和安全(密碼學)的奇幻世界。
設想一下:你家裡的電腦安裝了Linux系統,處於開機狀態,你在工作的時候想起來要用家裡的電腦進行某項下載任務或者提取某個文件。此時,你可以遠程連接到家裡的Linux系統,打開一個終端,就好像你坐在家裡的電腦面前一樣。我們到目前為止所學關於終端的所有操作,你都可以在遠程連接到的機器上實現,哪怕這台機器是在世界的另一個角落。
這一課對各位站長(小編也是其中一員,我們程序員聯盟有網站和論壇:http://coderunity.com/和http://coderunity.com/bbs/)特別有用,因為我們可以遠程連接到自己網站的服務器。
現在越來越多的人購買了服務器,在服務器上可以架設自己的網站,或提供服務(比如游戲服務器)。
一般來說,對服務器的操作都需要遠程連接(因為我們一般都是租用服務器提供商的遠端電腦,除非你有錢“任性”,那你可以買幾台電腦來做服務器),用終端來進行,而且基本都是用SSH協議來連接。
連接到遠程終端
到目前為止,我們本課程中所學的Linux的操作,都是我們本人坐在電腦前去操作自己面前的電腦。可能與我們原先還沒學編程,使用Windows電腦玩Dota時沒什麼區別:端坐在電腦前,按下開機鍵,電腦開機,然後... gg對戰平台,網易對戰平台,五人黑呀,好happy呀...
怎奈我們不甘寂寞(“一生有一種大海的氣魄,歲月一頁頁無情翻過。那乾坤留在我心中的一刻,就已經注定我不甘寂寞... ” 小編你可以了),在一個地方待久了,總想去外面闖闖看看。
Linux的一個強大之處就是可以很方便地操作很遠之處的另一台安裝有Linux的電腦。這個功能早在Unix時代就已經有了。
當然了,Windows系統也可以遠程連接到另一個Windows系統,我們也可以從Linux系統連接到Windows系統、Mac系統,或者從Windows連接到Linux,Mac。等等。只不過使用起來沒有Linux下那麼順手。
今天,比如我住在法國巴黎,我可以很方便地遠程連接到位於美國紐約的一台電腦。也可以連接到日本東京的一台電腦。我也可以操作美國的那台電腦給日本東京的電腦發送文件。
因為Internet(互聯網或英特網)的出現,這樣的事情在今天看來已經很平常了。
遠程連接技術大大節約了時間和精力。假如沒有這個技術,專門負責維護遠程服務器的技術人員(通常稱為System Administrator,系統管理員)要給東京機房的電腦安裝一個軟件,那還得買飛機票去東京...
服務器,英語是server。一般是指7天24小時不關機的電腦,這些電腦和你家裡的電腦類似,但又不一樣(通常更強勁,噪音更大 :P):也有一個處理器,一個或多個硬盤,等等。服務器的主要特色是保持開機,始終連接Internet,提供服務。比如程序員聯盟的網站的服務器是租用的阿裡雲的服務器,它也會不分日夜地殷勤為您傳送需要的網頁。
我們把連接到服務器的機器稱為客戶機,英語是client,我們本課之後的圖片中也會像下圖這樣來表述:
目前,你家裡的電腦應該還不能被稱為一台服務器。當然,如果你願意,你也可以將其“變為”一台服務器,只需要安裝一些軟件,做一些配置。
還有就是:不關機。
因為一台關機的服務器,就不是《服務》的機器了。作為服務器必須 任勞任怨,隨叫隨到;宕機重啟,永不言棄。
接下來,我們就有請今天的主角:SSH 上場。
不過我們也會講很多其他的相關知識點,前方知識點密集高能預警。准備好了嗎?我們將會以下面的順序來介紹SSH:
為什麼要保護網絡通信?
SSH又是如何保護網絡通信的?
SSH的具體使用方法。
從Telnet協議到SSH協議
協議
兩台機器在互聯網上通信的時候,需要遵循相同的協議。這不難理解,生活中,兩家公司要合作,要協商,也需要擬定一份協議,雙方都同意,並且簽署,遵守。一旦違反協議,交流合作即會結束。比如之前習大大訪問英國,和英國簽署了一系列商業協議,只有雙方都遵循此協議,合作交流才能繼續。
同樣地,對於我們的互聯網(Internet),要在其上相互通信,需要一定的協議。互聯網畢竟是人創立的嘛,那肯定引入了人的慣有思維。
或者我們也可以把互聯網協議(有時也稱為網絡協議。參看百度百科:http://baike.baidu.com/view/16603.htm)比作一種語言,只有都說英語或都說中文才能相互交流。
互聯網協議有很多,就不一一列舉了,可以看上面百度百科鏈接裡的列表。因此,兩台機器之間可以有不少種方式相互通信(每種協議對應一種通信方式)。
身為讀者的您肯定已經見過其中的一種協議了,那就是HTTP協議,只要你上網浏覽網頁,那麼你其實一直在使用這種協議,還記得我們程序員聯盟的網址嗎?
http://coderunity.com
看到最前面的http四個英文字母了嗎?這就說明它遵循的是HTTP協議。因此,你的電腦能看到程序員聯盟的官方網站,是因為你的電腦和程序員聯盟的服務器之間使用了HTTP協議來互相通信。
HTTP是英語Hyper Text Transfer Protocol的縮寫,表示《超文本傳輸協議》。protocol就是英語《協議》的意思。HTTP協議是Web(Web可以簡單翻譯為《網絡》)最常用的傳輸網頁的協議。
其他常見的網絡協議有FTP,是英語File Transfer Protocol的簡稱,表示《文件傳輸協議》。一般站長常用FTP,因為需要把文件(比如網站的源代碼)傳輸到遠程的網站服務器上。以前在大學時代,學校也會有公共的FTP站點,供學生們下載需要的學習資料。
還有我們每天使用郵箱所需要遵循的協議,常見的有IMAP和POP3。IMAP是Internet Message Access Protocol(互聯網消息訪問協議)的縮寫,POP3是Post Office Protocol Version 3(郵局協議第三版)的縮寫。一般我們使用Office Outlook,Thunderbird,Gmail,163郵箱,QQ郵箱等。都需要遵循相應的郵件協議。
Telnet協議:簡單易用危險多
既然我們這課的重點是講遠程連接,那麼我們就來談談遠程連接的協議好了。首先,介紹一個老古董:Telnet。
這個協議簡單,易用,在20世紀80年代就被創立了。它的功用就是在機器間傳輸簡單信息。
理論上,我們就可以使用Telnet來與遠端機器通信啦,比如與我們的服務器通信。
但是這個協議有什麼缺點呢?那就是它太簡單太基礎了,因此傳輸的信息並沒有經過加密,而是明文傳輸。
在密碼學中,明文(英語是:Plaintext或Cleartext)是指傳送方想要接收方獲得的可讀信息(比如《我愛你》)。 明文經過加密所產生的信息被稱為密文,而密文經過解密而還原得來的信息被稱為明文。
如果在互聯網上傳輸明文,那是很危險的。假設以下場景:一台軍方的客戶端電腦請求軍方的服務器發射導彈的密碼(可能是核彈,嚇死寶寶了...),服務器用明文將密碼傳輸給客戶端。
如下圖所示:
從上圖看來,並沒有什麼風險不是嗎?因為信息只傳遞給了請求的客戶機。
但是,很有可能一個不懷好意的黑客,監聽了上面兩者通信的信息,就可以截取軍方服務器發給軍方客戶機的明文信息了。如下圖所示:
要阻止這樣的黑客行為是很難的。雖說攔截數據這樣的操作本身有難度,但是有水平的黑客是可以輕易做到的。
比如, 像Wireshark這樣的軟件就可以用於監聽網絡(尤其是本地網絡),可以截獲數據。如下圖所示:
你也許會說:“呃... 等等。我只是想遠程連接到我的電腦或服務器以便訪問終端控制台。我可不會共享核彈密碼!況且我在電腦上只是運行grep之類的命令,被人知道也不妨啊。”
你的意思是你並不介意別人窺探你的電腦咯?好吧,你贏了。
但是當你連接到服務器時,你需要提供你的登錄名和密碼,假如被人竊取就麻煩了。
所以,必須加密網絡間傳輸的信息,你應該不希望自己的密碼被人知道吧。
SSH協議:保護信息的好方法
既然我們並不能阻止心懷不軌的人試圖截取Internet上傳輸的信息,那麼我們就要采取一些措施,使客戶機和服務器之間以安全的方式通信。加密技術就是專門替我們做這等差事的:假如黑客獲取了加密後的密碼,他便不能做什麼。
但是怎麼加密數據呢?客官莫急,待我把主角SSH請上來~
使用SSH的信息交換是如何加密的
SSH是英語Secure SHell的縮寫,直譯過來就是“安全的Shell”,shell是“殼”的意思。
在計算機科學中,Shell俗稱殼(用來區別於核),是指“提供使用者使用界面”的軟件(命令解析器)。它類似於DOS下的command和後來的cmd.exe。它接收用戶命令,然後調用相應的應用程序。Linux下有Bash等Shell程序,之後我們有專門的一大部分會講Shell程序,不要擔心。
不可諱言,SSH協議本身比較復雜,但是如果能對其大致原理有所了解,豈不快哉?
如果知其所以然,那使用的時候也不會那麼盲目了。所以我們從以下兩條主線來了解SSH:
有哪些不同的加密方法
SSH又是如何運用加密方法來保護數據的
不同的加密方法
說到加密方法,就要涉及到相應的算法了。什麼是算法呢?
============
百度百科的解釋:
算法(Algorithm)是指解題方案的准確而完整的描述,是一系列解決問題的清晰指令,算法代表著用系統的方法描述解決問題的策略機制。
============
所以下面我們就直接用“加密算法”這個詞了。
要說不同的加密算法,那實在是三天三夜講不完啊,所以小編就不在這給大家“一千零一夜”了。
雖說我們不能了解所有的加密算法(也沒那個必要),但是我們需要知道加密算法大致分兩類:
對稱加密
非對稱加密
對稱加密
對稱加密是比較簡單的加密算法,但簡單並不意味著不保險(有很安全的對稱加密算法)。簡單意味著功能比較好理解。對稱加密算法用一個密鑰(英文稱為Key,是在明文轉換為密文或將密文轉換為明文的算法中輸入的參數)來加密信息。舉個例子,假如此密鑰叫superkey,而需要被加密的信息是message,那麼加密過程如下圖所示:
上圖是對稱加密的加密過程的簡單演示。傳輸方用superkey這個密鑰將message這個明文信息進行加密,成為P7&(jk2%這樣的密文。
之後,接收方用同樣的密鑰superkey,對P7&(jk2%這個密文進行解密,就重新得到了明文message。解密的過程如下圖所示:
上圖就是對稱加密中用同樣的密鑰superkey進行解密的過程。
因此,對稱的意思就是指加密和解密使用的是同一個密鑰。因此加密方和解密方都須要知道這個密鑰。
這樣,假如黑客截獲了P7&(jk2%這個傳輸的密文,他沒有解密的密鑰superkey,他就不知道究竟是什麼明文信息了。如下圖所示:
你會說:這樣很不錯啊。
但是,客戶機和服務器都須要知道這個密鑰。因此客戶機首先要把這個密鑰傳給服務器,為了讓服務器可以解密那些加密過的信息。
實際上,為了達到上圖的目的,客戶機和服務器必須事先傳遞那個密鑰superkey。但是他們怎麼傳遞呢?假如他們傳遞密鑰用的是明文,那麼黑客照樣可以截獲密鑰,接下來就可以解密任何傳遞的加密信息了,不是嗎?如下圖所示:
你也許會問:為什麼我們不干脆把傳遞的密鑰也加密呢?
好問題,你的想法也是對的。Bravo
為了加密對稱加密的密鑰(是不是很繞),我們將用另一種方法:
非對稱加密。只要用了這個方法,我們就不用擔心密鑰被黑客獲取了。
非對稱加密
對稱加密方法中,我們只用一個密鑰來進行加密和解密。
非對稱加密方法中,我們用一個密鑰來進行加密,用另一個密鑰來解密。
因此,非對稱加密有兩個密鑰:
一個是"公鑰"(Public Key),用於加密
一個是"私鑰"(Private Key),用於解密
公鑰只用來加密。因此,用非對稱加密的算法,我們就只能用私鑰來解密咯。
我們請求電腦為我們生成這一對密鑰:一個私鑰和一個公鑰。它們總是成對出現。
但是您不要問我生成這一對密鑰的原理,也不要問我為什麼它們總是成對出現。因為“我不想說,我很親切;我不想說,我很純潔。可是我不能拒絕心中的感覺...”。 不好意思,跑題了(想起了楊钰瑩)。
其實是因為原理很復雜,我們只要知道怎麼用就好了。
假設我們有如下一對密鑰:
公鑰:37ab47pK
私鑰:1Tv314C
為了加密,我們要用到公鑰,如下圖所示:
而解密呢,公鑰就派不上用場了。必須用私鑰才行。公私分明,方為大德嘛。如下圖所示:
這就是為什麼我們稱這種方法為非對稱的原因:需要兩個不同的密鑰。其中一個用於加密,另一個用於解密。
公鑰可以在網絡上以明文傳輸,畢竟是公開的密鑰嘛(Public就是英語"公開的,公共的"的意思)。即使公鑰被不懷好意的黑客截獲也無所謂。但是,私鑰(private是英語"私人的,私有的"的意思),用於解密的,卻不能被公開傳輸,需要保管好。
當然了,非對稱算法絕不止一種,在這個大家族中,最有名的要數RSA算法了。
1977年,三位數學家Rivest、Shamir 和Adleman 設計了一種算法,可以實現非對稱加密。這種算法用他們三個人的名字的首字母命名,叫做RSA算法。
用SSH創建一個安全的通信管道
SSH結合使用非對稱加密和對稱加密兩種方法
SSH以如下順序使用兩種加密方法:非對稱加密和對稱加密
首先,使用非對稱加密來安全傳輸對稱加密的密鑰
之後,就一直使用對稱加密的密鑰來作為加密和解密的手段
聰明如你一定會好奇:那為什麼不只用非對稱加密呢?
當然可以只用非對稱加密,但是也有一個缺陷:非對稱加密太消耗電腦資源了。非對稱加密比對稱加密要慢大概100~1000倍。
因此,兩台電腦之間交換對稱加密的密鑰(用非對稱加密的方式),之後就可以用對稱加密來通信了,會更快捷。
非對稱加密只是在通信之初用於交換對稱加密的密鑰。
讓我們用圖解的方式來解釋一下SSH是如何創建一個安全的通信管道的:
首先,我們要交換一個對稱加密的密鑰,但是我們又不能以明文方式傳輸這個密鑰,不然黑客截獲之後就可以用其來解密了。因此,我們要用非對稱加密的方式來加密對稱加密的密鑰(希望你還沒暈)。
服務器將非對稱加密的公鑰以明文方式傳輸給客戶機,使客戶機可以用公鑰來加密。如下圖:
客戶機收到服務器傳給它的公鑰之後,就會用公鑰來加密自己的對稱加密的密鑰,假設是superkey。如下圖所示:
然後,客戶機將用公鑰加密後的對稱加密密鑰傳給服務器。黑客可以截獲這個加密後的密鑰,但是他沒辦法解密,因為他沒有用於解密的私鑰,這個私鑰只有服務器知道。如下圖所示:
服務器接收到客戶機傳來的密鑰,使用自己的私鑰來解密,就得到了對稱加密的密鑰。如下圖所示:
現在,客戶機和服務器都知道了對稱加密的密鑰是superkey,而他們從沒在網絡間以明文傳遞過這個密鑰。
因此,從現在開始他們可以以對稱加密的方式互相發送加密的信息(用superkey來加密和解密),不用再擔心被黑客獲取信息了。如下圖所示:
好了,以上就是SSH的工作原理了。是不是很巧妙地創建了一條安全通信的管道呢,設計這些的前輩真的非常機智,智商高達250呢~
現在既然客戶機和服務器已經有了安全的通信方式了,客戶機就可以放心地將自己的登錄名和密碼傳輸給服務器以連接服務器了。如下圖:
那麼,須要知道以上這些原理才能使用SSH嗎?
當然不是啦。以上這些都是自動完成的。為了連接遠程電腦,你要做的只是輸入登錄名和密碼就好了。
現在全球都在使用SSH,幾乎沒有人再用Telnet了。
用SSH進行連接
注:我們接下來的命令都是以Debian系列(Ubuntu為代表)來演示的,其他Linux發行版的命令格式類似。
好了,理論談得夠多了,該實戰了。你會發現其實使用SSH很簡單,因為電腦替我們做了大部分工作。
接下來我們分為兩種情況:
你已經租用了一台服務器(例如阿裡雲),那這台服務器因為已經配置好了作為SSH服務器,所以你什麼也不需要做。估計站長大多是這種情況吧。
你沒有租用一台服務器(大多數人的情況),我們就來看看怎麼把你自己的電腦配置成SSH服務器。
將你的電腦配置成SSH服務器
假如你要將自己的電腦配置成SSH服務器,以便自己或別人以後可以遠程用SSH登錄你的電腦,你可以這麼做:
首先,安裝openssh
sudo apt-get install openssh-server
安裝完成後,它會自動開啟sshd這個精靈進程。
你也可以手動開啟:
// Ubuntu系統
sudo service ssh start
// Debian系統
sudo /etc/init.d/ssh start
要停止的話:
// Ubuntu系統
sudo service ssh stop
// Debian系統
sudo /etc/init.d/ssh stop
如果你要對SSH的配置做修改,可以修改/etc/ssh/ssh_config,然後運行sudo /etc/init.d/ssh reload或sudo service ssh reload來使修改生效。
從一台Linux電腦上通過SSH連接(Mac電腦類似)
假定你要以用戶名user,登錄遠程服務器host,只要一條簡單命令就可以了:
ssh user@host
如果本地用戶名與遠程用戶名一致,登錄時可以省略用戶名:
ssh host
SSH的默認端口是22,也就是說,你的登錄請求會送進遠程服務器的22端口。使用p參數,可以修改這個端口:
ssh -p 250 user@host
上面這條命令表示,ssh直接連接遠程服務器的250端口。
如果你是第一次登錄遠程服務器,系統會出現類似下面的提示:
The authenticity of host 'host (12.18.429.21)' can't be established.
RSA key fingerprint is 98:2e:d7:e0:de:9f:ac:67:28:c2:42:2d:37:16:58:4d.
Are you sure you want to continue connecting (yes/no)?
這段話的意思是,無法確認host服務器的真實性,只知道它的公鑰指紋,問你還想繼續連接嗎?
所謂"公鑰指紋",是指公鑰長度較長(這裡采用RSA算法,長達1024位),很難比對,所以對其進行MD5計算,將它變成一個128位的指紋。上例中是98:2e:d7:e0:de:9f:ac:67:28:c2:42:2d:37:16:58:4d,再進行比較,就容易多了。
很自然的一個問題就是:用戶怎麼知道遠程服務器的公鑰指紋應該是多少?回答是沒有好辦法,遠程服務器必須在自己的網站上貼出公鑰指紋,以便用戶自行核對。
假定經過風險衡量以後,用戶決定接受這個遠程服務器的公鑰(輸入yes,回車):
Are you sure you want to continue connecting (yes/no)? yes
系統會出現一句提示,表示host主機已經得到認可:
Warning: Permanently added 'host,12.18.429.21' (RSA) to the list of known hosts.
然後,會要求輸入密碼:
Password: (enter password)
如果密碼正確,就可以登錄了。
當遠程服務器的公鑰被接受以後,它就會被保存在文件$HOME/.ssh/known_hosts之中。下次再連接這台服務器,系統就會認出它的公鑰已經保存在本地了,從而跳過警告部分,直接提示輸入密碼。
每個SSH用戶都有自己的known_hosts文件,此外系統也有一個這樣的文件,通常是/etc/ssh/ssh_known_hosts,保存一些對所有用戶都可信賴的遠程服務器的公鑰。
從一台Windows電腦上通過SSH連接
從Windows電腦要連接到遠程的SSH服務器,有不少軟件可以幫助我們。不過一般常用的是PuTTY這個軟件。
PuTTY這個軟件可以從它的官網(www.putty.org,盡量不要去第三方軟件網站下載,以防有內置惡意程序)下載可直接運行的可執行程序putty.exe,也可以下載安裝程序(例如 putty-0.66-installer.exe):
下載或安裝完畢後雙擊軟件圖標打開軟件。
打開PuTTY後,可以看到如下窗口
在紅色方框處填入要連接的服務器的IP地址,然後點擊Open按鈕,如果是首次連接,會彈出以下窗口,點擊“是”即可:
在彈出的命令行窗口中依次輸入用戶名和密碼。注意Linux系統下輸入的所有密碼都是不可見的(也不會用星號表示),所以你不要以為是鍵盤壞了或者輸入不起作用,其實已經輸入了:
用密鑰實現自動身份驗證
使用密碼登錄,每次都必須輸入密碼,非常麻煩。幸虧SSH還提供了公鑰登錄,可以省去輸入密碼的步驟。
所謂"公鑰登錄",原理很簡單,就是用戶將自己的公鑰儲存在遠程服務器上。登錄的時候,遠程服務器會向用戶發送一段隨機字符串,用戶用自己的私鑰加密後,再發回來。遠程服務器用事先儲存的公鑰進行解密,如果成功,就證明用戶是可信的,直接允許登錄shell,不再要求密碼。
這種方法要求用戶必須提供自己的公鑰。如果沒有現成的,可以直接用ssh-keygen生成一個:
ssh-keygen
運行上面的命令以後,系統會出現一系列提示,可以一路回車。其中有一個問題是,要不要對私鑰設置口令(passphrase),如果擔心私鑰的安全,這裡可以設置一個。一般都不設置。
運行結束以後,在$HOME/.ssh/目錄下,會新生成兩個文件:id_rsa.pub和id_rsa。前者是你的公鑰,後者是你的私鑰。
這時再輸入下面的命令,將公鑰傳送到遠程服務器host上面:
ssh-copy-id user@host
好了,從此你再登錄,就不需要輸入密碼了。
如果還是不行,就打開遠程服務器的/etc/ssh/sshd_config這個文件,檢查下面幾行前面"#"注釋是否取掉。
RSAAuthentication yes PubkeyAuthentication yes AuthorizedKeysFile .ssh/authorized_keys
然後,重啟遠程服務器的ssh服務:
// Ubuntu系統
sudo service ssh restart
// Debian系統
sudo /etc/init.d/ssh restart
總結
我們可以遠程連接到Linux系統,進入它的終端。我們一般都是這樣操作遠程服務器的。
連接到遠程Linux服務器的電腦我們一般稱為client,就是客戶。我們可以從多種操作系統遠程連接到Linux的終端,比如從Windows,Linux,Mac系統。
在Windows下,為了遠程連接到遠程的Linux系統,一般我們會用PuTTY這個軟件。
在Linux和Mac下,為了遠程連接到Linux系統,我們可以用ssh命令,為它指定在遠程Linux機器上的登錄名(login)和遠程Linux機器的IP地址。例如: ssh [email protected]
通過SSH協議, 兩台機器之間傳遞的信息會被加密,這樣就保證了傳輸信息的安全性。
為了免去每次用SSH協議連接遠程機器都要輸入用戶密碼的麻煩,我們可以創建一個用於驗證身份的密鑰對(公鑰和私鑰)。公鑰需要傳輸並儲存到遠程機器上,私鑰則存在我們自己的電腦裡。之後,我們的SSH連接就不需要輸入密碼了。
今天的課就到這裡,一起加油吧!
下一課我們學習:文件傳輸,潇灑同步