SSH的英文全稱是Secure SHell。通過使用SSH,你可以把所有傳輸的數據進行加密,這樣"中間人"這種攻擊方式就不可能實現了,而且也能夠防止DNS和IP欺騙。還有一個額外的好處就是傳輸的數據是經過壓縮的,所以可以加快傳輸的速度。SSH有很多功能,它既可以代替telnet,又可以為ftp、pop、甚至ppp提供一個安全的"通道"。
統的網絡服務程序,如:ftp、pop和telnet在本質上都是不安全的,因為它們在網絡上用明文傳送口令和數據,別有用心的人非常容易就可以截獲這些口令和數據。而且,這些服務程序的安全驗證方式也是有其弱點的,就是很容易受到"中間人"(man-in-the-middle)這種方式的攻擊。所謂"中間人"的攻擊方式,就是"中間人"冒充真正的服務器接收你的傳給服務器的數據,然後再冒充你把數據傳給真正的服務器。服務器和你之間的數據傳送被 "中間人"一轉手做了手腳之後,就會出現很嚴重的問題。
最初SSH是由芬蘭的一家公司開發的。但是因為受版權和加密算法的限制,現在很多人都轉而使用OpenSSH。OpenSSH是SSH的替代軟件,而且是免費的,可以預計將來會有越來越多的人使用它而不是SSH。
SSH是由客戶端和服務端的軟件組成的,有兩個不兼容的版本分別是:1.x和2.x。用SSH 2.x的客戶程序是不能連接到SSH 1.x的服務程序上去的。OpenSSH 2.x同時支持SSH 1.x和2.x。
SSH的安全驗證是如何工作的
從客戶端來看,SSH提供兩種級別的安全驗證。
第一種級別(基於口令的安全驗證)只要你知道自己帳號和口令,就可以登錄到遠程主機。所有傳輸的數據都會被加密,但是不能保證你正在連接的服務器就是你想連接的服務器。可能會有別的服務器在冒充真正的服務器,也就是受到"中間人"這種方式的攻擊。
第二種級別(基於密匙的安全驗證)需要依靠密匙,也就是你必須為自己創建一對密匙,並把公用密匙放在需要訪問的服務器上。如果你要連接到SSH服務器上,客戶端軟件就會向服務器發出請求,請求用你的密匙進行安全驗證。服務器收到請求之後,先在你在該服務器的家目錄下尋找你的公用密匙,然後把它和你發送過來的公用密匙進行比較。如果兩個密匙一致,服務器就用公用密匙加密"質詢"(challenge)並把它發送給客戶端軟件。客戶端軟件收到"質詢"之後就可以用你的私人密匙解密再把它發送給服務器。
用這種方式,你必須知道自己密匙的口令。但是,與第一種級別相比,第二種級別不需要在網絡上傳送口令。
第二種級別不僅加密所有傳送的數據,而且"中間人"這種攻擊方式也是不可能的(因為他沒有你的私人密匙)。但是整個登錄的過程可能需要10秒。
安裝並測試OpenSSH
因為受到美國法律的限制,在很多Linux的發行版中都沒有包括OpenSSH。但是,可以從網絡上下載並安裝OpenSSH(有關OpenSSH的安裝和配置請參考:http://www.linuxaid.com.cn/engineer/brimmer/html/OpenSSH.htm)。
安裝完OpenSSH之後,用下面命令測試一下:
ssh -l [your accountname on the remote host] [address of the remote host]
如果OpenSSH工作正常,你會看到下面的提示信息:
The authenticity of host [hostname] can't be established.
Key fingerprint is 1024 5f:a0:0b:65:d3:82:df:ab:44:62:6d:98:9c:fe:e9:52.
Are you sure you want to continue connecting (yes/no)?
OpenSSH告訴你它不知道這台主機,但是你不用擔心這個問題,因為你是第一次登錄這台主機。鍵入"yes"。這將把這台主機的"識別標記"加到"~/.ssh/know_hosts"文件中。第二次訪問這台主機的時候就不會再顯示這條提示信息了。
然後,SSH提示你輸入遠程主機上你的帳號的口令。輸入完口令之後,就建立了SSH連接,這之後就可以象使用telnet那樣使用SSH了。
SSH的密匙
生成你自己的密匙對
生成並分發你自己的密匙有兩個好處:
1) 可以防止"中間人"這種攻擊方式
2) 可以只用一個口令就登錄到所有你想登錄的服務器上
用下面的命令可以生成密匙:
ssh-keygen
如果遠程主機使用的是SSH 2.x就要用這個命令:
ssh-keygen -d
在同一台主機上同時有SSH1和SSH2的密匙是沒有問題的,因為密匙是存成不同的文件的。
ssh-keygen命令運行之後會顯示下面的信息:
Generating RSA keys: ............................ooooooO......ooooooO
Key generation complete.
Enter file in which to save the key (/home/[user]/.ssh/identity):
[按下ENTER就行了]
Created directory '/home/[user]/.ssh'.
Enter passphrase (empty for no passphrase):
[輸入的口令不會顯示在屏幕上]
Enter same passphrase again:
[重新輸入一遍口令,如果忘記了口令就只能重新生成一次密匙了]
Your identification has been saved in /home/[user]/.ssh/identity.
[這是你的私人密匙]
Your public key has been saved in /home/[user]/.ssh/identity.pub.
The key fingerprint is: 2a:dc:71:2f:27:84:a2:e4:a1:1e:a9:63:e2:fa:a5:89 [user]@[local machine]
"ssh-keygen -d"做的是幾乎同樣的事,但是把一對密匙存為(默認情況下)"/home/[user]/.ssh/id_dsa"(私人密匙)和"/home/[user]/.ssh/id_dsa.pub"(公用密匙)。
現在你有一對密匙了:公用密匙要分發到所有你想用ssh登錄的遠程主機上去;私人密匙要好好地保管防止別人知道你的私人密匙。用"ls -l ~/.ssh/identity"或"ls -l ~/.ssh/id_dsa"所顯示的文件的訪問權限必須是"-rw-------"。
如果你懷疑自己的密匙已經被別人知道了,不要遲疑馬上生成一對新的密匙。當然,你還要重新分發一次公用密匙。
分發公用密匙
在每一個你需要用SSH連接的遠程服務器上,你要在自己的家目錄下創建一個".ssh"的子目錄,把你的公用密匙"identity.pub" 拷貝到這個目錄下並把它重命名為"authorized_keys"。然後執行:
chmod 644 .ssh/authorized_keys
這一步是必不可少的。如果除了你之外別人對"authorized_keys"文件也有寫的權限,SSH就不會工作。
如果你想從不同的計算機登錄到遠程主機,"authorized_keys"文件也可以有多個公用密匙。在這種情況下,必須在新的計算機上重新生成一對密匙,然後把生成的"identify.pub"文件拷貝並粘貼到遠程主機的"authorized_keys"文件裡。當然在新的計算機上你必須有一個帳號,而且密匙是用口令保護的。有一點很重要,就是當你取消了這個帳號之後,別忘了把這一對密匙刪掉。
配置SSH
配置客戶端的軟件
OpenSSH 有三種配置方式:命令行參數、用戶配置文件和系統級的配置文件("/etc/ssh/ssh_config")。命令行參數優先於配置文件,用戶配置文件優先於系統配置文件。所有的命令行的參數都能在配置文件中設置。因為在安裝的時候沒有默認的用戶配置文件,所以要把 "/etc/ssh/ssh_config"拷貝並重新命名為"~/.ssh/config"。
標准的配置文件大概是這樣的:
[lots of explanations and possible options listed]
# Be paranoid by default
Host *
ForwardAgent no
ForwardX11 no
FallBackToRsh no
還有很多選項的設置可以用"man ssh"查看"CONFIGURATION FILES"這一章。
配置文件是按順序讀取的。先設置的選項先生效。
假定你在www.foobar.com上有一個名為"bilbo"的帳號。而且你要把"ssh-agent"和"ssh-add"結合起來使用並且使用數據壓縮來加快傳輸速度。因為主機名太長了,你懶得輸入這麼長的名字,用"fbc"作為"www.foobar.com"的簡稱。你的配置文件可以是這樣的:
Host *fbc
HostName www.foobar.com
User bilbo
ForwardAgent yes
Compression yes
# Be paranoid by default
Host *
ForwardAgent no
ForwardX11 no
FallBackToRsh no
你輸入"ssh fbc"之後,SSH會自動地從配置文件中找到主機的全名,用你的用戶名登錄並且用"ssh-agent"管理的密匙進行安全驗證。這樣很方便吧!
用SSH連接到其它遠程計算機用的還是"paranoid(偏執)"默認設置。如果有些選項沒有在配置文件或命令行中設置,那麼還是使用默認的"paranoid"設置。
在我們上面舉的那個例子中,對於到www.foobar.com的SSH連接:"ForwardAgent"和"Compression"被設置為 "Yes";其它的設置選項(如果沒有用命令行參數)"ForwardX11"和"FallBackToRsh"都被設置成"No"。
其它還有一些需要仔細看一看的設置選項是:
l CheckHostIP yes
這個選項用來進行IP地址的檢查以防止DNS欺騙。
l CompressionLevel
壓縮的級別從"1"(最快)到"9"(壓縮率最高)。默認值為"6"。
l ForwardX11 yes
為了在本地運行遠程的X程序必須設置這個選項。
l LogLevel DEBUG
當SSH出現問題的時候,這選項就很有用了。默認值為"INFO"。
配置服務端的軟件
SSH服務器的配置使用的是"/etc/ssh/sshd_config"配置文件,這些選項的設置在配置文件中已經有了一些說明而且用"man sshd"也可以查看幫助。請注意OpenSSH對於SSH 1.x和2.x沒有不同的配置文件。
在默認的設置選項中需要注意的有:
l PermitRootLogin yes
最好把這個選項設置成"PermitRootLogin without-password",這樣"root"用戶就不能從沒有密匙的計算機上登錄。把這個選項設置成"no"將禁止"root"用戶登錄,只能用"su"命令從普通用戶轉成"root"。
l X11Forwarding no
把這個選項設置成"yes"允許用戶運行遠程主機上的X程序。就算禁止這個選項也不能提高服務器的安全因為用戶可以安裝他們自己的轉發器(forwarder),請參看"man sshd"。
l PasswordAuthentication yes
把這個選項設置為"no"只允許用戶用基於密匙的方式登錄。這當然會給那些經常需要從不同主機登錄的用戶帶來麻煩,但是這能夠在很大程度上提高系統的安全性。基於口令的登錄方式有很大的弱點。
l # Subsystem /usr/local/sbin/sftpd
把最前面的#號去掉並且把路徑名設置成"/usr/bin/sftpserv",用戶就能使用"sftp"(安全的FTP)了(sftpserv在sftp 軟件包中)。因為很多用戶對FTP比較熟悉而且"scp"用起來也有一些麻煩,所以"sftp"還是很有用的。而且2.0.7版本以後的圖形化的ftp工具"gftp"也支持"sftp"。
拷貝文件
用"scp"拷貝文件
SSH提供了一些命令和shell用來登錄遠程服務器。在默認情況下它不允許你拷貝文件,但是還是提供了一個"scp"命令。
假定你想把本地計算機當前目錄下的一個名為"dumb"的文件拷貝到遠程服務器www.foobar.com上你的家目錄下。而且你在遠程服務器上的帳號名為"bilbo"。可以用這個命令:
scp dumb
[email protected]:.
把文件拷貝回來用這個命令:
scp
[email protected]:dumb .
"scp"調用SSH進行登錄,然後拷貝文件,最後調用SSH關閉這個連接。
如果在你的"~/.ssh/config"文件中已經為www.foobar.com做了這樣的配置:
Host *fbc
HostName www.foobar.com
User bilbo
ForwardAgent yes
那麼你就可以用"fbc"來代替"
[email protected]",命令就簡化為"scp dumb fbc:."。
"scp"假定你在遠程主機上的家目錄為你的工作目錄。如果你使用相對目錄就要相對於家目錄。
用"scp"命令的"-r"參數允許遞歸地拷貝目錄。"scp"也可以在兩個不同的遠程主機之間拷貝文件。
有時候你可能會試圖作這樣的事:用SSH登錄到www.foobar.com上之後,輸入命令"scp [local machine]:dumb ."想用它把本地的"dumb"文件拷貝到你當前登錄的遠程服務器上。這時候你會看到下面的出錯信息:
ssh: secure connection to [local machine] refused
之所以會出現這樣的出錯信息是因為你運行的是遠程的"scp"命令,它試圖登錄到在你本地計算機上運行的SSH服務程序……所以最好在本地運行"scp"除非你的本地計算機也運行SSH服務程序。
用"sftp"拷貝文件
如果你習慣使用ftp的方式拷貝文件,可以試著用"sftp"。"sftp"建立用SSH加密的安全的FTP連接通道,允許使用標准的ftp命令。還有一個好處就是"sftp"允許你通過"exec"命令運行遠程的程序。從2.0.7版以後,圖形化的ftp客戶軟件"gftp"就支持"sftp"。
如果遠程的服務器沒有安裝sftp服務器軟件"sftpserv",可以把"sftpserv"的可執行文件拷貝到你的遠程的家目錄中(或者在遠程計算機的 $PATH環境變量中設置的路徑)。"sftp"會自動激活這個服務軟件,你沒有必要在遠程服務器上有什麼特殊的權限。
用"rsync"拷貝文件
"rsync" 是用來拷貝、更新和移動遠程和本地文件的一個有用的工具,很容易就可以用"-e ssh"參數和SSH結合起來使用。"rsync"的一個優點就是,不會拷貝全部的文件,只會拷貝本地目錄和遠程目錄中有區別的文件。而且它還使用很高效的壓縮算法,這樣拷貝的速度就很快。
用"加密通道"的ftp拷貝文件
如果你堅持要用傳統的FTP客戶軟件。SSH可以為幾乎所有的協議提供"安全通道"。FTP是一個有一點奇怪的協議(例如需要兩個端口)而且不同的服務程序和服務程序之間、客戶程序和客戶程序之間還有一些差別。
實現"加密通道"的方法是使用"端口轉發"。你可以把一個沒有用到的本地端口(通常大於1000)設置成轉發到一個遠程服務器上,然後只要連接本地計算機上的這個端口就行了。有一點復雜是嗎?
其實一個基本的想法就是,轉發一個端口,讓SSH在後台運行,用下面的命令:
ssh [user@remote host] -f -L 1234:[remote host]:21 tail -f /etc/motd
接著運行FTP客戶,把它設置到指定的端口:
lftp -u [username] -p 1234 localhost
當然,用這種方法很麻煩而且很容易出錯。所以最好使用前三種方法。
用SSH設置"加密通道"
"加密通道"的基礎知識
SSH 的"加密通道"是通過"端口轉發"來實現的。你可以在本地端口(沒有用到的)和在遠程服務器上運行的某個服務的端口之間建立"加密通道"。然後只要連接到本地端口。所有對本地端口的請求都被SSH加密並且轉發到遠程服務器的端口。當然只有遠程服務器上運行SSH服務器軟件的時候"加密通道"才能工作。可以用下面命令檢查一些遠程服務器是否運行SSH服務:
telnet [full name of remote host] 22
如果收到這樣的出錯信息:
telnet: Unable to connect to remote host: Connection refused
就說明遠程服務器上沒有運行SSH服務軟件。
端口轉發使用這樣的命令語法:
ssh -f [username@remote host] -L [local port]:[full name of remote host]:[remote port] [some command]
你不僅可以轉發多個端口而且可以在"~/.ssh/config"文件中用"LocalForward"設置經常使用的一些轉發端口。
為POP加上"加密通道"
你可以用POP協議從服務器上取email。為POP加上"加密通道"可以防止POP的密碼被網絡監聽器(sniffer)監聽到。還有一個好處就是SSH的壓縮方式可以讓郵件傳輸得更快。
假定你在pop.foobar.com上有一個POP帳號,你的用戶名是"bilbo"你的POP口令是"topsecret"。用來建立SSH"加密通道"的命令是:
ssh -f -C
[email protected] -L 1234:pop.foobar.com:110 sleep 5
(如果要測試,可以把"sleep"的值加到500)。運行這個命令之後會提示你輸入POP口令:
[email protected]'s password:
輸入口令之後就可以用"telnet"連接到本地的轉發端口了。
telnet localhost 1234
你會收到遠程mail服務器的"READY"消息。
當然,這個方法要求你手工輸入所有的POP命令,這是很不方便的。可以用Fetchmail(參考how to configure Fetchmail)。Secure POP via SSH mini-HOWTO、man fetchmail和在"/usr/doc/fetchmail-[…]"目錄下的Fetchmail的FAQ都提供了一些具體的例子。
請注意IMAP協議使用的是不同的端口:IMAP v2的端口號為143而IMAP v3的端口號為220。
為X加上"加密通道"
如果你打算在本地計算機上運行遠程SSH服務器上的X程序,那麼登錄到遠程的計算機上,創建一個名為"~/.ssh/environment"的文件並加上這一行:
XAUTHORITY=/home/[remote user name]/.Xauthority
(如果在遠程主機上你的家目錄下不存在".Xauthority"這個文件,那麼當用SSH登錄的時候就會自動創建)。
比如啟動一個X程序(xterm)可以這個命令:
ssh -f -X -l [remote user name] [remote machine] xterm
這將在遠程運行xterm這個程序。其它的X程序也是用相同的方法。
為linuxconf加上"加密通道"
Linuxconf(http://www.solucorp.qc.ca/linuxconf/)是Linux的配置工具,它支持遠程管理。Linuxconf的FAQ重說明了如何通過SSH使用linuxconf:
其命令為:
remadmin --exec [link_command] linuxconf --guiproto
如果你想在兩台計算機之間用加密的方式傳送信息,那麼最好用ssh。命令是:
remadmin --exec ssh -l [account] linuxconf --guiproto
這是非常有效的而且運行用圖形界面管理計算機。
這種方法需要在客戶端安裝linuxconf。其它的方法還有直接登錄到服務器上用"X11Forwarding"或字符界面運行linuxconf。
為Webmin加上"加密通道"
Webmin(http://www.webmin.com/webmin/)是一個新的基於浏覽器的配置工具。它運行在1000端口。你可以用SSH的"端口轉發"對它進行加密:
ssh -f -l [remote user name] [remote host] -L 1234:[remote host]:10000 tail -f /etc/motd
把浏覽器指向
http://localhost:1234
版權說明
這篇文章翻譯和改編自:http://www.mandrakeuser.org/secure/index.html。英文版的版權屬於"MandrakeSoft SA and LSTB 1999/2000"。
中文版版權歸譯者brimmer(
[email protected])和www.linuxaid.com.cn站點所有。
本文遵循Open Content Public Licence。