# 11.2 文字接口聯機服務器: SSH 服務器
## 11.2 文字接口聯機服務器: SSH 服務器
由于先前的遠程聯機服務器大多是明碼,而且協議也有些資安問題,因此后來就有 SSH 這個協議來取代上述這些咚咚。 那么 SSH 是什么呢?它有什么特異功能?簡單的來說,SSH 是 **S**ecure **SH**ell protocol 的簡寫 (安全的殼程序協議),它可以透過數據封包加密技術,將等待傳輸的封包加密后再傳輸到網絡上, 因此,數據訊息當然就比較安全啰!這個 SSH 可以用來取代較不安全的 finger, R Shell (rcp, rlogin, rsh 等), talk 及 telnet 等聯機模式。底下我們將先簡介一下 SSH 的聯機模式,來說明為什么 SSH 的數據訊息會比較安全呢!
特別注意:這個 SSH 協議,在預設的狀態中,本身就提供兩個服務器功能:
1. 一個就是類似 telnet 的遠程聯機使用 shell 的服務器,亦即是俗稱的 ssh ;
2. 另一個就是類似 FTP 服務的 sftp-server !提供更安全的 FTP 服務。
- - - - - -
### 11.2.1 聯機加密技術簡介
什么是『數據加密』呢?簡單的說,就是將人們看的懂得原始電子數據,經過一些運算,讓這些數據變成沒有意義的亂碼 (至少對人類來說),然后再讓這個咚咚在網絡上面傳輸,而當用戶想要查閱這個數據時,再透過解密運算, 將這些咚咚反推出原始的電子數據。由于這些數據已經被重新處理過,所以,即使數據在因特網上被 cracker 監聽而竊取,他們也不容易就推算得出來原始資料內容的。
**Tips:** 鳥哥常常說,加密機制有點像是兩個人之間的火星語對話啦!如果你跟你的朋友約定好使用你們制訂的某種特別語言, 這個語言只對你們兩個有意義。那么當你們兩人講話時,在旁邊的人聽到的只是一堆沒有意義的聲音,因為他們聽不懂啊! 即使路人將你的聲音錄下來,只要他不知道你們的特殊用語,那他就不可能了解你們對話的內容啰。

加解密運算的機制與技術非常多,我們這里不去討論復雜的理論問題,只談對我們比較有關的一些加解密概念而已。 目前常見的網絡封包加密技術通常是藉由所謂的『非對稱密鑰系統』來處理的。 主要是透過兩把不一樣的公鑰與私鑰 (Public and Private Key) 來進行加密與解密的過程。由于這兩把鑰匙是提供加解密的功用, 所以在同一個方向的聯機中,這兩把鑰匙當然是需要成對的!它的功用分別如下:
- 公鑰 (public key):提供給遠程主機進行數據加密的行為,也就是說,**大家都能取得你的公鑰來將數據加密**的意思;
- 私鑰 (private key):遠程主機使用你的公鑰加密的數據,在本地端就能夠使用私鑰來進行解密。由于私鑰是這么的重要, **因此私鑰是不能夠外流的!只能保護在自己的主機上。**
由于每部主機都應該有自己的密鑰 (公鑰與私鑰),且公鑰用來加密而私鑰用來解密, 其中私鑰不可外流。但因為網絡聯機是雙向的,所以,每個人應該都要有對方的『公鑰』才對!那如果以 ssh 這個通訊協議來說,在客戶端與服務器端的相對聯機方向上,應該有如下的加密動作:

圖 11.2-1、公鑰與私鑰在進行數據傳輸時的角色示意圖
如上圖所示,我們如果站在客戶端的角度來看,那么,首先你必須要取得服務器端的公鑰,然后將自己的公鑰發送給服務器端, 最終在客戶端上面的密鑰會是『服務器的公鑰加上客戶端我自己的私鑰』來組成的。
**Tips:** 數據加密的技術真的相當的多,也各有其優缺點,有的指令周期快,但是不夠安全;有的夠安全,但是加密/解密的速度較慢~ 目前在 SSH 使用上,主要是利用 RSA/DSA/Diffie-Hellman 等機制喔!

目前 SSH 的協議版本有兩種,分別是 version 1 與 version 2 ,其中 V2 由于加上了聯機檢測的機制, 可以避免聯機期間被插入惡意的攻擊碼,因此比 V1 還要更加的安全。所以啰,請盡量使用 V2 版本即可,不要使用 V1 啰。 無論是哪種版本,都還是需要公私鑰加密系統的,那么這些公鑰與私鑰是如何產生的呢?底下我們就來談一談啦!
- SSH 的聯機行為簡介
我們可以將 ssh 服務器端與客戶端的聯機步驟示意為下圖,至于步驟說明如后:

圖 11.2-2、ssh 服務器端與客戶端的聯機步驟示意圖
1. 服務器建立公鑰檔: 每一次啟動 sshd 服務時,該服務會主動去找 /etc/ssh/ssh\_host\* 的檔案,若系統剛剛安裝完成時,由于沒有這些公鑰檔案,因此 sshd 會主動去計算出這些需要的公鑰檔案,同時也會計算出服務器自己需要的私鑰檔;
2. 客戶端主動聯機要求: 若客戶端想要聯機到 ssh 服務器,則需要使用適當的客戶端程序來聯機,包括 ssh, pietty 等客戶端程序;
3. 服務器傳送公鑰檔給客戶端: 接收到客戶端的要求后,服務器便將第一個步驟取得的公鑰檔案傳送給客戶端使用 (此時應是明碼傳送,反正公鑰本來就是給大家使用的!);
4. 客戶端記錄/比對服務器的公鑰數據及隨機計算自己的公私鑰: 若客戶端第一次連接到此服務器,則會將服務器的公鑰數據記錄到客戶端的用戶家目錄內的 ~/.ssh/known\_hosts 。若是已經記錄過該服務器的公鑰數據,則客戶端會去比對此次接收到的與之前的記錄是否有差異。若接受此公鑰數據, 則開始計算客戶端自己的公私鑰數據;
5. 回傳客戶端的公鑰數據到服務器端: 用戶將自己的公鑰傳送給服務器。此時服務器:『具有服務器的私鑰與客戶端的公鑰』,而客戶端則是: 『具有服務器的公鑰以及客戶端自己的私鑰』,你會看到,在此次聯機的服務器與客戶端的密鑰系統 (公鑰+私鑰) 并不一樣,所以才稱為非對稱式密鑰系統喔。
6. 開始雙向加解密: (1)服務器到客戶端:服務器傳送數據時,拿用戶的公鑰加密后送出。客戶端接收后,用自己的私鑰解密; (2)客戶端到服務器:客戶端傳送數據時,拿服務器的公鑰加密后送出。服務器接收后,用服務器的私鑰解密。
在上述的第 4 步驟中,客戶端的密鑰是隨機運算產生于本次聯機當中的,所以你這次的聯機與下次的聯機的密鑰可能就會不一樣啦! 此外在客戶端的用戶家目錄下的 ~/.ssh/known\_hosts 會記錄曾經聯機過的主機的 public key ,用以確認我們是連接上正確的那部服務器。
例題:如何產生新的服務器端的 ssh 公鑰與服務器自己使用的成對私鑰? (注:注意,本例題不要在已經正常運作的網絡服務器上面,因為可能會造成其他客戶端的困擾!)答:由于服務器提供的公鑰與自己的私鑰都放置于 /etc/ssh/ssh\_host\* ,因此你可以這樣做:
```
[root@www ~]# rm /etc/ssh/ssh_host* <==刪除密鑰檔
[root@www ~]# /etc/init.d/sshd restart
正在停止 sshd: [ 確定 ]
正在產生 SSH1 RSA 主機密鑰: [ 確定 ] <==底下三個步驟重新產生密鑰!
正在產生 SSH2 RSA 主機密鑰: [ 確定 ]
正在產生 SSH2 DSA 主機密鑰: [ 確定 ]
正在激活 sshd: [ 確定 ]
[root@www ~]# date; ll /etc/ssh/ssh_host*
Mon Jul 25 11:36:12 CST 2011
-rw-------. 1 root root 668 Jul 25 11:35 /etc/ssh/ssh_host_dsa_key
-rw-r--r--. 1 root root 590 Jul 25 11:35 /etc/ssh/ssh_host_dsa_key.pub
-rw-------. 1 root root 963 Jul 25 11:35 /etc/ssh/ssh_host_key
-rw-r--r--. 1 root root 627 Jul 25 11:35 /etc/ssh/ssh_host_key.pub
-rw-------. 1 root root 1675 Jul 25 11:35 /etc/ssh/ssh_host_rsa_key
-rw-r--r--. 1 root root 382 Jul 25 11:35 /etc/ssh/ssh_host_rsa_key.pub
# 看一下上面輸出的日期與檔案的建立時間,剛剛建立的新公鑰、私鑰系統!
```
- - - - - -
### 11.2.2 啟動 SSH 服務
事實上,在我們使用的 Linux 系統當中,默認就已經含有 SSH 的所有需要的軟件了!這包含了可以產生密碼等協議的 [OpenSSL](http://www.openssl.org/) 軟件與 [OpenSSH](http://www.openssh.com/) 軟件 ([注1](#ps1)),所以呢,要啟動 SSH 真的是太簡單了!就直接給他啟動就是了!此外,在目前的 Linux Distributions 當中,都是預設啟動 SSH 的,所以一點都不麻煩,因為不用去設定,他就已經啟動了! 哇!真是爽快~無論如何,我們還是得說一說這個啟動的方式吧!直接啟動就是以 SSH daemon ,簡稱為 sshd 來啟動的,所以,手動可以這樣啟動:
```
[root@www ~]# /etc/init.d/sshd restart
[root@www ~]# netstat -tlnp | grep ssh
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 :::22 :::* LISTEN 1539/sshd
```
需要注意的是,SSH 不但提供了 shell 給我們使用,亦即是 ssh protocol 的主要目的,同時亦提供了一個較為安全的 FTP server ,亦即是 ssh-ftp server 給我們當成是 FTP 來使用!所以,這個 sshd 可以同時提供 shell 與 ftp 喔!而且都是架構在 port 22 上面的呢!所以,底下我們就來提一提,那么怎么樣由 Client 端連接上 Server 端呢?同時,如何以 FTP 的服務來連接上 Server 并且使用 FTP 的功能呢?
- - - - - -
### 11.2.3 ssh 客戶端聯機程序 - Linux 用戶
如果你的客戶端是 Linux 的話,那么恭喜你了,預設的情況下,你的系統已經有底下的所有指令,可以不必安裝額外的軟件喔! 底下就來介紹一下這些指令吧!
- ssh :直接登入遠程主機的指令
SSH 在 client 端使用的是 ssh 這個指令,這個指令可以指定聯機的版本 (version1, version2), 還可以指定非正規的 ssh port (正規 ssh port 為 22)。不過,一般的用法可以使用底下的方式:
```
[root@www ~]# ssh [-f] [-o 參數項目] [-p 非正規埠口] [賬號@]IP [指令]
選項與參數:
-f :需要配合后面的 [指令] ,不登入遠程主機直接發送一個指令過去而已;
-o 參數項目:主要的參數項目有:
ConnectTimeout=秒數 :聯機等待的秒數,減少等待的時間
StrictHostKeyChecking=[yes|no|ask]:預設是 ask,若要讓 public key
主動加入 known_hosts ,則可以設定為 no 即可。
-p :如果你的 sshd 服務啟動在非正規的埠口 (22),需使用此項目;
[指令] :不登入遠程主機,直接發送指令過去。但與 -f 意義不太相同。
# 1\. 直接聯機登入到對方主機的方法 (以登入本機為例):
[root@www ~]# ssh 127.0.0.1
The authenticity of host '127.0.0.1 (127.0.0.1)' can't be established.
RSA key fingerprint is eb:12:07:84:b9:3b:3f:e4:ad:ba:f1:85:41:fc:18:3b.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '127.0.0.1' (RSA) to the list of known hosts.
root@127.0.0.1's password: <==在這里輸入 root 的密碼即可!
Last login: Mon Jul 25 11:36:06 2011 from 192.168.1.101
[root@www ~]# exit <==離開這次的 ssh 聯機
# 由于 ssh 后面沒有加上賬號,因此預設使用當前的賬號來登入遠程服務器
```
一般使用 ssh 登入遠程主機,都會填寫『 ssh 賬號@主機IP 』的格式, 意思是說,使用該主機的某賬號登入的意思。但是很多朋友都不喜歡寫賬號,亦即使用『 ssh 主機IP 』的格式。 如同上面的范例情況。要注意喔,如果不寫賬號的話,那么會以本地端計算機的賬號來嘗試登入遠程。 也就是說,如果近端與遠程具有相同的賬號,那么不寫賬號也沒有關系,如上表中的范例。但是,為了以后習慣著想, 還是一開始就使用類似 email 的方式來登入遠程主機,這樣的行為習慣比較好啦!
上面出現的訊息中,開頭 RSA 的那行后面接的就是遠程服務器的公鑰指紋碼,如果確定該指紋碼沒有問題,那么你就得要輸入 yes 來將該指紋碼寫入服務器公鑰記錄文件 (~/.ssh/known\_hosts),以方便未來比對該服務器的正確性之用。 注意是要寫 yes 喔,單純輸入 Y 或 y 是不會被接受的~此外, 由于該主機的公鑰已經被記錄,因此未來重復使用 ssh 登入此主機時,就不會出現這個指紋碼提示了。
```
# 2\. 使用 student 賬號登入本機
[root@www ~]# ssh student@127.0.0.1
student@127.0.0.1's password:
[student@www ~]$ exit
# 由于加入賬號,因此切換身份成為 student 了!另外,因為 127.0.0.1 曾登入過,
# 所以就不會再出現提示你要增加主機公鑰的訊息啰!
# 3\. 登入對方主機執行過指令后立刻離開的方式:
[root@www ~]# ssh student@127.0.0.1 find / &> ~/find1.log
student@localhost's password:
# 此時你會發現怎么畫面卡住了?這是因為上頭的指令會造成,你已經登入遠程主機,
# 但是執行的指令尚未跑完,因此你會在等待當中。那如何指定系統自己跑?
# 4\. 與上題相同,但是讓對方主機自己跑該指令,你立刻回到近端主機繼續工作:
[root@www ~]# ssh -f student@127.0.0.1 find / &> ~/find1.log
# 此時你會立刻注銷 127.0.0.1 ,但 find 指令會自己在遠程服務器跑喔!
```
上述的范例當中,第 4 個范例最有用!如果你想要讓遠程主機進行關機的指令,如果不加上 -f 的參數, 那你會等待對方主機關機完畢再將你踢出聯機,這比較不合理。因此,加上 -f 就很重要~因為你會指定遠程主機自己跑關機, 而不需要在空空等待。例如:『ssh -f root@some\_IP shutdown -h now 』之類的指令啰。
```
# 5\. 刪除掉 known_hosts 后,重新使用 root 聯機到本機,且自動加上公鑰記錄
[root@www ~]# rm ~/.ssh/known_hosts
[root@www ~]# ssh -o StrictHostKeyChecking=no root@localhost
Warning: Permanently added 'localhost' (RSA) to the list of known hosts.
root@localhost's password:
# 如上所示,不會問你 yes 或 no 啦!直接會寫入 ~/.ssh/known_hosts 當中!
```
鳥哥上課常常使用 ssh 聯機到同學的計算機去看他有沒有出錯,有時候會寫 script 來進行答案偵測。 此時如果每臺計算機都在主動加上公鑰文件記錄,都得要輸入『 yes 』,會累死!那么加上這個 StrictHostKeyChecking=no 就很有幫助啦!他會不詢問自動加入主機的公鑰到檔案中,對于一般使用者幫助不大,對于程序腳本來說, 這玩意兒可就很不錯用了!
- 服務器公鑰記錄文件: ~/.ssh/known\_hosts
當你登入遠程服務器時,本機會主動的用接收到的服務器的 public key 去比對 ~/.ssh/known\_hosts 有無相關的公鑰, 然后進行底下的動作:
- 若接收的公鑰尚未記錄,則詢問用戶是否記錄。若要記錄 (范例中回答 yes 的那個步驟) 則寫入 ~/.ssh/known\_hosts 且繼續登入的后續工作;若不記錄 (回答 no) 則不寫入該檔案,并且離開登入工作;
- 若接收到的公鑰已有記錄,則比對記錄是否相同,若相同則繼續登入動作;若不相同,則出現警告信息, 且離開登入的動作。這是客戶端的自我保護功能,避免你的服務器是被別人偽裝的。
雖然說服務器的 ssh 通常可能會改變,問題是,如果是測試用的主機,因此常常在重新安裝,那么服務器的公鑰肯定經常不同, 果真如此的話,你就無法繼續登入了!那怎辦?讓我們來模擬一下這個行為吧!讓你比較有印象啦!
例題:仿真伺服器重新安裝后,假設服務器使用相同的 IP ,造成相同 IP 的服務器公鑰不同,產生的問題與解決之道為何?答:利用前一小節講過的方式,刪除原有的系統公鑰,重新啟動 ssh 讓你的公鑰更新:
```
rm /etc/ssh/ssh_host*
/etc/init.d/sshd restart
```
然后重新使用底下的方式來進行聯機的動作:
```
[root@www ~]# ssh root@localhost
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @ <==就告訴你可能有問題
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that the RSA host key has just been changed.
The fingerprint for the RSA key sent by the remote host is
a7:2e:58:51:9f:1b:02:64:56:ea:cb:9c:92:5e:79:f9.
Please contact your system administrator.
Add correct host key in /root/.ssh/known_hosts to get rid of this message.
Offending key in /root/.ssh/known_hosts:1 <==冒號后面接的數字就是有問題數據行號
RSA host key for localhost has changed and you have requested strict checking.
Host key verification failed.
```
上述的表格出現的錯誤訊息中,特殊字體的地方在告訴你:/root/.ssh/known\_hosts 的第 1 行,里面的公鑰與這次接收到的結果不同, 很可能被攻擊了!那怎辦?沒關系啦!請你使用 vim 到 /root/.ssh/known*hosts ,并將第 1 行(冒號 : 后面接的數字就是了) 刪除,之后再重新 ssh 過,那系統又會重新問你要不要加上公鑰啰!就這么簡單! ^*^
- 模擬 FTP 的文件傳輸方式: sftp
ssh 是登入遠程服務器進行工作,那如果你只是想要從遠程服務器下載或上傳檔案呢? 那就不是使用 ssh 啦,而必須要使用 sftp 或 scp。這兩個指令也都是使用 ssh 的通道 (port 22),只是模擬成 FTP 與復制的動作而已。我們先談談 sftp ,這個指令的用法與 ssh 很相似,只是 ssh 是用在登入而 sftp 在上傳/下載文件而已。
```
[root@www ~]# sftp student@localhost
Connecting to localhost...
student@localhost's password: <== 這里請輸入密碼啊!
sftp> exit <== 這里就是在等待你輸入 ftp 相關指令的地方了!
```
進入到 sftp 之后,那就跟在一般 FTP 模式下的操作方法沒有兩樣了!底下我們就來談一談, sftp 這個接口下的使用指令吧!
針對遠方服務器主機 (Server) 之行為變換目錄到 /etc/test 或其他目錄 cd /etc/test cd PATH列出目前所在目錄下的文件名 ls dir建立目錄 mkdir directory刪除目錄 rmdir directory顯示目前所在的目錄 pwd更改檔案或目錄群組 chgrp groupname PATH更改檔案或目錄擁有者 chown username PATH更改檔案或目錄的權限 chmod 644 PATH 其中,644 與權限有關!回去看基礎篇!建立連結檔 ln oldname newname刪除檔案或目錄 rm PATH更改檔案或目錄名稱 rename oldname newname離開遠程主機 exit (or) bye (or) quit針對本機 (Client) 之行為(都加上 l, L 的小寫 )變換目錄到本機的 PATH 當中 lcd PATH列出目前本機所在目錄下的文件名 lls在本機建立目錄 lmkdir顯示目前所在的本機目錄 lpwd針對資料上傳/下載的行為將檔案由本機上傳到遠程主機 put \[本機目錄或檔案\] \[遠程\] put \[本機目錄或檔案\] 如果是這種格式,則檔案會放置到目前遠程主機的目錄下!將檔案由遠程主機下載回來 get \[遠程主機目錄或檔案\] \[本機\] get \[遠程主機目錄或檔案\] 若是這種格式,則檔案會放置在目前本機所在的目錄當中!可以使用通配符,例如: get \* get \*.rpm 亦是可以的格式!就整體而言, sftp 在 Linux 底下,如果不考慮圖形接口,那么他已經可以取代 FTP 了呢!因為所有的功能都已經涵蓋啦!因此,在不考慮到圖形接口的 FTP 軟件時,可以直接關掉 FTP 的服務,而改以 sftp-server 來提供 FTP 的服務吧! ^\_^
例題:假設 localhost 為遠程服務器,且服務器上有 student 這個使用者。你想要 (1)將本機的 /etc/hosts 上傳到 student 家目錄,并 (2)將 student 的 .bashrc 復制到本機的 /tmp 底下,該如何透過 sftp 達成?答:
```
[root@www ~]# sftp student@localhost
sftp> lls /etc/hosts <==先看看本機有沒有這個檔案
/etc/hosts
sftp> put /etc/hosts <==有的話,那就上傳吧!
Uploading /etc/hosts to /home/student/hosts
/etc/hosts 100% 243 0.2KB/s 00:00
sftp> ls <==有沒有上傳成功?看遠程目錄下的文件名
hosts
sftp> ls -a <==那有沒有隱藏檔呢?
. .. .bash_history .bash_logout
.bash_profile .bashrc .mozilla hosts
sftt> lcd /tmp <==切換本機目錄到 /tmp
sftp> lpwd <==只是進行確認而已!
Local working directory: /tmp
sftp> get .bashrc <==沒問題就下載吧!
Fetching /home/student/.bashrc to .bashrc
/home/student/.bashrc 100% 124 0.1KB/s 00:00
sftp> lls -a <==看本地端檔案檔名
. .font-unix keyring-rNd7qX .X11-unix
.. .gdm_socket lost+found scim-panel-socket:0-root
.bashrc .ICE-unix mapping-root .X0-lock
sftp> exit <==離開吧!
```
如果你不喜歡使用文字接口進行 FTP 的傳輸,那么還可以透過圖形接口來連接到 sftp-server 哩! 你可以利用二十一章 FTP 服務器提到的 [Filezilla](http://linux.vbird.org/linux_server/0410vsftpd.php#client) 來進行聯機的啦! 如此一來,與服務器之間的文件傳輸就方便多了吧!
- 檔案異地直接復制: scp
通常使用 sftp 是因為可能不知道服務器上面有什么檔名的檔案存在,如果已經知道服務器上的檔案檔名了, 那么最簡單的文件傳輸則是透過 scp 這個指令喔!最簡單的 scp 用法如下:
```
[root@www ~]# scp [-pr] [-l 速率] file [賬號@]主機:目錄名 <==上傳
[root@www ~]# scp [-pr] [-l 速率] [賬號@]主機:file 目錄名 <==下載
選項與參數:
-p :保留原本檔案的權限數據;
-r :復制來源為目錄時,可以復制整個目錄 (含子目錄)
-l :可以限制傳輸的速度,單位為 Kbits/s ,例如 [-l 800] 代表傳輸速限 100Kbytes/s
# 1\. 將本機的 /etc/hosts* 全部復制到 127.0.0.1 上面的 student 家目錄內
[root@www ~]# scp /etc/hosts* student@127.0.0.1:~
student@127.0.0.1's password: <==輸入 student 密碼
hosts 100% 207 0.2KB/s 00:00
hosts.allow 100% 161 0.2KB/s 00:00
hosts.deny 100% 347 0.3KB/s 00:00
# 文件名顯示 進度 容量(bytes) 傳輸速度 剩余時間
# 你可以仔細看,出現的訊息有五個字段,意義如上所示。
# 2\. 將 127.0.0.1 這部遠程主機的 /etc/bashrc 復制到本機的 /tmp 底下
[root@www ~]# scp student@127.0.0.1:/etc/bashrc /tmp
```
其實上傳或下載的重點是那個冒號 (:) 啰!連接在冒號后面的就是遠程主機的檔案。 因此,如果冒號在前,代表的就是從遠程主機下載下來,如果冒號在后,則代表本機數據上傳啦! 而如果想要復制目錄的話,那么可以加上 -r 的選項!
例題:假設本機有個檔案檔名為 /root/dd\_10mb\_file ,這個檔案有 10 MB 這么大。假設你想要上傳到 127.0.0.1 的 /tmp 底下去, 而且你在 127.0.0.1 上面有 root 這個賬號的使用權。但由于帶寬很寶貴,因此你只想要花費 100Kbyes/s 的傳輸量給此一動作, 那該如何下達指令?答:由于預設不存在這個檔案,因此我們得先使用 dd 來建立一個大檔案:
```
dd if=/dev/zero of=/root/dd_10mb_file bs=1M count=10
```
建立妥當之后,由于是上傳數據,觀察 -l 的選項中,那個速率用的是 bit ,轉成容量的 bytes 需要乘上 8 倍,因此指令就要這樣下達:
```
scp -l 800 /root/dd_10mb_file root@127.0.0.1:/tmp
```
- - - - - -
### 11.2.4 ssh 客戶端聯機程序 - Windows 用戶
與 Linux 不同的是,預設的 Windows 并沒有 ssh 的客戶端程序,因此所有的程序都得要下載其他第三方軟件才行。 常見的軟件主要有 pietty, psftp 及 filezilla 等。底下就讓我們來談談這幾個軟件吧。
- 直接聯機的 pietty
在 Linux 底下想要連接 SSH 服務器,可以直接利用 [ssh](#ssh) 這個指令,在 Windows 操作系統底下就得要使用 pietty 或 putty 這兩個玩意兒,這兩者的下載點請參考 ([注2](#ps2)):
- putty 官方網站:[http://www.chiark.greenend.org.uk/~sgtatham/putty/](http://www.chiark.greenend.org.uk/%7Esgtatham/putty/)
- pietty 官方網站:[http://www.csie.ntu.edu.tw/~piaip/pietty/](http://www.csie.ntu.edu.tw/%7Epiaip/pietty/)
在 putty 的官方網站上有很多的軟件可以使用的,包括 putty/pscp/psftp 等等。他們分別對應了 ssh/scp/sftp 這三個指令就是了。而鳥哥愛用的 pietty 則是臺灣的林弘德先生根據 putty 所改版而成的。由于 pietty 除了完整的兼容于 putty 之外,還提供了選單與較為完整的文字編碼,實在很好用呢,所以底下鳥哥就以 pietty 來作為介紹啰。在你下載 pietty 完成后,雙擊該檔案,就會出現如下的畫面啰:

圖 11.2-3、pietty 的啟動屏幕示意圖
在上圖中箭頭為 1 的地方請填寫相關的主機名或者是 IP ,箭頭 2 當然務必選擇 SSH 那一項,至于箭頭 3 的地方,鳥哥比較喜歡選單出現的樣式,因為可以直接修改一些 pietty 的環境設定值,所以鳥哥是選擇選單啦! 若沒有問題,按下『聯機』后,就會出現如下等待登入與輸入賬/密數據的畫面:

圖 11.2-4、pietty 的登入與使用畫面示意圖
這個圖標會讓你以為是在主機前面工作吧!而且上頭還有選單可以隨時調整類似字形、字體、字符編碼等等的重要環境參數。 尤其是字符編碼的問題,有時候你會發現開啟檔案時,竟然畫面當中會有亂碼而不是正常的中文顯示, 那就是編碼的問題。要解決這個問題時,你必須要牢記下面的三個跟語系編碼有關的數據要相同才行:
- 文本文件本身在存檔時所挑選的語系;
- Linux 程序 (如 bash 軟件) 本身所使用的語系 (可用 LANG 變量調整);
- pietty 所使用的語系。
我們知道 Linux 本身的編碼可以透過 LANG 這個變量來調整,那該如何調整 pietty 的中文編碼呢?你可以透過圖 11.2-4 選單列當中的『選項』來處理,如下所示:

圖 11.2-5、調整 pietty 的語系編碼方式 (與中文較相關)
在『選項』的『字符編碼』里面可以挑選 big5 (cp950) 或者是 unicode (utf8) 的中文編碼,讓它符合你的 Linux 與檔案所儲存的數據格式,那中文字就 OK 的啦! ^\_^!如果想要作更細部的設定時,可以選擇圖 11.2-5 上頭最底下的那個『詳細設定』項目, 就會出現如下圖示。其中更為重要的是『鍵盤右側的數字鍵想要生效』時, 可以按照下圖的指示來啟動數字鍵的功能:

圖 11.2-6、pietty 軟件環境詳細設定,與鍵盤右側數字鍵相關者
將上圖中箭頭 2 所指的那個項目勾選起來且按下『Apply』之后,你鍵盤右側的數字鍵才能夠正常的使用呢,否則按右側數字鍵會是亂碼啦。 再來,你可以調整 pietty 滾動條的記憶行數,這樣當數據太多時,你依舊可以調整滾動條來查閱之前的數據。設定的方法如下:

圖 11.2-7、調整畫面可以記憶的行數,可讓用戶回去看較多之前的畫面
調整完這些常用的數據后,再來這是最重要的:『你要以哪一個版本的 SSH 算法登入?』前面說過,我們預設是以 version2 來登入的,所以這里我們可以調整為 2 那個項目!這樣每次登入都會以 version 2 的模式登入主機了!

圖 11.2-8、設定登入服務器時使用的 ssh 算法版本
整個 pietty 的使用與相關設定流程就是這樣!如此一來,你就可以在 Windows 上面以 SSH 的協議,登入遠程的 Linux 主機嚕!粉方便吧! ^\_^ !如果想要中文支持的話,目前 pietty 已經支持中文啦!你可以輸入中文喔!不過需要修改一下字符集, 選擇[圖 11.2-5](#fig11.2-5) 『選項』內的『字型』就會出現如下圖示:

圖 11.2-9、選擇中文的字形與編碼
將(1)字型設定為細明體、(2)字集設定為『Big5』,如此一來,你的 pietty 就支持中文的輸入啰!
那么上面我們作的這些設定值都記錄在哪里啊?呵呵!都記錄在 Windows 的登錄文件當中啊!你可以在 Windows 的系統當中,在『開始』-->『執行』后,出現的框框內輸入『regedit』, 之后會出現一個大窗口。請在左邊的畫面當中選擇『 HKEY\_CURRENT*USER --> Software --> SimonTatham --> PuTTY --> Sessions』, 就可以看到你的設定值啰! ^*^! 這樣,也就可以儲存你的設定值啰~
- 使用 sftp-server 的功能: psftp
在 putty 的官方網站上也提供 psftp 這支程序。這一支程序的重點則在使用 sftp-server。使用的方式可以直接點選 psftp 這個檔案,讓他直接啟動,則會出現下面的圖樣:
```
psftp: no hostname specified; use "open host.name" to connect
psftp>
```
這個時候可以填入你要連接上去的主機名,例如我的區域內網絡 192.168.100.254 這部主機:
```
psftp: no hostname specified; use "open host.name" to connect
psftp> open 192.168.100.254
login as: root
root@192.168.100.254's password:
Remote working directory is /root
psftp> <== 這里就在等待你輸入 FTP 的指令了!
```
呵呵!這樣就登入主機啦!很簡單吧!然后其他的使用方式跟前面提到的 [sftp](#sftp) 一樣哩!加油的使用吧!
- 圖形化接口的 sftp 客戶端軟件: Filezilla
SSH 所提供的 sftp 功能只能利用純文本接口的 psftp 來聯機嗎?有沒有圖形接口的軟件呢?呵呵!當然有! 那就是非常有用的 Filezilla 啰!Filezilla 是圖形接口的一個 FTP 客戶端軟件,使用上非常的方便, 至于詳細的安裝與使用流程請參考第二十一章 [vsftpd](http://linux.vbird.org/linux_server/0410vsftpd.php#client) 的說明喔!
- - - - - -
### 11.2.5 sshd 服務器細部設定
基本上,所有的 sshd 服務器詳細設定都放在 /etc/ssh/sshd\_config 里面!不過,每個 Linux distribution 的預設設定都不太相同,所以我們有必要來了解一下整個設定值的意義為何才好! 同時請注意,在預設的檔案內,只要是預設有出現且被批注的設定值 (設定值前面加 #),即為『默認值!』,你可以依據它來修改的哩。
```
[root@www ~]# vim /etc/ssh/sshd_config
# 1\. 關于 SSH Server 的整體設定,包含使用的 port 啦,以及使用的密碼演算方式
# Port 22
# SSH 預設使用 22 這個port,也可以使用多個port,即重復使用 port 這個設定項目!
# 例如想要開放 sshd 在 22 與 443 ,則多加一行內容為:『 Port 443 』
# 然后重新啟動 sshd 這樣就好了!不過,不建議修改 port number 啦!
Protocol 2
# 選擇的 SSH 協議版本,可以是 1 也可以是 2 ,CentOS 5.x 預設是僅支援 V2。
# 如果想要支持舊版 V1 ,就得要使用『 Protocol 2,1 』才行。
# ListenAddress 0.0.0.0
# 監聽的主機適配器!舉個例子來說,如果你有兩個 IP,分別是 192.168.1.100 及
# 192.168.100.254,假設你只想要讓 192.168.1.100 可以監聽 sshd ,那就這樣寫:
# 『 ListenAddress 192.168.1.100 』默認值是監聽所有接口的 SSH 要求
# PidFile /var/run/sshd.pid
# 可以放置 SSHD 這個 PID 的檔案!上述為默認值
# LoginGraceTime 2m
# 當使用者連上 SSH server 之后,會出現輸入密碼的畫面,在該畫面中,
# 在多久時間內沒有成功連上 SSH server 就強迫斷線!若無單位則默認時間為秒!
# Compression delayed
# 指定何時開始使用壓縮數據模式進行傳輸。有 yes, no 與登入后才將數據壓縮 (delayed)
# 2\. 說明主機的 Private Key 放置的檔案,預設使用下面的檔案即可!
# HostKey /etc/ssh/ssh_host_key # SSH version 1 使用的私鑰
# HostKey /etc/ssh/ssh_host_rsa_key # SSH version 2 使用的 RSA 私鑰
# HostKey /etc/ssh/ssh_host_dsa_key # SSH version 2 使用的 DSA 私鑰
# 還記得我們在主機的 SSH 聯機流程里面談到的,這里就是 Host Key ~
# 3\. 關于登錄文件的訊息數據放置與 daemon 的名稱!
SyslogFacility AUTHPRIV
# 當有人使用 SSH 登入系統的時候,SSH 會記錄信息,這個信息要記錄在什么 daemon name
# 底下?預設是以 AUTH 來設定的,即是 /var/log/secure 里面!什么?忘記了!
# 回到 [Linux 基礎](http://linux.vbird.org/linux_basic/)去翻一下。其他可用的 daemon name 為:DAEMON,USER,AUTH,
# LOCAL0,LOCAL1,LOCAL2,LOCAL3,LOCAL4,LOCAL5,
# LogLevel INFO
# 登錄記錄的等級!嘿嘿!任何訊息!同樣的,忘記了就回去參考!
# 4\. 安全設定項目!極重要!
# 4.1 登入設定部分
# PermitRootLogin yes
# 是否允許 root 登入!預設是允許的,但是建議設定成 no!
# StrictModes yes
# 是否讓 sshd 去檢查用戶家目錄或相關檔案的權限數據,
# 這是為了擔心使用者將某些重要檔案的權限設錯,可能會導致一些問題所致。
# 例如使用者的 ~.ssh/ 權限設錯時,某些特殊情況下會不許用戶登入
# PubkeyAuthentication yes
# AuthorizedKeysFile .ssh/authorized_keys
# 是否允許用戶自行使用成對的密鑰系統進行登入行為,僅針對 version 2。
# 至于自制的公鑰數據就放置于用戶家目錄下的 .ssh/authorized_keys 內
PasswordAuthentication yes
# 密碼驗證當然是需要的!所以這里寫 yes 啰!
# PermitEmptyPasswords no
# 若上面那一項如果設定為 yes 的話,這一項就最好設定為 no ,
# 這個項目在是否允許以空的密碼登入!當然不許!
# 4.2 認證部分
# RhostsAuthentication no
# 本機系統不使用 .rhosts,因為僅使用 .rhosts太不安全了,所以這里一定要設定為 no
# IgnoreRhosts yes
# 是否取消使用 ~/.ssh/.rhosts 來做為認證!當然是!
# RhostsRSAAuthentication no #
# 這個選項是專門給 version 1 用的,使用 rhosts 檔案在 /etc/hosts.equiv
# 配合 RSA 演算方式來進行認證!不要使用啊!
# HostbasedAuthentication no
# 這個項目與上面的項目類似,不過是給 version 2 使用的!
# IgnoreUserKnownHosts no
# 是否忽略家目錄內的 ~/.ssh/known_hosts 這個檔案所記錄的主機內容?
# 當然不要忽略,所以這里就是 no 啦!
ChallengeResponseAuthentication no
# 允許任何的密碼認證!所以,任何 login.conf 規定的認證方式,均可適用!
# 但目前我們比較喜歡使用 PAM 模塊幫忙管理認證,因此這個選項可以設定為 no 喔!
UsePAM yes
# 利用 PAM 管理使用者認證有很多好處,可以記錄與管理。
# 所以這里我們建議你使用 UsePAM 且 ChallengeResponseAuthentication 設定為 no
# 4.3 與 Kerberos 有關的參數設定!因為我們沒有 Kerberos 主機,所以底下不用設定!
# KerberosAuthentication no
# KerberosOrLocalPasswd yes
# KerberosTicketCleanup yes
# KerberosTgtPassing no
# 4.4 底下是有關在 X-Window 底下使用的相關設定!
X11Forwarding yes
# X11DisplayOffset 10
# X11UseLocalhost yes
# 比較重要的是 X11Forwarding 項目,他可以讓窗口的數據透過 ssh 信道來傳送喔!
# 在本章后面比較進階的 ssh 使用方法中會談到。
# 4.5 登入后的項目:
# PrintMotd yes
# 登入后是否顯示出一些信息呢?例如上次登入的時間、地點等等,預設是 yes
# 亦即是打印出 /etc/motd 這個檔案的內容。但是,如果為了安全,可以考慮改為 no !
# PrintLastLog yes
# 顯示上次登入的信息!可以啊!預設也是 yes !
# TCPKeepAlive yes
# 當達成聯機后,服務器會一直傳送 TCP 封包給客戶端藉以判斷對方式否一直存在聯機。
# 不過,如果聯機時中間的路由器暫時停止服務幾秒鐘,也會讓聯機中斷喔!
# 在這個情況下,任何一端死掉后,SSH可以立刻知道!而不會有僵尸程序的發生!
# 但如果你的網絡或路由器常常不穩定,那么可以設定為 no 的啦!
UsePrivilegeSeparation yes
# 是否權限較低的程序來提供用戶操作。我們知道 sshd 啟動在 port 22 ,
# 因此啟動的程序是屬于 root 的身份。那么當 student 登入后,這個設定值
# 會讓 sshd 產生一個屬于 sutdent 的 sshd 程序來使用,對系統較安全
MaxStartups 10
# 同時允許幾個尚未登入的聯機畫面?當我們連上 SSH ,但是尚未輸入密碼時,
# 這個時候就是我們所謂的聯機畫面啦!在這個聯機畫面中,為了保護主機,
# 所以需要設定最大值,預設最多十個聯機畫面,而已經建立聯機的不計算在這十個當中
# 4.6 關于用戶抵擋的設定項目:
DenyUsers *
# 設定受抵擋的使用者名稱,如果是全部的使用者,那就是全部擋吧!
# 若是部分使用者,可以將該賬號填入!例如下列!
DenyUsers test
DenyGroups test
# 與 DenyUsers 相同!僅抵擋幾個群組而已!
# 5\. 關于 SFTP 服務與其他的設定項目!
Subsystem sftp /usr/lib/ssh/sftp-server
# UseDNS yes
# 一般來說,為了要判斷客戶端來源是正常合法的,因此會使用 DNS 去反查客戶端的主機名
# 不過如果是在內網互連,這項目設定為 no 會讓聯機達成速度比較快。
```
基本上,CentOS 預設的 sshd 服務已經算是挺安全的了,不過還不夠!建議你 (1)將 root 的登入權限取消; (2)將 ssh 版本設定為 2 。其他的設定值就請你依照自己的喜好來設定了。 通常不建議進行隨便修改啦!另外,如果你修改過上面這個檔案(/etc/ssh/sshd\_config),那么就必需要重新啟動一次 sshd 這個 daemon 才行!亦即是:
- /etc/init.d/sshd restart
- - \*
### 11.2.6 制作不用密碼可立即登入的 ssh 用戶
你或許已經想到了,既然 ssh 可以使用 scp 來進行網絡復制的話,那么我能不能將 scp 的指令放置于 crontab 服務中, 讓我們的系統透過 scp 直接在背景底下自行定期的進行網絡復制與備份呢?抱歉,答案是:『預設狀況下不允許此動作』的! 為甚么呢?因為預設狀況下,你必須要透過遠程登錄,與 scp 互動的輸入密碼才行啊!但 crontab 又不會讓你有終端接口輸入密碼, 所以該程序就會一直卡住而無法在 crontab 內執行成功喔! 那怎辦?我們要放棄這個好用的網絡復制工具嗎?當然不是啦!我們可以透過密鑰認證系統來處理的!
既然 SSH 可以使用密鑰系統來比對數據,并且提供用戶數據的加密功能,那么可不可能利用這個 Key 就提供用戶自己進入主機,而不需要輸入密碼呢?呵呵!好主意!我們可以將 Client 產生的 Key 給他拷貝到 Server 當中,所以, 以后 Client 登入 Server 時,由于兩者在 SSH 要聯機的訊號傳遞中,就已經比對過 Key 了, 因此,可以立即進入數據傳輸接口中,而不需要再輸入密碼呢!在實作上的步驟可以是:
1. 客戶端建立兩把鑰匙:想一想,在密鑰系統中,是公鑰比較重要還是私鑰比較重要? 當然是私鑰比較重要!因此私鑰才是解密的關鍵啊!所以啰,這兩把鑰匙當然得在發起聯機的客戶端建置才對。利用的指令為 ssh-keygen 這個命令;
2. 客戶端放置好私鑰檔案:將 Private Key 放在 Client 上面的家目錄,亦即 $HOME/.ssh/ , 并且得要注意權限喔!
3. 將公鑰放置服務器端的正確目錄與文件名去:最后,將那把 Public Key 放在任何一個你想要用來登入的服務器端的某 User 的家目錄內之 .ssh/ 里面的認證檔案即可完成整個程序。
說是好像很困難的樣子,其實步驟真的很簡單,我們依序來進行作業好了!假設前提如下,該進行的步驟則如下圖:
- Server 部分為 www.centos.vbird 這部 192.168.100.254 的主機,欲使用的賬號為 dmtsai ;
- Client 部分為 clientlinux.centos.vbird 這部 192.168.100.10 的 vbirdtsai 這個賬號, 該賬號要用來登入 192.168.100.254 這部主機的 dmtsai 賬號。

圖 11.2-10、制作不需要密碼的 ssh 賬號基本流程
- 1. 客戶端建立兩把鑰匙:
建立的方法很簡單,在 clientlinux.centos.vbird 這部主機上面以 vbirdtsai 的身份來建立兩把鑰匙即可。 不過,需要注意的是,我們有多種密碼算法,如果不指定特殊的算法,則默認以 RSA 算法來處理:
```
[vbirdtsai@clientlinux ~]$ ssh-keygen [-t rsa|dsa] <==可選 rsa 或 dsa
[vbirdtsai@clientlinux ~]$ ssh-keygen <==用預設的方法建立密鑰
Generating public/private rsa key pair.
Enter file in which to save the key (/home/vbirdtsai/.ssh/id_rsa): <==按 enter
Created directory '/home/vbirdtsai/.ssh'. <==此目錄若不存在則會主動建立
Enter passphrase (empty for no passphrase): <==按 Enter 不給密碼
Enter same passphrase again: <==再輸入一次 Enter 吧!
Your identification has been saved in /home/vbirdtsai/.ssh/id_rsa. <==私鑰檔
Your public key has been saved in /home/vbirdtsai/.ssh/id_rsa.pub. <==公鑰檔
The key fingerprint is:
0f:d3:e7:1a:1c:bd:5c:03:f1:19:f1:22:df:9b:cc:08 vbirdtsai@clientlinux.centos.vbird
[vbirdtsai@clientlinux ~]$ ls -ld ~/.ssh; ls -l ~/.ssh
drwx------. 2 vbirdtsai vbirdtsai 4096 2011-07-25 12:58 /home/vbirdtsai/.ssh
-rw-------. 1 vbirdtsai vbirdtsai 1675 2011-07-25 12:58 id_rsa <==私鑰檔
-rw-r--r--. 1 vbirdtsai vbirdtsai 416 2011-07-25 12:58 id_rsa.pub <==公鑰檔
```
請注意上面喔,我的身份是 vbirdtsai ,所以當我執行 ssh-keygen 時,才會在我的家目錄底下的 .ssh/ 這個目錄里面產生所需要的兩把 Keys ,分別是私鑰 (id\_rsa) 與公鑰 (id\_rsa.pub)。 ~/.ssh/ 目錄必須要是 700 的權限才行!另外一個要特別注意的就是那個 id\_rsa 的檔案權限啦!他必須要是 -rw------- 且屬于 vbirdtsai 自己才行!否則在未來密鑰比對的過程當中,可能會被判定為危險而無法成功的以公私鑰成對檔案的機制來達成聯機喔。 其實,建立私鑰后預設的權限與文件名放置位置都是正確的,你只要檢查過沒問題即可。
- 2. 將公鑰檔案數據上傳到服務器上:
因為我們要登入 www.centos.vbird 是以 dmtsai 的身份,因此我們就得要將上個步驟建立的公鑰 (id\_rsa.pub) 上傳到服務器上的 dmtsai 用戶才行。那如何上傳呢?最簡單的方法當然就是使用 scp 嘛!
```
[vbirdtsai@clientlinux ~]$ scp ~/.ssh/id_rsa.pub dmtsai@192.168.100.254:~
# 上傳到 dmtsai 的家目錄底下即可。
```
- 3. 將公鑰放置服務器端的正確目錄與文件名:
還記得 [sshd\_config](#sshd_config_auth) 里面談到的 AuthorizedKeysFile 這個設定值吧?該設定值就是在指定公鑰數據應該要放置的文件名啰!所以,我們必須要到服務器端的 dmtsai 這個用戶身份下, 將剛剛上傳的 id\_rsa.pub 數據附加到 authorized\_keys 這個檔案內才行。作法有點像這樣:
```
# 1\. 建立 ~/.ssh 檔案,注意權限需要為 700 喔!
[dmtsai@www ~]$ ls -ld .ssh
ls: .ssh: 沒有此一檔案或目錄
# 由于可能是新建的用戶,因此這個目錄不存在。不存在才作底下建立目錄的行為
[dmtsai@www ~]$ mkdir .ssh; chmod 700 .ssh
[dmtsai@www ~]$ ls -ld .ssh
drwx------. 2 dmtsai dmtsai 4096 Jul 25 13:06 .ssh
# 權限設定中,務必是 700 且屬于使用者本人的賬號與群組才行!
# 2\. 將公鑰檔案內的數據使用 cat 轉存到 authorized_keys 內
[dmtsai@www ~]$ ls -l *pub
-rw-r--r--. 1 dmtsai dmtsai 416 Jul 25 13:05 id_rsa.pub <==確實有存在
[dmtsai@www ~]$ cat id_rsa.pub >> .ssh/authorized_keys
[dmtsai@www ~]$ chmod 644 .ssh/authorized_keys
[dmtsai@www ~]$ ls -l .ssh
-rw-r--r--. 1 dmtsai dmtsai 416 Jul 25 13:07 authorized_keys
# 這個檔案的權限設定中,就得要是 644 才可以!不可以搞混了!
```
- - - - - -
這樣就搞定密鑰系統啰!以后你從 clientlinux.centos.vbird 的 vbirdtsai 登入到 www.centos.vbird 的 dmtsai 用戶時, 就不需要任何的密碼啰!舉例來說,你可以這樣測試看看啰:
例題:透過上述的案例練習成功后,請在 clientlinux 的 vbirdtsai 身份中,將系統的 /etc/hosts\* 檔案復制給 www.centos.vbird 的 dmtsai 用戶的家目錄。答:
```
[vbirdtsai@clientlinux ~]$ scp /etc/hosts* dmtsai@192.168.100.254:~
hosts 100% 187 0.2KB/s 00:00
hosts.allow 100% 161 0.2KB/s 00:00
hosts.deny 100% 347 0.3KB/s 00:00
# 你會發現,原本會出現的那個密碼提示數據不會出現了喔!
[vbirdtsai@clientlinux ~]$ ssh dmtsai@192.168.100.254 "ls -l"
-rw-r--r--. 1 dmtsai dmtsai 196 2011-07-25 13:09 hosts
-rw-r--r--. 1 dmtsai dmtsai 370 2011-07-25 13:09 hosts.allow
-rw-r--r--. 1 dmtsai dmtsai 460 2011-07-25 13:09 hosts.deny
-rw-r--r--. 1 dmtsai dmtsai 416 2011-07-25 13:05 id_rsa.pub
# 確實有復制到對方去了!有顯示出正確的遠程數據哩!
```
很簡單的步驟吧!這樣一來,使用 ssh 相關的客戶端指令就可以不需密碼的手續了!無論如何,在建立密鑰系統的步驟中你要記得的是:
- Client 必須制作出 Public & Private 這兩把 keys,且 Private 需放到 ~/.ssh/ 內;
- Server 必須要有 Public Key ,且放置到用戶家目錄下的 ~/.ssh/authorized\_keys,同時目錄的權限 (.ssh/) 必須是 700 而檔案權限則必須為 644 ,同時檔案的擁有者與群組都必須與該賬號吻合才行。
未來,當你還想要登入其他的主機時,只要將你的 public key (就是 id\_rsa.pub 這個檔案) 給他 copy 到其他主機上面去,并且新增到某賬號的 ~/.ssh/authorized\_keys 這個檔案中!哈哈!成功!
- - - - - -
### 11.2.7 簡易安全設定
老實說,大家都被『SSH 是個安全的服務』所欺騙了!其實 sshd 并不怎么安全的!翻開 openssh 的過去歷史來看,確實有很多人是利用 ssh 的程序漏洞來取得遠程主機 root 的權限,進一步黑掉對方的主機!所以這玩意兒說實話,也不是很安全的啦!
sshd 之所謂的『安全』其實指的是『 sshd 的數據是加密過的,所以他的數據在 Internet 上面傳遞時是比較安全的。至于 sshd 這個服務本身就不是那樣安全了!所以說:『非必要,不要將 sshd 對 Internet 開放可登入的權限,盡量局限在幾個小范圍內的 IP 或主機名即可!這很重要的喔!
好了,那么關于安全的設定方面,有沒有什么值得注意的呢?當然是有啦!我們可以先建議幾個項目吧!分別可以由底下這三方面來進行:
- 服務器軟件本身的設定強化:/etc/ssh/sshd\_config
- TCP wrapper 的使用:/etc/hosts.allow, /etc/hosts.deny
- iptables 的使用: iptables.rule, iptables.allow
- 服務器軟件本身的設定強化:/etc/ssh/sshd\_config
一般而言,這個檔案的默認項目就已經很完備了!所以,事實上是不太需要更動他的! 但是,如果你有些使用者方面的顧慮,那么可以這樣修正一些問題呢!
- 禁止 root 這個賬號使用 sshd 的服務;
- 禁止 nossh 這個群組的用戶使用 sshd 的服務;
- 禁止 testssh 這個用戶使用 sshd 的服務;
除了上述的賬號之外,其他的用戶則可以正常的使用系統。現在鳥哥假設你的系統里面已經有 sshnot1, sshnot2, sshnot3 加入 nossh 群組, 同時系統還有 testssh, student 等賬號。相關的賬號處理請自行參考基礎篇來設定,底下僅是列出觀察的重點:
```
# 1\. 先觀察一下所需要的賬號是否存在呢?
[root@www ~]# for user in sshnot1 sshnot2 sshnot3 testssh student; do \
> id $user | cut -d ' ' -f1-3 ; done
uid=507(sshnot1) gid=509(sshnot1) groups=509(sshnot1),508(nossh)
uid=508(sshnot2) gid=510(sshnot2) groups=510(sshnot2),508(nossh)
uid=509(sshnot3) gid=511(sshnot3) groups=511(sshnot3),508(nossh)
uid=511(testssh) gid=513(testssh) groups=513(testssh)
uid=505(student) gid=506(student) groups=506(student)
# 若上述賬號并不存在你的系統,請自己建置出來!UID/GID 與鳥哥的不同也沒關系!
# 2\. 修改 sshd_config 并且重新啟動 sshd 吧!
[root@www ~]# vim /etc/ssh/sshd_config
PermitRootLogin no <==約在第 39 行,請拿掉批注且修改成這樣
DenyGroups nossh <==底下這兩行可以加在檔案的最后面
DenyUsers testssh
[root@www ~]# /etc/init.d/sshd restart
# 3\. 測試與觀察相關的賬號登入情況吧!
[root@www ~]# ssh root@localhost <==并請輸入正確的密碼
[root@www ~]# tail /var/log/secure
Jul 25 13:14:05 www sshd[2039]: pam_unix(sshd:auth): authentication failure;
logname= uid=0 euid=0 tty=ssh ruser= rhost=localhost user=root
# 你會發現出現這個錯誤訊息,而不是密碼輸入錯誤而已。
[root@www ~]# ssh sshnot1@localhost <==并請輸入正確的密碼
[root@www ~]# tail /var/log/secure
Jul 25 13:15:53 www sshd[2061]: User sshnot1 from localhost not allowed because
a group is listed in DenyGroups
[root@www ~]# ssh testssh@localhost <==并請輸入正確的密碼
[root@www ~]# tail /var/log/secure
Jul 25 13:17:16 www sshd[2074]: User testssh from localhost not allowed
because listed in DenyUsers
```
從上面的結果來看,你就會發現到,不同的登入賬號會產生不一樣的登錄檔結果。因此,當你老是無法順利使用 ssh 登入某一部主機時,記得到該服務器上去檢查看看登錄檔,說不定就會順利的讓你解決問題啰!在我們的測試機上面,請還是放行 root 的登入喔!
- /etc/hosts.allow 及 /etc/hosts.deny
舉例來說,你的 sshd 只想讓本機以及區網內的主機來源能夠登入的話,那就這樣作:
```
[root@www ~]# vim /etc/hosts.allow
sshd: 127.0.0.1 192.168.1.0/255.255.255.0 192.168.100.0/255.255.255.0
[root@www ~]# vim /etc/hosts.deny
sshd : ALL
```
- iptables 封包過濾防火墻
多幾層保護也很好的!所以也可以使用 iptables 喔! 參考:第九章、防火墻與 NAT 服務器內的實際腳本程序,你應該在 iptables.rule 內將 port 22 的放行功能取消,然后再到 iptables.allow 里面新增這行:
```
[root@www ~]# vim /usr/local/virus/iptables/iptables.allow
iptables -A INPUT -i $EXTIF -s 192.168.1.0/24 -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -i $EXTIF -s 192.168.100.0/24 -p tcp --dport 22 -j ACCEPT
[root@www ~]# /usr/local/virus/iptables/iptables.rule
```
上述的方法處理完畢后,如果你還是一部測試機,那么記得要將設定值還原回來呦!最后, 『鳥哥呼吁大家,不要開放 SSH 的登入權限給所有 Internet 上面的主機~』 這很重要喔~因為如果對方可以 ssh 進入你的主機,那么...太危險了~
- - - - - -
- 鳥哥的Linux私房菜:服務器架設篇 第三版
- 第一部份:架站前的進修專區
- 作者序
- 第一章、架設服務器前的準備工作
- 1.1 前言: Linux 有啥功能
- 1.2 基本架設服務器流程
- 1.3 自我評估是否已經具有架站的能力
- 1.4 本章習題
- 第二章、基礎網絡概念
- 2.1 網絡是個什么玩意兒
- 2.2 TCP/IP 的鏈結層相關協議
- 2.3 TCP/IP 的網絡層相關封包與數據
- 2.4 TCP/IP 的傳輸層相關封包與數據
- 2.5 連上 Internet 前的準備事項
- 2.6 重點回顧:
- 2.7 本章習題
- 2.8 參考數據與延伸閱讀
- 第三章、局域網絡架構簡介
- 3.1 局域網絡的聯機
- 3.2 本書使用的內部聯機網絡參數與通訊協議
- 第四章、連上 Internet
- 4.1 Linux 連上 Internet 前的注意事項
- 4.2 連上 Internet 的設定方法
- 4.3 無線網絡--以筆記本電腦為例
- 4.4 常見問題說明
- 4.5 重點回顧
- 4.6 本章習題
- 4.7 參考數據與延伸閱讀
- 第五章、 Linux 常用網絡指令
- 5.1 網絡參數設定使用的指令
- 5.2 網絡偵錯與觀察指令
- 5.3 遠程聯機指令與實時通訊軟件
- 5.4 文字接口網頁瀏覽
- 5.5 封包擷取功能
- 5.6 重點回顧
- 5.7 本章習題
- 5.8 參考數據與延伸閱讀
- 第六章、 Linux 網絡偵錯
- 6.1 無法聯機原因分析
- 6.2 處理流程
- 6.3 本章習題
- 6.4 參考數據與延伸閱讀
- 第二部分:主機的簡易資安防護措施
- 第七章、網絡安全與主機基本防護:限制端口, 網絡升級與 SELinux
- 7.1 網絡封包聯機進入主機的流程
- 7.2 網絡自動升級軟件
- 7.3 限制聯機埠口 (port)
- 7.4 SELinux 管理原則
- 7.5 被攻擊后的主機修復工作
- 7.6 重點回顧
- 7.7 課后練習
- 7.8 參考數據與延伸閱讀
- 第八章、路由觀念與路由器設定
- 8.1 路由
- 8.2 路由器架設
- 8.3 動態路由器架設:quagga (zebra + ripd)
- 8.4 特殊狀況:路由器兩邊界面是同一個 IP 網段: ARP Proxy
- 8.5 重點回顧
- 8.6 本章習題
- 8.7 參考數據與延伸閱讀
- 第九章、防火墻與 NAT 服務器
- 9.1 認識防火墻
- 9.2 TCP Wrappers
- 9.3 Linux 的封包過濾軟件:iptables
- 9.4 單機防火墻的一個實例
- 9.5 NAT 服務器的設定
- 9.6 重點回顧
- 9.7 本章習題
- 9.8 參考數據與延伸閱讀
- 第十章、申請合法的主機名
- 10.1 為何需要主機名
- 10.2 注冊一個合法的主機名
- 10.3 重點回顧
- 10.4 本章習題
- 10.5 參考數據與延伸閱讀
- 第三部分:局域網絡內常見的服務器架設
- 第十一章、遠程聯機服務器SSH / XDMCP / VNC / RDP
- 11.1 遠程聯機服務器
- 11.2 文字接口聯機服務器: SSH 服務器
- 11.3 最原始圖形接口: Xdmcp 服務的啟用
- 11.4 華麗的圖形接口: VNC 服務器
- 11.5 仿真的遠程桌面系統: XRDP 服務器
- 11.6 SSH 服務器的進階應用
- 11.7 重點回顧
- 11.8 本章習題
- 11.9 參考數據與延伸閱讀
- 第十二章、網絡參數控管者: DHCP 服務器
- 12.1 DHCP 運作的原理
- 12.2 DHCP 服務器端的設定
- 12.3 DHCP 客戶端的設定
- 12.4 DHCP 服務器端進階觀察與使用
- 12.5 重點回顧
- 12.6 本章習題
- 12.7 參考數據與延伸閱讀
- 第十三章、文件服務器之一:NFS 服務器
- 13.1 NFS 的由來與其功能
- 13.2 NFS Server 端的設定
- 13.3 NFS 客戶端的設定
- 13.4 案例演練
- 13.5 重點回顧
- 13.6 本章習題
- 13.7 參考數據與延伸閱讀
- 第十四章、賬號控管: NIS 服務器
- 14.1 NIS 的由來與功能
- 14.2 NIS Server 端的設定
- 14.3 NIS Client 端的設定
- 14.4 NIS 搭配 NFS 的設定在叢集計算機上的應用
- 14.5 重點回顧
- 14.6 本章習題
- 14.7 參考數據與延伸閱讀
- 第十五章、時間服務器: NTP 服務器
- 15.1 關于時區與網絡校時的通訊協議
- 15.2 NTP 服務器的安裝與設定
- 15.3 客戶端的時間更新方式
- 15.4 重點回顧
- 15.5 本章習題
- 15.6 參考數據與延伸閱讀
- 第十六章、文件服務器之二: SAMBA 服務器
- 16.1 什么是 SAMBA
- 16.2 SAMBA 服務器的基礎設定
- 16.3 Samba 客戶端軟件功能
- 16.4 以 PDC 服務器提供賬號管理
- 16.5 服務器簡單維護與管理
- 16.6 重點回顧
- 16.7 本章習題
- 16.8 參考數據與延伸閱讀
- 第十七章、區網控制者: Proxy 服務器
- 17.1 什么是代理服務器 (Proxy)
- 17.2 Proxy 服務器的基礎設定
- 17.3 客戶端的使用與測試
- 17.4 服務器的其他應用設定
- 17.5 重點回顧
- 17.6 本章習題
- 17.7 參考數據與延伸閱讀
- 第十八章、網絡驅動器裝置: iSCSI 服務器
- 18.1 網絡文件系統還是網絡驅動器
- 18.2 iSCSI target 的設定
- 18.3 iSCSI initiator 的設定
- 18.4 重點回顧
- 18.5 本章習題
- 18.6 參考數據與延伸閱讀
- 第四部分:常見因特網服務器架設
- 第十九章、主機名控制者: DNS 服務器
- 19.1 什么是 DNS
- 19.2 Client 端的設定
- 19.3 DNS 服務器的軟件、種類與 cache only DNS 服務器設定
- 19.4 DNS 服務器的詳細設定
- 19.5 協同工作的 DNS: Slave DNS 及子域授權設定
- 19.6 DNS 服務器的進階設定
- 19.7 重點回顧
- 19.8 本章習題
- 19.9 參考數據與延伸閱讀
- 第二十章、WWW 伺服器
- 20.1 WWW 的簡史、資源以及伺服器軟體
- 20.2 WWW (LAMP) 伺服器基本設定
- 20.3 Apache 伺服器的進階設定
- 20.4 登錄檔分析以及 PHP 強化模組
- 20.5 建立連線加密網站 (https) 及防砍站腳本
- 20.6 重點回顧
- 20.7 本章習題
- 20.8 參考資料與延伸閱讀
- 第二十一章、文件服務器之三: FTP 服務器
- 21.1 FTP 的數據鏈路原理
- 21.2 vsftpd 服務器基礎設定
- 21.3 客戶端的圖形接口 FTP 聯機軟件
- 21.4 讓 vsftpd 增加 SSL 的加密功能
- 21.5 重點回顧
- 21.6 本章習題
- 21.7 參考數據與延伸閱讀
- 第二十二章、郵件服務器: Postfix
- 22.1 郵件服務器的功能與運作原理
- 22.2 MTA 服務器: Postfix 基礎設定
- 22.3 MRA 服務器: dovecot 設定
- 22.4 MUA 軟件:客戶端的收發信軟件
- 22.5 郵件服務器的進階設定
- 22.6 重點回顧
- 22.7 本章習題
- 22.8 參考數據與延伸閱讀