This is an article I translated for TS media for the Chinese Edition of Linux Journal. Original article on Linux Journal: The 101 Uses of OpenSSH: Part I 本文為筆者替天充文化翻譯 Linux Journal 中文版之文章,本譯文於2001 年 2 月號凌客誌中見刊。
使用OpenSSH的101種方法:Part I, 作者Mick將帶領我們深入剖析「ssh」的奧秘
作者:Mick Bauer / 譯者:劉自強 (TzuChiang Liou)
本文首先會介紹一段有關「Paranoid Penguin」(譯註:有偏執狂的企鵝)的故事。別擔心!這只是一段對Linux狂熱者的引言(也是您在LJ中期待會遇到的故事),事實上,有許多狂熱及愛好者都在使用OpenSSH,而本文也會在下一期LJ中一一道出。
本月我們會先討論「ssh」的背景及架構,像是如何建構及安裝OpenSSH、如何使用「ssh」成為「Telnet」安全的替代方案、如何配置「ssh」基礎的設定選項,及如何使用「scp」作為安全的檔案傳輸方式等。而在下一期我則會介紹「RSA/DSA」認證架構、本地端的「port-forwarding」、遠端的命令列執行方式,及其他許多「ssh/OpenSSH」進階及強大的功能。
SSH細說從頭
在Unix世界裡有個非常酷的事情是,使用者可以在遠端透過主控台(consoles)用許多不同的方法來做系統管理,然而比較不理想的是,大多數方法(如Telnet,、rsh及X等等)在網路上都是用未加密的文字傳輸所有訊息,當然也包含了密碼在內。除此之外,我們以往所信賴的網路上已經有越來越多的無聊人士及封包竊聽的方法,因此使得純文字的網路應用管理方式變得有點過時了。
話說在幾年前一個居住在芬蘭名為Tatu Ylonen的「uber-hacker」設計了一個非常酷的程式叫做「Secure Shell」(也可以稱作「ssh」)。基本上「ssh」的功能和Sun的「rsh」、「rcp」、「rlogin」等指令相呼應,只有一項比較大的差異,那就是:偏執(Paranoid)!「ssh」可以讓您完成任何「rsh」、「rcp」、「rlogin」能做的事,並且可以採用「libertarian-grade」等級的編碼方式或是認證的方法來完成工作。或許您會說,其中不是有一個非常倚賴「RSA」的「ssh」版本嗎?是的,那個版本的確非常好用,但是就如同我們所說的,這是一個受到專利法拖累的科技產品,除非是非商業用途使用,否則任何想使用這個應用程式的人都必須要藉由購買來得到授權,不過即使容許非商業用途使用,「ssh」的合法性也是備受質疑。
或許您又會說,美國政府對「RSA」的專利保護在2000年九月時已經過期了不是嗎,這樣還有問題嗎?答案是肯定的,因為Tatu先生也必須要過日子,所以當「RSA」法律上的問題解禁之後,Tatu的公司「F-Secure」卻改變了授權方式,使得「ssh」本身變得更加受牽制。事實上,自「ssh」2.0版開始,已經不允許未經授權或是非商業用途的使用(到此為止已經與「RSA」的議題無關了)。這些都違反了Tatu希望「ssh」成為網路標準的想法,因為要成為標準,其中一項重要的因素是至少要有一個版本是可以自由取得的。
接下來讓我們把鏡頭轉向Theo de Raadt及「OpenBSD」工作小組,這是NetBSD的一個旁支,特別重視安全性的議題,同時當然也是一個可以自由取得的BSD UNIX版本,當時Theo和「OpenBSD」計畫裡的開放原始碼同好們希望把「ssh」也包含在「OpenBSD 2.6」版中,但一方面又擔心「ssh」的許多限制會有所影響。因此當他們知道瑞典程式設計師Bjoern Groenvall把他對於Ylonen的「ssh」之修正版本釋出時(1.2.12,也是最新版可以自由取得的ssh版本──除了與RSA相關之外),「OpenBSD」的成員立刻更新並把這個程式修改成為合適更大多數人使用,自此,「OpenSSH」便成為「OpenBSD」的一部分,同時也成為後來大多數Unix系統的可選擇套件之一。
「OpenSSH」建構在Groenvall的基礎架構上(他的版本叫做OSSH,目前在網路上仍然可以取得),但是增加了對新版本的ssh通訊協定的支援、並且以模組化的方式來建構他的編碼機制,如此一來,在編譯「OpenSSH」時便可以避開那些受到專利保護的運算規則(例如:可以選擇不要支援ssh第一版,因為該版需要使用RSA)。另一項「OpenBSD」團隊做的改良是把「OpenSSH」的編碼基礎方式設計成為一個比較「clean」的版本,也就是盡量保持簡單而可以達到平台獨立性、使其成為可移植(portable)的版本,讓使用者可以針對其他許多不同的Unix系統,順利編譯該程式。
最後一項更新特別和Linux玩家有關,那就是這個經過「clean」的版本的程式碼非常乾淨清晰易懂,因而保證他的基礎穩定性及安全性。更由於程式碼是經過像Theo這樣的偏執狂臨幸過、並加強一些功能,所以我們相信這個套件是完全安全而且與Linux百分之一百相容。
順帶一提,當「OpenBSD」團隊發現「OSSH」、到發表「OpenSSH 1.2.2」之間總共花不到兩個月的時間,而大約在六週半之後,他們又釋出了完全可移植的版本及與「ssh v.2」版完全相容的「OpenSSH 2.0」。雖然說他們是建構在Ylonen’s及 Groenvall’s 的基礎上進行,但能達到這樣的成績已經是相當的不簡單了,尤其是當我們看到成品的品質那麼優秀而且沒有人從中獲利時,更可以了解到這是件不容易的事情。
以上就是「ssh」及「OpenSSH」的故事,希望您也能體會到這就像「OpenSSH」軟體本身一樣,這也是非常令人讚嘆的故事。相信這個程式應該在不久的將來就會成為大部份開放原始碼UNIX系統內建的版本。
現在,您是否已經激起對「OpenSSH」的熱愛,並且準備好要安裝在所有的UNIX系統了呢?非常好,那就讓我們開始動手吧!
再提醒一下,「ssh v.1.x」及「ssh protocol v.1」分別是指ssh的軟體釋出版本及通訊協定,表示的並不是同一件事。但因為套件及通訊協定的主要版本號碼大致都有相關,所以接下來我會用「ssh v.1x」指涉那些以「RSA」為基礎的「ssh/OpenSSH」版本,而以「ssh v.2x」來指稱那些同時支援「RSA」及「DSA」的版本,如果您不知道「RSA」及「DSA」之間的差別的話,您可以這樣來理解:兩者指的都是同樣的技術,但是「DSA」沒有專利法拖累或是授權條款的限制。
SSH的運作方式
基本上,SSH的運作方式和網頁交易機制的「Secure Sockets Layer」非常類似(這並不是巧合,因為OpenSSH用的編碼方式正是由OpenSSL所提供,而那是一個Netscape的Secure Sockets Layer原始碼函式庫的免費版本)。兩者都可以用沒有專利保護的熱鍵來設定編碼管道、同時也可以使用數位簽證的方式(也就是由第三公正權威單位來做認證如:VeriSign等),以下針對聯結建立的方式作介紹:
首先,客戶端和伺服器端互相交換「(public) host keys」(也就是公鑰),此時如果客戶端發現沒有遇過相同的公鑰時,ssh和大部分的瀏覽器都會詢問使用者是否要接受這個未經認證的公鑰,接下來,兩者使用這些機制來協調出一個「session key」,並藉由「Triple-DES (3DES)」、「blowfish」或是「idea」等「block cipher」的機制,把所有後來的資料都加密起來。
>接著,伺服器端會企圖使用「RSA」或「DSA」來認證客戶端,如果不成功的話,客戶端會出現一個要求輸入使用者名稱/密碼的提示(關於這點是可以選擇的,如果您是用「rhosts」這種以主機IP為認證基礎的方式,不論是否有「RSA」都可以使用,同時OpenSSH也支援「KerberosIV」及「skey」)。經過成功的認證之後,便開始正式的交換訊息,自此不論是一個遠端的殼層操作、或是安全的檔案傳輸等等,都可以在一個被編碼過後的管道中進行。
就像我之前提過的一樣,「ssh」事實上是一組工具的組合,在此介紹如下:
「Dssh d」-是用來接受所有指令操作的「Server Daemon」
「Dssh」-主要是終端使用者的工具:用來做遠端殼層操作、遠端指令執行及遠端「port-forwarding」的操作。
「Dscp」-自動化的檔案傳輸工具
「Dsftp」-用來做互動式的檔案傳輸-只有在商業版的SSH才能使用
「Dssh-keygen」-密碼產生器,用來產生「RSA」及「DSA」用來認證的公鑰及私鑰「public key pairs」(包含host keys)
「Dssh-agent」-將客戶端「RSA/DSA」認證自動化的一個「daemon」
「Dssh-add」-將公鑰(private keys)載入「ssh-agent」的機制
「Dssh-askpass」-是一個「ssh-add」的X介面
請注意,你們也許曾注意到「sftp」這個有編碼功能及認證機制的FTP傳輸方式,或是在別的參考文件上看到相關的介紹,不過我在這裡只會介紹「scp」,那是因為「sftp」目前只能在F-Secure公司的「ssh version 2」的商業版本中使用該程式的緣故。
基本上「加密過的Telnet」是使用ssh最簡單的範例,而在這些工具中,大多數的人關心的通常也只是這項功能。不知道Scp(包含ssh-agent及ssh-add)有著強大認證機制及TCP「port-forwarding」功能,這些功能可以使得ssh變得更有彈性、更好用。所以既然我們身為偏執狂,而又想把在網路上面傳輸的訊息盡量加密的話,我們就應該好好的來利用、享受這樣的彈性機制。
取得和安裝OpenSSH
「OpenSSH」的官方網站(請參考資源列表)是獲得「OpenSSH」最新版本的一個地方(原始碼和「RPM」兩種格式裡面都有),該網站內也有「OpenSSL」(這是安裝「OpenSSH」時所需要的)、以及安裝「OpenSSH」時需要的另一個程式「zlib」(可以由freesoftware.com網站中得到-請參考資源列表)。
您可能無法完全使用「RPM」套件的方式來安裝,比如當我嘗試在我的筆記型電腦(我跑的是SuSE Linux)上面安裝由OpenSSH.com上面下載的「RPM」套件時,幾乎所有的東西都可以正常運作,但獨獨「sshd」無法運作,無法安裝的原因是因為SuSE沒有「chkconfig」這個套件,所以您所使用的Linux發行版本也可能會有類似的問題,或著也可能會有針對不同版本的「OpenSSH」RPM套件,您可以仔細找找。(就我所知,當您讀到本文時,某人可能正在製作SuSE的「RPM」套件)。
如果當「RPM」套件無法成功安裝,您就必須要自己從原始碼編譯「OpenSSH」(甚至是「OpenSSL」或「zlib」都有可能需要您自己編譯),對那些比較老舊的Linux系統而言,可以使用「rolling your own」的軟體安裝方式,如果您不屬於這個類型的話也不要絕望,因為這三個套件都只需要簡單的使用「.configure」來幫大多數的使用者省去編寫「makefiles」的動作,假設您的系統裡有「gcc」及其他一般該有的系統函式庫(當然是最新的會比較好),那麼安裝的過程是又快又簡單。
在我的例子裡,安裝完「OpenSSL 0.9.5a」及「zlib-1.1.3」(對了,或許當您看到本文時,這些或許已經不是最新版了)之後,我依照下面的幾個步驟來建構及安裝「OpenSSH 2.1.1p4」:
tar -xzvf openssh-2.1.1p4.tar.gz
cd openssh-2.1.1p4
./configure --sysconfdir=/etc/ssh
make
make install
依照「INSTALL」檔提供的步驟,我在設定命令稿中增加一個客製化的選項:我選擇把所有的設定檔案安裝在/etc/sshd這個目錄裡面,而不是預設的/etc。因為這個版本的「OpenSSH」有支援「RSA」和「DSA」,所以最好把/etc裡面ssh 相關雜亂的檔案減低到最少。
如果您只要安裝客戶端應用程式的話,只需要安裝到這裡就可以了,請注意,當您閱讀本文時,上面所提及任何軟體的版本都有可能已經不是最新版了,所以請記得到「OpenSSH」和「zlib」的網站上找最新的版本來用。
如果您想要執行「Secure Shell daemon」(也就是「sshd」),比如說想要接受遠端的ssh連線時,則必須要編寫啟動命令稿,以SuSE為例,您必須要編輯「/etc/rc.config」這個檔案。而這些作者也都替您想好了,在原始套件的「contrib」目錄中有一些不錯的好東西可以參考一下。
比如,在「Red Hat」這個目錄裏有一個「sshd.init」檔,您可以複製到/etc/rc.d裡面,並且連結到適當的「run-level」目錄去(比如說/etc/rc.d/rc2.d裡)。而如果您有使用「Pluggable Authentication Modules (PAM)」的話,這裡也有一個「sshd.pam」檔,可以把他複製到/etc/pam裡。同時也可以使用「openssh.spec」來建立自己的「OpenSSH」RPM套件。需要注意的是,雖然這些工具看起來很明顯的都是針對「Red Hat」系統設計的,但是同樣也可以在「Red Hat」系統的分支上運作良好(如Mandrake或是Yellow Dog等等)。
在「SuSE」的目錄裡同樣也有一個「openssh.spec」檔可以用來針對「SuSE」建立「OpenSSH」PRPM套件;也有「rc.sshd」檔案可以用來安裝在/etc/rc.d這個目錄內(在「SuSE」裡是/sbin/init.d)。另外如果要讓「rc.sshd」這個命令稿運作正常的話,必須要把「rc.config.ssd」加到/etc/rc.config裡面,我們可以藉由下面這個簡單的步驟來完成:
cat ./rc.config.ssd > /etc/rc.config
接下來就是替「rc2.d」及/或「rc3.d」建立符號連結(symbolic link),這麼一來,您的「SuSE」就可以使用安全的殼層操作了!不過記得要先重新開機或是執行「/etc/rc.d/rc.sshd start」來重新啟動daemon。
大眾化的SSH功能-編碼過的遠端工具Telnet
如果您需要的只是透過「Telnet」和遠端系統作互動式的殼層操作的話,有一個甚至不用看設定檔就可以執行的操作方法,就是只要簡單的輸入下面的指令即可:
ssh remote.host.net
執行後系統會要求您輸入密碼(SSH會假設您希望使用和本地端電腦同樣的使用者帳號來簽入遠端的電腦),如果密碼通過了,您就進到系統裡去了,這絕對是最簡單、而且無庸置疑的比telnet安全許多的方式。
如果您不想用本地端的使用者帳號簽入遠端伺服器,而想用不同的帳號簽入時,您需要使用參數「l」,並且在後面加上您想用來簽入的使用者帳號。如:假設我在筆記型電腦上使用「mick」這個帳號簽入,但是想要用ssh以「mbauer」這個帳號簽入「kong-fu.mutantmonkeys.org」裡,我會使用下面的指令:
ssh -l mbauer kong-fu.mutantmonkeys.org
這樣做有什麼改變呢?用Telnet看起來好像都一樣,不同的是,輸入這個指令後,系統會詢問我是否要接受遠端伺服器的公鑰「public key」,依照網路品質、伺服器的負載不同等因素,這個過程可能要花點時間才能完成。使用這種方式的平均連線速度可能會比Telnet慢一點(雖然我感覺不太出來),不過好處是當簽入伺服器時,我的使用者帳號和密碼不會以文字型態在網路上傳輸,同時所有傳輸的訊息也都會經過加密。所以我就不用擔心會被竊聽,而可以做任何我想做的事(包含su)。而且重點是對我的負擔不大。
深入設定檔
修改配置「OpenSSH」並不會很複雜,如果想要控制「ssh」的伺服器端及客戶端行為的話,只要修改下面兩個檔案即可:「ssh_config」及「sshd_config」,依照您安裝時的設定,這些檔案的位置可能會在「/etc」或是任何您指定的目錄裡。其中「ssh_config」是一個全域(global)的設定檔,主要針對本地主機的「ssh」客戶端連結設定作修改。然而這個全域變數並不是在所有情況下都適用,比如當使用者以命令列輸入指令時,就算和這個檔案的設定不同,仍然可以正常執行;或是當使用者有個別的設定檔時也不會受它的影響(如果有的話,會放在「$HOME/.ssh/config」裡面),例如假設「/etc/ssh/ssh_config」裡面有下面這一行字:
Compression no
但「/home/bobo/」裡面的檔案設定是
.ssh/config
contains the line
Compression yes
這麼一來,不論使用者bobo何時使用「ssh」連線,「Compression」的預設都是可以支援。但是其他在「$HOME/.ssh/」沒有設定檔的使用者的預設值是「Compression」無法使用。不過再從另一個角度來看,假設bobo下面的指令來執行ssh時:
ssh -o Compression=no remote.host.net
這麼一來,在此次的連線中「Compression」將無法使用。換句話說ssh參數執行的順序呈現一個遞減的順序,依序是命令列、「$HOME/.ssh/config」、及「/etc/ssh/ssh_config」。
「ssh_config」裡面包含了一系列的子機碼,每一行一個,依照下面的設置
parameter value(s)
有些子機碼是布林運算,因此他的參數值可以包含「yes」或「no」,有些則可能包含以逗號分開的一串數值,大多數的子機碼上面都會有一些說明和解釋,而您也可以在ssh的「man page」裡面找到所有的解釋。我在列表一裡面列出一些比較好用或是重要的出來改大家參考(斜體字代表可能的數值)
除此之外還有很多的選項,我會在本文的第二部分提及,如果您想要看比較完整的清單,可以先查閱「man page」。
設定及執行「sshd」–「Secure Shell daemon」
以上所討論的大多是在當您想要聯結別人的主機時應注意的事項,接下來我們要談的是如何設定您的主機來接受其他人的ssh連線。其實這也是非常的簡單。
我們知道,「ssh」的客戶端主機的各種行為都可以在單一檔案裡面設定完成,也就是「sshd_config」,這個檔案可能在「/etc」裡或是在任何您指定安裝的目錄裡。在ssh客戶端的執行順序上,命令列又比設定檔的配置優先,這是我們所知道客戶端的設定問題。然而伺服器端不同的是,在使用者的家目錄裡,沒有針對個別的使用者的「daemon」設定檔,也就是說一般使用者無法指定「daemon」的行為。
列表二裡面描述的是一些可以在「sshd_config」檔案裡面設定的選項,除了列表二所列的項目之外,在「sshd_config」裡其實還有很多項目可以設定,下個月我們會談更多相關的設定,不過剛剛介紹的那些已經夠讓我們玩一陣子了(在此假設您主要的需求只需要一個「Telnet」及「ftp」安全的替代方案)。
使用「scp」來傳輸加密的檔案
在結束之前我們還會談另一個ssh的主題,也就是「scp」相關的指令,這個指令在某些程度上和傳統的「rcp」功能相類似(事實上「scp」就是在「rcp」的原始碼上作修改而成的),也就是用來在遠端和近端主機之間複製檔案或目錄。如果兩者您都不熟悉的話,要先告訴您的是,兩個命令都不是互動式的,而且都需要判隨著一個命令列指令,在該行命令裡您必須明確指出您想要傳輸的檔案及您要傳達位址的完整名稱及路徑。
因為「scp」這項非互動性的特質,使得「scp」看起來比「Ftp」不容易使用:因此不論您喜不喜歡,如果想要使用「scp」就應該詳讀「man page」裡面的說明(或是像本文這樣的文章),並熟記相關的指令參數。但就像其他的命令列工具一樣,對命令稿語言而言,「scp」遠比一些互動性的工具來的好用。如果您想要馬上就享受「scp」也是非常簡單的,「scp」基本的命令語法如下:
scp [ options ] sourcefilestring destfilestring (scp [參數] 原始檔 目的檔)
原始檔及目的檔的檔案描述可以是一般的「UNIX」的檔案路徑表示方式,(如「./docs/hello.txt」或是「/home/me/mydoc.txt」等等),也可以是以主機為分界的格式如下
username@remote.host.name:path/filename
舉例來說,如果您目前簽入到名為「crueller」的主機裡,並且想要傳輸「recipe」檔到您的家目錄及遠端主機「kolach」上,再假設您在兩台主機的系統上都有同樣的使用者名稱時,相關的指令看起來會像是這樣子:
crueller: > scp ./recipe kolach:~
mick@kolach's password: *******
recipe 100% |**************>| 13226 00:00
crueller: >
當我們輸入「scp」命列時,系統會要求我們輸入密碼(如果沒有特別指定的話,系統會自動的以目前我們簽入crueller主機的使用者帳號傳輸到遠端主機上),「scp」在傳輸檔案的過程中,會顯示出目前的進度,如此就完成了安全的檔案傳輸了,簡單吧!
如果您用「mick」這個帳號簽入crueller主機裡,而想要把檔案寫入到遠端主機kolach的「data/recipes/pastries」目錄裡,但在遠端主機kolach的帳號卻是「mbauer」時,需要輸入的指令如下:
crueller: > scp ./recipe mbauer@kolach:/data/recipies/pastries/
現在讓我們反過來試試看,假設我們想要從遠端主機kolach的目錄裡,擷取檔案「/etc/oven.conf」過來(目前我們仍然簽入在近端主機crueller),此時我們的命令會如下所示:
crueller: > scp mbauer@kolach:/etc/oven.conf.
了解了嗎?重點是來源檔案的描述必須放在目的檔的前面
雖然大部分的使用者多半只用「ssh」來替代簽入和檔案傳輸的功能,但其實這些只使用到「ssh」的皮毛,下個月我們會檢視要如何使用「RSA」及「DSA」來讓傳輸過程更安全、如何使用「null-passphrase」來讓命令稿語言也能包含「ssh」的指令、如何把「ssh」認證資訊暫存在記憶體中以避免不必要的手續等等功能,最後會討論到如何將其他的TCP服務也透過加密的「ssh」連線來進行。
Mick Bauer (mick@visi.com),目前擔任ENRGI在Minneapolis的安全問題專家,該公司為一家網路工程及顧問公司,作者自1995年開始就已經是Linux的愛好者,並且在1997開始熱衷於OpenBSD,非常喜歡在一些破舊的設備上執行這些尖端的作業系統。Mick非常歡迎大家向他提出問題、批評和問候。
side words
在Unix世界裡有個非常酷的事情是,使用者可以透過遠端「consoles」用許多不同的方法來做系統管理
ssh…有一向非常重要的的特質:偏執
我不用擔心會被竊聽,而可以做任何我想做的事(包含su在內)。
列表一:ssh_config裡面一些基礎的客戶端選項
子機碼 可能的數值 描述
CheckHostIP Yes No (Default=yes) 用來檢視已知的主機公鑰和來源IP是否相符合,並於每次發現不一致時警告使用者。
Cipher 3des blowfish (Default=3des) 用來決定使用哪種「block ciphers」來針對「ssh v.1」加密。
Ciphers 3des-cbc 用來定義使用「block ciphers」、「blowfish-cbc」或「arcfour」的順序,可以用來針對「ssh v.2」作加密。
Compression Yes No 決定是否針對要加密的資料壓縮,這點在連線頻寬有限時非常好用,但也可能會增加延遲的時間。
ForwardX11 Yes No (Default=no) 決定是否再加密的通道上使用X的連線,並將「DISPLAY」也設定在其中,這是非常貼心的設計。
Password- Yes No 決定是否嘗試去認證加密過的「UNIX」密碼,而不使用「RSA/DSA」的方法。
列表二:設定「sshd_config」裡的子機碼
子機碼 可能的數值 描述
Port number (Default=22) 決定「daemon」應該接收哪個「TCP」port的請求,當您使用連結埠轉送功能來讓同一個IP指定許多主機時,這就是非常好用的功能。
PermitRootLogin yes no 決定是否可以讓「root」簽入,最好設定為「no」,因為系統管理者最好是用沒有特權的帳號簽入,如果要使用「root」的指令時,只要使用「su」暫時轉換即可。
PasswordAuthentication yes no (Default=yes) 決定是否使用加密過的使用者帳號及密碼來認證,或是堅持使用以「DSA」或「DSA」為基礎的認證方式。
PermitEmptyPasswords yes no (Default=no) 決定是否讓沒有系統密碼的使用者簽入,這個選項在「PasswordAuthentication」設定為「no」時沒有用處,同時,也無法應用「DSA」或「RSA」的使用當中。
X11Forwarding yes no (Default=no) 決定是否允許客戶端在SSH的連線中使用「X-Windows」的應用程式,在此設定為「no」似乎也沒有什麼好處,因為在「sshd_config」裡無法similarly disable。
相關資源
OpenSSH: http://www.openssh.com
zlib: ftp://ftp.freesoftware.com/pub/infozip/zlib
generic TCP forwaring (which can be usedto forward X11).