本文已不再維護,更新文章請參考這裡

維護網路伺服器最簡單的方式不是跑去實體伺服器前面登入,而是透過遠端連線伺服器連線功能來登入主機, 然後再來進行其他有的沒的維護就是了。 Linux 主機幾乎都會提供 sshd 這個連線服務,而且這個服務還是主動進行資料加密的! 訊息在網路上面跑安全多了。同時我們還能透過 rsync 這個指令以 sshd 通道來達成異地資料備援的功能哩!相當不賴。 如果想要利用圖形介面登入,那麼預設的 Xdmcp 配合 VNC 就能夠使用圖形介面在網路的另一端登入你的伺服器! 如果你習慣使用 Windows 的遠端桌面,那麼 XRDP 也不要放過囉!

11.1 遠端連線伺服器
  11.1.1 什麼是遠端連線伺服器
  11.1.2 有哪些可供登入的類型?
11.2 文字介面連線伺服器:SSH 伺服器
  11.2.1 連線加密技術簡介產生新的公鑰
  11.2.2 啟動 ssh 服務
  11.2.3 ssh 用戶端連線程式 - Linux 用戶ssh, ~/.ssh/known_hosts, sftp, scp
  11.2.4 ssh 用戶端連線程式 - Windows 用戶pietty, psftp, filezilla
  11.2.5 sshd 伺服器細部設定
  11.2.6 製作不用密碼可立即登入的 ssh 用戶ssh-keygen
  11.2.7 簡易安全設定
11.3 最原始圖形介面: Xdmcp 服務的啟用
  11.3.1 X Window 的 Server/Client 架構與各元件
  11.3.2 設定 gdm 的 XDMCP 服務
  11.3.3 用戶系統為 Linux 的登入方式Xnest
  11.3.4 用戶系統為 Windows 的登入方式: Xming
11.4 華麗的圖形介面: VNC 伺服器
  11.4.1 預設的 VNC 伺服器:使用 twm window managervncserver, vncpasswd
  11.4.2 VNC 的用戶端連線軟體vncviewer, realvnc
  11.4.3 VNC 搭配本機的 Xdmcp 畫面
  11.4.4 開機就啟動 VNC server 的方法
  11.4.5 同步的 VNC :可以透過圖示同步教學
11.5 模擬的遠端桌面系統: XRDP 伺服器
11.6 SSH 伺服器的進階應用
  11.6.1 啟動 ssh 在非正規埠口 (非 port 22)
  11.6.2 以 rsync 進行同步鏡相備份
  11.6.3 透過 ssh 通道加密原本無加密的服務
  11.6.4 以 ssh 通道配合 X server 傳遞圖形介面
11.7 重點回顧
11.8 課後練習
11.9 參考資料與延伸閱讀
11.10針對本文的建議:http://phorum.vbird.org/viewtopic.php?p=114550

11.1 遠端連線伺服器

遠端連線伺服器對我們來說,可是一項很有用的工具啊!他可以讓我們更方便的管理主機。 不過,方便歸方便,但開放全世界都可以嘗試登入你的主機並不個好主意,因為可能會有安全性的問題吶! 所以本章才要特別強調一下這個玩意兒啊!


11.1.1 什麼是遠端連線伺服器

首先,我們來瞭解一下,什麼是『遠端連線伺服器』? 這個東西的功能為何?我想,你應該已經聽過,一部開放到網際網路上的伺服器,基本上,它可以不需要螢幕、鍵盤、 滑鼠等等的周邊配備,只要有基本的主機板、CPU、RAM、硬碟再加上一塊好一點的網路卡,並且連上網際網路, 那這部主機就能夠提供你有需要的網路服務了。但如果你需要重新設定這部主機,該如何登入主機取得類似 bash 的介面來操縱與進行修改呢?那就得要透過連線伺服器的服務了。

是的!你猜對啦,遠端連線伺服器在提供你由遠端透過文字或圖形介面的方式來登入系統, 讓你在遠端的工作機前面登入 Linux 主機以取得可操控主機之介面 (shell),而登入後的操作感覺上就像坐在系統前面一樣! 所以啦,你當然不需要遠端網路伺服器的鍵盤、滑鼠、螢幕等等。你只要工作機可以正常連線到遠端主機即可啊。

以鳥哥個人為例,目前鳥哥管理將近十部左右的 Unix-Like 主機,這些主機都不放在同一個地方,分佈在南台灣各處! 那麼當有新的軟體的漏洞被發佈,或者是需要進行一些額外的設定的時候,是否鳥哥本人一定要到現場嗎?當然不需要, 只要透過網路連線到該主機上面,就可以進行任何工作了!真的就好像在主機前面工作一般的輕鬆愉快! ^_^!這就是遠端連線伺服器啦!

很多人會說,我用 FTP 也要輸入帳號密碼來登入啊?那個這個章節談到的登入有何不同?最大的不同在於取得的 shell 能進行的工作啦!用 ssh/telnet/VNC 等方式取得的文字或圖形 shell 能夠進行很多系統管理的任務,與單純的 FTP 能進行的工作當然不同!

當你的工作需要使用到 Linux 強大的程式語言編譯功能時,那麼你一定需要 Linux 對吧!而且最好是運算速度快一點的主機, 這個時候你可以將你研究室最快的那一部主機開放出來,設定一下遠端連線伺服器,讓你的學生啦,或者是研究室的同仁啦, 可以透過這部機器幫他們進行研究的工作,這個時候,你的主機就可以讓多人進行分享 Linux 運算的功能啦!

舉例來說,鳥哥與崑山還有長榮大學的老師、同學們組建了一組伺服器等級的叢集架構電腦 (PC cluster), 目前我們在該電腦上面跑 MM5 、Models3 等大氣與空氣品質模式,要在這樣的架構底下跑數值模式的原因, 主要就是考量運算能力。那會使用到該組電腦的有好多人,難道大家都在擠在一部螢幕前面工作?當然不需要啦! 這時候就是遠端連線伺服器的服務範圍囉!

但是否每一部連到 Internet 上面的主機都應該要開放遠端連線的功能呢?其實並不盡然, 還是需要針對你的主機來進行規劃的,我們底下分伺服器與工作站來說明:

在一般對網際網路開放服務的伺服器中,由於開放的服務可能會有較為重要的資訊,而遠端連線程式連進主機之後, 可以進行的工作又太多了(幾乎就像在主機前面工作一般!),因此伺服器的遠端連線程式通常僅針對少部分系統維護者開放而已! 除非必要,否則 Server 類型的主機還真的不建議開放連線的服務呢!

以鳥哥為例,我的主機提供了我們研究室使用 Mail 與 Internet 上面的 WWW 服務,如果還主動提供遠端連線的話, 那麼萬一不小心被入侵,那可就傷腦筋了!因此,鳥哥僅開放『很小部分的網域』讓系統管理員連進來, 其他來源的 IP 一律抵擋!不許使用遠端連線的功能呢!

所謂的工作站就是不提供網際網路服務的主機,僅提供大量的運算能力給使用者。 既然不提供網際網路的服務,那你還開連線伺服器幹嘛?不是啦!像前面鳥哥提到的 PC cluster 大量運算的整組電腦, 也可以稱之為工作站,因為它沒有提供常見的網路服務嘛!不過必須要提供給使用者登入的權限,這樣大家才用的到運算功能啊! 此時你就得要針對內部,或者是特定的某些來源開放他們使用你的工作站囉!


11.1.2 有哪些可供登入的類型?

那麼目前遠端連線伺服器的主要類型有哪些?如果以登入的連線介面來分類,基本上有文字介面與圖形介面兩種:

在文字介面登入的連線伺服器,主要有以『明碼』傳送資料的 telnet 伺服器,及以加密技術進行資料加密再傳送的 SSH 伺服器!雖然 telnet 可以支援的用戶端端軟體比較多,不過由於它是使用明碼來傳送資料,你的資料很容易遭到有心人士的擷取! 所以近來我們都呼籲大家多使用 SSH 這一種連線方式

至於圖形介面的連線伺服器,比較簡單的有 Xdmcp (X Display Manager Control Protocol),架設 Xdmcp 很簡單, 不過用戶端端的軟體比較少。另外一款目前很常見的圖形連線伺服器,就是 VNC (Virtual Network Computing), 透過 VNC server/client 軟體來進行連接。如果你想要使用類似 Windows 的遠端桌面連線,該功能使用的是 RDP (Remote Desktop Protocol),那你可得要架設 RDP 伺服器才行。

圖形介面最大的優點是『圖形』啊!不過,因為是透過圖形來傳送,傳輸的資料量相當的大, 所以速度與安全性都有待考量。因此,我們僅建議你將圖形介面的遠端登入伺服器開放在內部網域 (LAN) 就好了!

什麼是『明碼』與『加密』的資料封包傳送模式呢?為什麼 telnet 使用明碼就比較不安全?所謂的明碼就是: 『當我們的資料封包在網路上傳輸時,該資料封包的內容為資料的原始格式』, 也就是說,你使用 telnet 登入遠端主機時,不是得要輸入帳號密碼嗎?那你的帳號密碼是以原本的資料格式傳輸, 所以如果被類似 tcpdump 之類的監聽軟體擷取資料, 那你的帳密就有可能被竊取啦!

所以啦,萬一你的資料封包裡面含有信用卡資料、密碼、身份確認等重要資訊時,是否很危險吶? 因此,目前我們通常都希望使用可以將這些在網路上面跑的資料加密的技術,以增加資料在 Internet 上面傳送的安全性啊!

說 ssh 比較安全,其實是透過 ssh 通道傳輸訊息時,該訊息在網路上面比較安全,因為資料是加密過的,即使被竊取, 對方可能也不會知道資料內容為何,因此資訊比較安全。但這不代表 ssh 這個通訊協定就比較安全喔!兩者意義不同!

由於明碼傳輸的 telnet, rsh 等連線伺服器已經被 ssh 取代,並且在一些實際應用上已經很少看到 telnet 與 rsh 了, 因此本章在文字介面上面著重於介紹 ssh 的應用,包括以 rsync 藉由 ssh 通道來進行異地備援的任務等等。至於圖形介面則會介紹 Xdmcp, VNC 與 RDP 喔!因為很多工作站使用者需要顯示他們在工作站實作後的圖形呈現,因此這部分也是很重要的呢!


11.2 文字介面連線伺服器: SSH 伺服器

由於先前的遠端連線伺服器大多是明碼,而且協定也有些資安問題,因此後來就有 SSH 這個協定來取代上述這些咚咚。 那麼 SSH 是什麼呢?它有什麼特異功能?簡單的來說,SSH 是 Secure SHell 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 監聽而竊取,他們也不容易就推算得出來原始資料內容的。

鳥哥常常說,加密機制有點像是兩個人之間的火星語對話啦!如果你跟你的朋友約定好使用你們制訂的某種特別語言, 這個語言只對你們兩個有意義。那麼當你們兩人講話時,在旁邊的人聽到的只是一堆沒有意義的聲音,因為他們聽不懂啊! 即使路人將你的聲音錄下來,只要他不知道你們的特殊用語,那他就不可能瞭解你們對話的內容囉。

加解密運算的機制與技術非常多,我們這裡不去討論複雜的理論問題,只談對我們比較有關的一些加解密概念而已。 目前常見的網路封包加密技術通常是藉由所謂的『非對稱金鑰系統』來處理的。 主要是透過兩把不一樣的公鑰與私鑰 (Public and Private Key) 組合成為一把獨一無二的金鑰 (key pair) 後, 利用這把金鑰來進行資料的加解密工作。那這兩把鑰匙怎麼來的呢?

所以大家都看的到公鑰,但是私鑰卻是隨機運算產生的,而用戶端產生私鑰並進一步組合成金鑰後, 此時伺服器與用戶端兩邊均有這把金鑰。當資料要進行傳送的時候,系統會使用公鑰來進行加密,當接收端收到密碼後, 系統會使用私鑰來進行解密。由於在 Internet 上面跑的資料是加密過後的,所以你的資料內容當然就比較安全啦!

公鑰與私鑰在進行資料傳輸時的角色示意圖
圖 11.2-1、公鑰與私鑰在進行資料傳輸時的角色示意圖
資料加密的技術真的相當的多,也各有其優缺點,有的運算速度快,但是不夠安全;有的夠安全,但是加密/解密的速度較慢∼ 目前在 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. 回傳私鑰資料到伺服器端: 透過前一個步驟取得的公鑰進行加密,將這次連線計算所得的私鑰資料加密傳送到伺服器, 此時由用戶端傳送到伺服器端的資料是加密的!而伺服器端則透過自己的私鑰來進行解密。此時的加密應該是單向的, 亦即由用戶端加密送來的資料只有伺服器能夠解密,但伺服器送出去的資料用戶端是不能解密的,因為並沒有解密的私鑰。 因此前面的 1~4 步驟在伺服器送到用戶端這個方向,應該都是明碼傳送的;

  6. 伺服器接受私鑰,開始雙向加解密連線: 等到伺服器接受這把用戶端的私鑰後,才是透過金鑰系統進行雙向加解密;

在上述的第 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*
四  2月 17 13:50:29 CST 2011
-rw------- 1 root root  668  2月 17 13:49 /etc/ssh/ssh_host_dsa_key
-rw-r--r-- 1 root root  590  2月 17 13:49 /etc/ssh/ssh_host_dsa_key.pub
-rw------- 1 root root  963  2月 17 13:49 /etc/ssh/ssh_host_key
-rw-r--r-- 1 root root  627  2月 17 13:49 /etc/ssh/ssh_host_key.pub
-rw------- 1 root root 1675  2月 17 13:49 /etc/ssh/ssh_host_rsa_key
-rw-r--r-- 1 root root  382  2月 17 13:49 /etc/ssh/ssh_host_rsa_key.pub
# 看一下上面輸出的日期與檔案的建立時間,剛剛建立的新公鑰、私鑰系統!


11.2.2 啟動 SSH 服務

事實上,在我們使用的 Linux 系統當中,預設就已經含有 SSH 的所有需要的軟體了!這包含了可以產生密碼等協定的 OpenSSL 軟體與 OpenSSH 軟體 (註1),所以呢,要啟動 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  3236/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 在 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 aa:a3:37:49:fd:51:2e:f4:72:eb:85:c8:8d:07:2a:a1.
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: Fri Feb 18 11:26:14 2011
[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 就很有幫助啦!他會不詢問自動加入主機的公鑰到檔案中,對於一般使用者幫助不大,對於程式腳本來說, 這玩意兒可就很不錯用了!

當你登入遠端伺服器時,本機會主動的用接收到的伺服器的 public key 去比對 ~/.ssh/known_hosts 有無相關的公鑰, 然後進行底下的動作:

雖然說伺服器的 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
1f:69:e0:8a:c6:ba:14:75:5a:b5:d5:00:f5:45:45:3c.
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 過,那系統又會重新問你要不要加上公鑰囉!就這麼簡單! ^_^

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 來進行連線的啦! 如此一來,與伺服器之間的檔案傳輸就方便多了吧!

通常使用 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 等。底下就讓我們來談談這幾個軟體吧。

在 Linux 底下想要連接 SSH 伺服器,可以直接利用 ssh 這個指令,在 Windows 作業系統底下就得要使用 pietty 或 putty 這兩個玩意兒,這兩者的下載點請參考 (註2):

在 putty 的官方網站上有很多的軟體可以使用的,包括 putty/pscp/psftp 等等。他們分別對應了 ssh/scp/sftp 這三個指令就是了。而鳥哥愛用的 pietty 則是台灣的林弘德先生根據 putty 所改版而成的。由於 pietty 除了完整的相容於 putty 之外,還提供了選單與較為完整的文字編碼,實在很好用呢,所以底下鳥哥就以 pietty 來作為介紹囉。在你下載 pietty 完成後,雙擊該檔案,就會出現如下的畫面囉:

pietty 的啟動畫面示意圖
圖 11.2-3、pietty 的啟動畫面示意圖

在上圖中箭頭為 1 的地方請填寫相關的主機名稱或者是 IP ,箭頭 2 當然務必選擇 SSH 那一項,至於箭頭 3 的地方,鳥哥比較喜歡選單出現的樣式,因為可以直接修改一些 pietty 的環境設定值,所以鳥哥是選擇選單啦! 若沒有問題,按下『連線』後,就會出現如下等待登入與輸入帳/密資料的畫面:

pietty 的登入與使用畫面示意圖
圖 11.2-4、pietty 的登入與使用畫面示意圖

這個圖示會讓你以為是在主機前面工作吧!而且上頭還有選單可以隨時調整類似字形、字體、字元編碼等等的重要環境參數。 尤其是字元編碼的問題,有時候你會發現開啟檔案時,竟然畫面當中會有亂碼而不是正常的中文顯示, 那就是編碼的問題。要解決這個問題時,你必須要牢記下面的三個跟語系編碼有關的資料要相同才行:

我們知道 Linux 本身的編碼可以透過 LANG 這個變數來調整,那該如何調整 pietty 的中文編碼呢?你可以透過圖 11.2-4 選單列當中的『選項』來處理,如下所示:

調整 pietty 的語系編碼方式 (與中文較相關)
圖 11.2-5、調整 pietty 的語系編碼方式 (與中文較相關)

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

pietty 軟體環境詳細設定,與鍵盤右側數字鍵相關者
圖 11.2-6、pietty 軟體環境詳細設定,與鍵盤右側數字鍵相關者

將上圖中箭頭 2 所指的那個項目勾選起來且按下『Apply』之後,你鍵盤右側的數字鍵才能夠正常的使用呢,否則按右側數字鍵會是亂碼啦。 再來,你可以調整 pietty 捲軸的記憶行數,這樣當資料太多時,你依舊可以調整捲軸來查閱之前的資料。設定的方法如下:

調整畫面可以記憶的行數,可讓用戶回去看較多之前的畫面
圖 11.2-7、調整畫面可以記憶的行數,可讓用戶回去看較多之前的畫面

調整完這些常用的資料後,再來這是最重要的:『你要以哪一個版本的 SSH 演算法登入?』前面說過,我們預設是以 version2 來登入的,所以這裡我們可以調整為 2 那個項目!這樣每次登入都會以 version 2 的模式登入主機了!

設定登入伺服器時使用的 ssh 演算法版本
圖 11.2-8、設定登入伺服器時使用的 ssh 演算法版本

整個 pietty 的使用與相關設定流程就是這樣!如此一來,你就可以在 Windows 上面以 SSH 的協定,登入遠端的 Linux 主機嚕!粉方便吧! ^_^ !如果想要中文支援的話,目前 pietty 已經支援中文啦!你可以輸入中文喔!不過需要修改一下字元集, 選擇圖 11.2-5 『選項』內的『字型』就會出現如下圖示:

選擇中文的字形與編碼
圖 11.2-9、選擇中文的字形與編碼

將(1)字型設定為細明體、(2)字集設定為『Big5』,如此一來,你的 pietty 就支援中文的輸入囉!

那麼上面我們作的這些設定值都記錄在哪裡啊?呵呵!都記錄在 Windows 的登錄檔當中啊!你可以在 Windows 的系統當中,在『開始』-->『執行』後,出現的框框內輸入『regedit』, 之後會出現一個大視窗。請在左邊的畫面當中選擇『 HKEY_CURRENT_USER --> Software --> SimonTatham --> PuTTY --> Sessions』, 就可以看到你的設定值囉! ^_^! 這樣,也就可以儲存你的設定值囉∼

在 putty 的官方網站上也提供 psftp 這支程式。這一支程式的重點則在使用 sftp-server。使用的方式可以直接點選 psftp 這個檔案,讓他直接啟動,則會出現下面的圖樣:

psftp: no hostname specified; use "open host.name" to connect
psftp>

這個時候可以填入你要連接上去的主機名稱,例如我的區域內網路 192.168.1.10 這部主機:

psftp: no hostname specified; use "open host.name" to connect
psftp> open 192.168.1.10
login as: root
root@192.168.1.10's password:
Remote working directory is /root
psftp> <== 這裡就在等待你輸入 FTP 的指令了!

呵呵!這樣就登入主機啦!很簡單吧!然後其他的使用方式跟前面提到的 sftp 一樣哩!加油的使用吧!

SSH 所提供的 sftp 功能只能利用純文字介面的 psftp 來連線嗎?有沒有圖形介面的軟體呢?呵呵!當然有! 那就是非常有用的 Filezilla 囉!Filezilla 是圖形介面的一個 FTP 用戶端軟體,使用上非常的方便, 至於詳細的安裝與使用流程請參考 vsftpd 章節的說明喔!


11.2.5 sshd 伺服器細部設定

基本上,所有的 sshd 伺服器詳細設定都放在 /etc/ssh/sshd_config 裡面!不過,每個 Linux distribution 的預設設定都不太相同,所以我們有必要來瞭解一下整個設定值的意義為何才好! 同時請注意,在預設的檔案內,只要是預設有出現且被註解的設定值 (設定值前面加 #),即為『預設值!』,你可以依據它來修改的哩。

[root@www ~]# vi /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.0.100 及 
# 192.168.2.20 ,假設你只想要讓 192.168.0.100 可以監聽 sshd ,那就這樣寫:
# 『 ListenAddress 192.168.0.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 基礎去翻一下。其他可用的 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 才行!亦即是:


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/ 裡面的認證檔案即可完成整個程序。

說是好像很困難的樣子,其實步驟真的很簡單,我們依序來進行作業好了!假設前提如下,該進行的步驟則如下圖:

製作不需要密碼的 ssh 帳號基本流程
圖 11.2-10、製作不需要密碼的 ssh 帳號基本流程

建立的方法很簡單,在 client.centos.vbird 這部主機上面以 vbirdtsai 的身份來建立兩把鑰匙即可。 不過,需要注意的是,我們有多種密碼演算法,如果不指定特殊的演算法,則預設以 RSA 演算法來處理:

[vbirdtsai@client ~]$ ssh-keygen [-t rsa|dsa] <==可選 rsa 或 dsa
[vbirdtsai@client ~]$ 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:
42:20:e1:dc:62:94:44:4f:b1:46:6f:3a:5d:20:01:a4 vbirdtsai@client.centos.vbird

[vbirdtsai@client ~]$ ls -ld ~/.ssh; ls -l ~/.ssh
drwx------ 2 vbirdtsai vbirdtsai 4096  2月 20 12:08 /home/vbirdtsai/.ssh
-rw------- 1 vbirdtsai vbirdtsai 1675  2月 20 12:08 id_rsa     <==私鑰檔
-rw-r--r-- 1 vbirdtsai vbirdtsai  411  2月 20 12:08 id_rsa.pub <==公鑰檔

請注意上面喔,我的身份是 vbirdtsai ,所以當我執行 ssh-keygen 時,才會在我的家目錄底下的 .ssh/ 這個目錄裡面產生所需要的兩把 Keys ,分別是私鑰 (id_rsa) 與公鑰 (id_rsa.pub)。 另外一個要特別注意的就是那個 id_rsa 的檔案權限啦!他必須要是 -rw------- 且屬於 vbirdtsai 自己才行!否則在未來金鑰比對的過程當中,可能會被判定為危險而無法成功的以公私鑰成對檔案的機制來達成連線喔。 其實,建立私鑰後預設的權限與檔名放置位置都是正確的,你只要檢查過沒問題即可。

因為我們要登入 www.centos.vbird 是以 dmtsai 的身份,因此我們就得要將上個步驟建立的公鑰 (id_rsa.pub) 上傳到伺服器上的 dmtsai 用戶才行。那如何上傳呢?最簡單的方法當然就是使用 scp 嘛!

[vbirdtsai@client ~]$ scp ~/.ssh/id_rsa.pub dmtsai@192.168.1.10:~
# 上傳到 dmtsai 的家目錄底下即可。

還記得 sshd_config 裡面談到的 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  2月 20 21:16 .ssh
# 權限設定中,務必是 700 且屬於使用者本人的帳號與群組才行!

# 2. 將公鑰檔案內的資料使用 cat 轉存到 authorized_keys 內
[dmtsai@www ~]$ ls -l *pub
-rw-r--r-- 1 dmtsai dmtsai 411  2月 20 20:46 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 411  2月 20 21:20 authorized_keys
# 這個檔案的權限設定中,就得要是 644 才可以!不可以搞混了!


這樣就搞定金鑰系統囉!以後你從 client.centos.vbird 的 vbirdtsai 登入到 www.centos.vbird 的 dmtsai 用戶時, 就不需要任何的密碼囉!舉例來說,你可以這樣測試看看囉:

例題:
透過上述的案例練習成功後,請在 client 的 vbirdtsai 身份中,將系統的 /etc/hosts* 檔案複製給 www.centos.vbird 的 dmtsai 用戶的家目錄。
答:
[vbirdtsai@client ~]$ scp /etc/hosts* dmtsai@192.168.1.10:~
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@client ~]$ ssh dmtsai@192.168.1.10 "ls -l"
-rw-r--r-- 1 dmtsai dmtsai 187  2月 20 21:26 hosts
-rw-r--r-- 1 dmtsai dmtsai 161  2月 20 21:26 hosts.allow
-rw-r--r-- 1 dmtsai dmtsai 347  2月 20 21:26 hosts.deny
-rw-r--r-- 1 dmtsai dmtsai 411  2月 20 20:46 id_rsa.pub
# 確實有複製到對方去了!有顯示出正確的遠端資料哩!

很簡單的步驟吧!這樣一來,使用 ssh 相關的用戶端指令就可以不需密碼的手續了!無論如何,在建立金鑰系統的步驟中你要記得的是:

未來,當你還想要登入其他的主機時,只要將你的 public key (就是 id_rsa.pub 這個檔案) 給他 copy 到其他主機上面去,並且新增到某帳號的 ~/.ssh/authorized_keys 這個檔案中!哈哈!成功!


11.2.7 簡易安全設定

老實說,大家都被『SSH 是個安全的服務』所欺騙了!其實 sshd 並不怎麼安全的!翻開 openssh 的過去歷史來看,確實有很多人是利用 ssh 的程式漏洞來取得遠端主機 root 的權限,進一步黑掉對方的主機!所以這玩意兒說實話,也不是很安全的啦!

sshd 之所謂的『安全』其實指的是『 sshd 的資料是加密過的,所以他的資料在 Internet 上面傳遞時是比較安全的。至於 sshd 這個服務本身就不是那樣安全了!所以說:『非必要,不要將 sshd 對 Internet 開放可登入的權限,盡量侷限在幾個小範圍內的 IP 或主機名稱即可!這很重要的喔!

好了,那麼關於安全的設定方面,有沒有什麼值得注意的呢?當然是有啦!我們可以先建議幾個項目吧!分別可以由底下這三方面來進行:

一般而言,這個檔案的預設項目就已經很完備了!所以,事實上是不太需要更動他的! 但是,如果你有些使用者方面的顧慮,那麼可以這樣修正一些問題呢!

除了上述的帳號之外,其他的用戶則可以正常的使用系統。現在鳥哥假設你的系統裡面已經有 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=501(sshnot1) gid=502(sshnot1) groups=502(sshnot1),501(nossh)
uid=502(sshnot2) gid=503(sshnot2) groups=503(sshnot2),501(nossh)
uid=503(sshnot3) gid=504(sshnot3) groups=504(sshnot3),501(nossh)
uid=504(testssh) gid=505(testssh) groups=505(testssh)
uid=505(student) gid=506(student) groups=506(student)

# 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
Feb 20 22:02:00 www sshd[16472]: pam_unix(sshd:auth): authentication failure;
logname= uid=0 euid=0 tty=ssh ruser= rhost=localhost.localdomain  user=root
# 你會發現出現這個錯誤訊息,而不是密碼輸入錯誤而已。

[root@www ~]# ssh sshnot1@localhost  <==並請輸入正確的密碼
[root@www ~]# tail /var/log/secure
Feb 20 22:04:38 www sshd[16481]: User sshnot1 from localhost.localdomain not 
allowed because a group is listed in DenyGroups

[root@www ~]# ssh testssh@localhost  <==並請輸入正確的密碼
[root@www ~]# tail /var/log/secure
Feb 20 22:06:41 www sshd[16490]: User testssh from localhost.localdomain not 
allowed because listed in DenyUsers

從上面的結果來看,你就會發現到,不同的登入帳號會產生不一樣的登錄檔結果。因此,當你老是無法順利使用 ssh 登入某一部主機時,記得到該伺服器上去檢查看看登錄檔,說不定就會順利的讓你解決問題囉!

舉例來說,你的 sshd 只想讓本機以及區網內的主機來源能夠登入的話,那就這樣作:

[root@www ~]# vim /etc/hosts.allow
sshd: 127.0.0.1 192.168.1.0/255.255.255.0

[root@www ~]# vim /etc/hosts.deny
sshd : ALL 

多幾層保護也很好的!所以也可以使用 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
[root@www ~]# /usr/local/virus/iptables/iptables.rule

上述的方法處理完畢後,如果你還是一部測試機,那麼記得要將設定值還原回來呦!最後, 『鳥哥呼籲大家,不要開放 SSH 的登入權限給所有 Internet 上面的主機∼』 這很重要喔∼因為如果對方可以 ssh 進入你的主機,那麼...太危險了∼


11.3 最原始圖形介面: Xdmcp 服務的啟用

考慮一個情況,如果你的 Linux 主機主要是用來作為圖形處理時,而且同時有多人需要用到那個功能, 那麼一部 Linux 是否一次僅能提供一個人處理那個軟體呢?嘿嘿!那可不一定喔!因為 Linux 有相當優秀的 X Window System 啊!現在就來談談第一個圖形介面的遠端連線伺服器吧!


11.3.1 X Window 的 Server/Client 架構與各元件

由於我們 Linux 使用的圖形介面是所謂的 X-Window System 的東西,這玩意兒是能夠跨平台的,目前在 Linux 上頭開發的圖形介面軟體,幾乎都是使用這個 X 的架構來處理,所以囉,你就不能夠不知道 X Window 啦! 我們在基礎篇第三版的二十四章已經講過 X Window 啦, 因此這裡只會作個簡單的介紹,以方便大家來瞭解為何我們的軟體是這麼安裝與設定喔!

X Window System 在運作的過程中,又因控制的資料不同而分為 X Server 與 X Client 兩種程序,雖然說是 X Server/Client , 但是他的作用卻與網路主機的 Server/Client 架構大異其趣喔∼先來說說 X Server/Client 這兩種程序所負責的任務先:

鳥哥常常開玩笑的說, X server 就是畫布,而 X client 就是手拿畫筆的畫家。你得要先有畫布 (管理好所有可顯示的硬體後) 之後畫家的想法 (計算出來的繪圖數據) 才能夠繪製到畫布上!

由於每一支 X client 都是獨立存在的程序,因此在圖形顯示會發生一些疊圖的問題 (想像一下每一個 X client 都是一個很自我的畫家, 每個畫家都不承認對方的存在,都自顧自的在畫布上面作畫,最後的結果會是如何?)。因此,後來就有一組特殊的 X client 在進行管理所有的其他 X client 程式,這個總管的咚咚就是 Window Manager!

既然 X Window System 是 Linux 上面的一組程式,那麼它如何啟動的呢?早期的使用者在登入系統後,必須要自己先啟動 X server 程式,然後再啟動個別的 Window manager ,若有其他需求,再啟動其他額外的 X client 就是了。這麼麻煩!所以為了簡化啟動個人圖形介面的步驟,後來還有所謂的 Display Manager (DM) 這玩意喔!

在目前新釋出的 Linux distributions 中,通常啟動圖形介面讓使用者登入的方式中,都是先執行 Display Manager 程式, 該程式會主動載入一個 X Server 程式,然後再提供一個等待輸入帳號密碼的介面程式,之後再根據使用者的選擇去啟動所需要的 Window Manager 程式,最後就由使用者直接操作 WM 來玩圖形介面囉。

例題:
在 CentOS 5.x 當中,若預設為 init 5 的情況下,那麼最終啟動圖形介面的是哪一隻程式?
答:
分析 /etc/inittab 當中會發現底下這行:
x:5:respawn:/etc/X11/prefdm -nodaemon
你可以分析 /etc/X11/prefdm 的內容,就能夠發現其實該行啟動的就是一個 X display manager 程式了喔!

例題:
登入 init 5 的 CentOS 5.x 之前,先到 tty1 去查閱一下 X server 是由哪一支程式所喚醒的?
答:
我們可以透過 pstree 來觀察程序間的相關性喔!同時注意,預設的 CentOS 5.x 的 X server 程式名稱為 Xorg 的哩。
[root@www ~]# pstree -p
init(1)─┬─acpid(1978)
....(中間省略)....
         ├─anacron(2189)
         ├─gdm-binary(2318)───gdm-binary(2390)─┬─Xorg(2395)
         │                                          └─gdmgreeter(2416)
....(後面省略)....
由上述的資料來看, gdm-binary 可以喚醒 Xorg 喔!同理,我們也會知道提供認證的圖形畫面應該是由 gdmgreeter 所提供的喔!

當 X server, X client 都在同一部主機上面的時候,你可以很輕鬆的啟動一個完整的 X Window System。 但是如果你想要透過這個機制在網路上面啟動 X 呢?此時你得先在用戶端啟動一個 X server 將圖形介面繪圖所需要的硬體裝置配置好, 並且啟動一個 X server 常見的接收埠口 (通常是 port 6000),然後再由伺服器端的 X client 取得繪圖數據,再將資料繪製成圖囉。 透過這個機制,你可以在任何一部啟動 X server 登入伺服器喔!而且不管你的作業系統是啥呢!意義就像下圖, 如此一來,你就可以取得伺服器所提供的圖形介面環境啦!

X server/client 的架構
圖 11.3-1、X server/client 的架構

但是如果你是使用最笨的方法在用戶端自己啟動 X server ,然後在告訴伺服器將 X client 程式一個一個的載入回來, 那就太累人了吧!我們之前上面不是提到過可以用 display manager 來管理使用者的登入與啟動 X 嗎?那伺服器能不能提供一個類似的服務, 那我們直接透過伺服器的 display manager 就能夠提供我們登入的認證與載入自己選擇的 window manager 的話,這樣就太棒了! 能夠達到嗎?當然可以啊!那就是透過 Xdmcp (X display manager control protocol) (註3) 啦!

Xdmcp 啟動後會在伺服器的 udp 177 開始監聽,然後當用戶端的 X server 連線到伺服器的 port 177 之後, 我們的 Xdmcp 就會在用戶端的 X server 放上使用者輸入帳密的圖形介面程式囉!那你就能透過這個 Xdmcp 去載入伺服器所提供的類似 Window Manager 的相關 X client 囉!那你就能夠取得圖形介面的遠端連線伺服器哩!贊吧!

那麼什麼時候會出現多使用者連入伺服器取得 X 的情況呢?以鳥哥的例子來說,鳥哥實驗室有一組 Linux 在進行數值模擬, 他輸出的結果是 NetCDF 檔案,我們必須使用 PAVE 這一套軟體去處理這些資料。但是我們有兩三個人同時都會使用到那個功能, 偏偏 Linux 主機是放在機架櫃裡面的,要我們擠在那個小小的空間前面『站著』操作電腦,可真是討人厭啊∼ 這個時候,我們就會架設圖形介面的遠端登入伺服器,讓我們可以『多人同時以圖形介面登入 Linux 主機』來操作我們自己的程序!很棒,不是嗎!


11.3.2 設定 gdm 的 XDMCP 服務

既然是所謂的 Xdmcp 協定,那麼是否意味著與 X display manager 有關呢?沒錯啦! Xdmcp 協定是由 DM 程式所提供的。 我們的 CentOS 預設的 DM 為 GNOME 這個計畫所提供的 gdm 哩!因此,你想要啟動 Xdmcp 服務,那就得要針對 gdm 這個程式來設定囉。 這個 gdm 的設定資料都放置在 /etc/gdm/ 目錄下,而我們所要修改的設定檔其實僅是一個 /etc/gdm/custom.conf (註4) 檔案而已。

X11 提供的 display manager 為 xdm ,而著名的 KDE 與 GNOME 也都有自己的 display manager 管理程序,分別是 kdm 與 gdm 。你可以透過三者中任何一者的 display manager 的設定檔來啟動 xdmcp 這個協定呢∼
[root@www ~]# vim /etc/gdm/custom.conf
[security]           <==約在第 44 行左右
AllowRemoteRoot=yes  <==xdmcp 預設不許 root 登入,得用這個項目才能以 root 登入
DisallowTCP=false    <==這個項目在允許用戶端使用 TCP 的方式連線到 xdmcp

[xdmcp]              <==約在第 46 行左右
Enable=true          <==啟動 xdmcp 的最重要項目囉!
# 上述特殊字體的部份就是你得要自己新增的內容囉!

[root@www ~]# gdm-restart
# 上述這個指令會讓你的 X 重新啟動,因此這個指令下達時,記得 X 內的資料要先儲存

[root@www ~]# netstat -tulnp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address  Foreign Address   State    PID/Program name
tcp        0      0 0.0.0.0:6000   0.0.0.0:*         LISTEN   2704/Xorg
tcp        0      0 :::6000        :::*              LISTEN   2704/Xorg
udp        0      0 0.0.0.0:177    0.0.0.0:*                  2323/gdm-binary
# 上述的 port 6000 是由 DisallowTCP=false 項目啟動的, port 177 才是我們要的

上述的動作鳥哥是在 runlevel 5 底下啟動的,因此你也可以利用『 init 3 && init 5 』來重新啟動圖形介面。 但如果你是在 runlevel 3 底下並且不希望變更成為 runlevel 5 呢?那又該如何啟動 port 177 啊?如果是這樣的話, 那麼你可以這樣啟動 xdmcp 啦:

[root@www ~]# init 3
[root@www ~]# runlevel
5 3 <==左邊的是前一個 runlevel,右邊的是目前的,因此目前是 runlevel 3
[root@www ~]# gdm   <==這樣就啟動 xdmcp 囉!
[root@www ~]# vim /etc/rc.d/rc.local
/usr/sbin/gdm

現在你知道如何在不同的 runlevel 啟動 xdmcp 了吧?如果是 runlevel 5 ,因為在 /etc/inittab 就已經有自動啟動 gdm 了, 所以你只要順利啟動 runlevel 5 即可。但如果你是在 runlevel 3 的話,因為這樣 gdm 就不會被系統的啟動流程啟動, 那你只好自己在 /etc/rc.d/rc.local 裡面指定啟動他囉!這樣瞭解呼?接下來,你得要開放用戶端對你的 port 177 連線才行! 請自行修改你的防火牆規則,開放 udp port 177 吧!鳥哥這裡假設你使用鳥哥的防火牆腳本,那你這樣作就好了:

[root@www ~]# vim /usr/local/virus/iptables/iptables.rule
iptables -A INPUT -p UDP -i $EXTIF --dport 177 --sport 1024:65534 \
> -s 192.168.1.0/24 -j ACCEPT #xdmcp

[root@www ~]# /usr/local/virus/iptables/iptables.rule
[root@www ~]# iptables-save | grep 177
-A INPUT -s 192.168.1.0/255.255.255.0 -i eth0 -p udp -m udp --sport 1024:65534 
--dport 177 -j ACCEPT  <==這是同一行喔!
# 確實有開放 port 177 ,而且是 udp 的埠口喔!要注意這兩個項目。

11.3.3 用戶系統為 Linux 的登入方式

由於 Linux 本身的視窗就是由 X server 提供來的,因此使用 Linux 登入遠端的圖形伺服器是很簡單的啦! 但是因為啟動 X 的方式不同而已數種啟動方式,底下我們就講講兩個常見的啟動方式:

如果你的用戶端已經在 runlevel 5 了,因此其實你已經有一個 X 視窗的環境,這個環境的顯示終端機就稱為『 :0 』。 在 CentOS 5.x 的環境中,這個圖形介面的 :0 是在 tty7 終端機啦!由於已經有一個 X 了,因此你必須要在另外的終端機啟動另一個 X 才行!那個新的 X 就稱為 :1 介面,其實通常就在 tty8 啦!但因為 X server 要接受 X client 必須要有授權才行, 所以你得先在視窗介面開放接受來自伺服器的 X client 資料。

此外,雖然你在用戶端是以主動的方式連接到伺服器的 udp port 177 ,但是伺服器的 X client 卻會主動的連接到你用戶端的 X server,因此,你必須要開放來自伺服器端主動對你的 TCP port 6001 (因為是 :1 介面) 的防火牆連線才行喔!那就來實做看看:

# 1. 在 X Window 的畫面當中,啟用一個 shell ,然後輸入:
[root@client ~]# xhost + 192.168.1.10
192.168.1.10 being added to access control list
# 假設我剛剛那部 Linux 主機的 IP 為 192.168.1.10

# 2. 開始啟動防火牆,因為我們啟動 port 6001 ,所以你在用戶端這樣作:
[root@client ~]# vim /usr/local/virus/iptables/iptables.allow
iptables -A INPUT -i $EXTIF -s 192.168.1.0/24 -p tcp --dport 6001 -j ACCEPT

[root@client ~]# /usr/local/virus/iptables/iptables.rule
[root@client ~]# iptables-save
-A INPUT -s 192.168.1.0/255.255.255.0 -p tcp -m tcp --dport 6001 -j ACCEPT
# 要能看到上面這一行才行呦!

# 3. 在文字介面 (例如 tty1) 下輸入如下的指令:
[root@client ~]# X -query 192.168.1.10 :1
# 進入 X Window 囉!

如果一切順利的話,那麼你在 client.centos.vbird 就會看到如下的畫面(注意主機名稱):

在用戶端連上 Xdmcp 成功的畫面
圖 11.3-2、在用戶端連上 Xdmcp 成功的畫面

在上圖中輸入正確的帳號與密碼之後,你在 tty8 (:1) 就會有個視窗介面囉!那你如果想要回到本機的視窗介面, 就回到 tty7 (:0) 即可切換成功!那想要關閉 tty8 該如何是好?你不能夠在 tty8 登出啦,因為登出後, 系統會重新開一個等待登入的畫面,你還是沒辦法關閉的。你得要回到剛剛啟動 X 的 tty1 然後按下 [ctrl]-c 中斷連線即可!

如果常常在 tty7, tty8 切換來去的話,偶而會忘記到底在哪個介面了,尤其是當你的桌面都一模一樣時, 那就更難判斷了。有沒有辦法直接在 tty7 啟動另一個視窗來載入遠端伺服器的圖形介面呢?可以的,那就透過 Xnest 吧! 這指令需要在 X 的環境下使用喔!它的簡單用法如下:

[root@www ~]# Xnest -query 主機名 -geometry 解析度 :1
選項與參數:
-query    :後面接 xdmcp 伺服器的主機名稱或 IP 囉
-geometry :後面接畫面的解析度,例如 1024x768 或 800x600 等之類的解析度

# 根據上述資料,使用 800x600 連上 192.168.1.10 那部主機:
[root@www ~]# Xnest -query 192.168.1.10 -geometry 800x600 :1

如果一切順利的話,那你就會在 tty7 的本機 X 環境下看到如下的畫面 (底下的畫面是已經登入的情況!)

在用戶端的 X 順利連上 Xdmcp 的畫面
圖 11.3-3、在用戶端的 X 順利連上 Xdmcp 的畫面

一開始的圖示會與圖 11.3-2 一樣,就是出現輸入帳密的畫面,如果輸入正確的帳密後, 就會出現上述的圖示了。仔細看一下畫面當中的終端機標頭,你就會發現確實是兩部主機的桌面呢!這樣有沒有更棒棒? ^_^! 要關閉這個 X 就簡單多了!直接按下關閉,或者是中斷那個 Xnest 的程式即可。


11.3.4 用戶系統為 Windows 的登入方式: Xming

由於 Windows 本身並沒有提供預設的 X server ,因此我們得要自行安裝 X server 在 Windows 上面才行。 目前常見的 X server 有底下這幾個:

其中 X-Win32 與 Exceed 都屬於商業軟體,而 Xming 則屬於輕量級的自由軟體,說是輕量級並非說它不好, 而是因為 Xming 的檔案真的很小,而該有的功能都有了,所以算是很不賴的一個軟體喔!因此底下鳥哥是以 Xming (註5) 作範例來介紹的。

  1. 安裝:你可以使用預設的方法,一直下一步的安裝下去,就能夠順利的安裝好 Xming 這套 X server 的軟體囉。

  2. 啟動:請在『開始』-->『程式集』-->『Xming』-->『XLaunch』開啟設定連線到 xdmcp 的方式。底下我們會使用區網內的廣播 (broadcast) 來找到 xdmcp 伺服器的方式。啟動 XLaunch 之後會出現如下的圖示:

    Xming 的 Xdmcp 連接方式示意圖
    圖 11.3-4、Xming 的 Xdmcp 連接方式示意圖

    記得上面的圖示要選擇 One window 或 Fullscreen 或 One window without titlebar 才能夠使用 XDMCP 喔!選擇完畢後按『下一步』 就會出現如下的畫面:

    Xming 的 Xdmcp 連接方式示意圖
    圖 11.3-5、Xming 的 Xdmcp 連接方式示意圖

    上述的圖示當中共有三種傳遞 X client 的方法,在這個小節當中我們要連到 xdmcp ,所以你得要選擇第三個喔!之後再下一步會出現下圖:

    Xming 的 Xdmcp 連接方式示意圖
    圖 11.3-6、Xming 的 Xdmcp 連接方式示意圖

    這裡當然就是連接到你想要連上去的 xdmcp 伺服器囉!將他的 IP 填上去吧!之後再下一步去:

    Xming 的 Xdmcp 連接方式示意圖
    圖 11.3-7、Xming 的 Xdmcp 連接方式示意圖

    上圖的項目與資料的互相複製貼上有關,保留預設值即可。按下下一步吧!

    Xming 的 Xdmcp 連接方式示意圖
    圖 11.3-8、Xming 的 Xdmcp 連接方式示意圖

    出現上圖就是設定完畢了,給它按下『完成』之後,你就會發現如同圖 11.3-2 的畫面出現,你就能夠開始在 Windows 底下連上圖形介面的 Linux Server 囉!很輕鬆吧!

其實從上面的設定當中你會發現, XDMCP 不論是在 Server 還是 Client 的設定上面都很簡單!但是有時候你就是會發現, 明明所有的動作都做完了,但是就是沒有辦法連上 Xdmcp 伺服器!最容易發生錯誤的其實就是防火牆啦!因為雖然我們用戶端啟動 X server 後,會主動連線到伺服器端的 Xdmcp (port 177),但是,接下來卻是伺服器主動連線到我們用戶端的 X server (可能是 port 6000~6010)。 因此,如果你只是設定了伺服器的防火牆而已,那麼很可能出現問題的應該就是用戶端的防火牆忘記打開提供伺服器主動連線的規則囉! 這點是必須要跟大家說明的喔!


11.4 華麗的圖形介面: VNC 伺服器

就如同剛剛上頭講到的,使用 xdmcp 可能會啟動多個不同的埠口,導致防火牆設定上面比較困擾些。那有沒有簡單一點的圖形介面連接方式? 其實還有很多啦,在這裡我們先來講一個比較簡單的,那就是 VNC (Virtual Network Computing) 這玩意兒啦!(註6)


11.4.1 預設的 VNC 伺服器:使用 twm window manager

VNC server 會在伺服器端啟動一個監聽用戶要求的埠口,一般埠口號碼在 5901 ~ 5910 之間。當用戶端啟動 X server 連線到 5901 之後, VNC server 再將一堆預先設定好的 X client 透過這個連線傳遞到用戶端上,最終就能夠在用戶端顯示伺服器的圖形介面了。

不過需要注意的是,預設的 VNC server 都是獨立提供給『單一』一個用戶端來連線的,因此當你要使用 VNC 時, 再連線到伺服器去啟動 VNC server 即可。所以,一般來說, VNC server 都是使用手動啟動的,然後使用完畢後, 再將 VNC server 關閉即可。整個作法其實很簡單喔!你可以這樣作:

[root@www ~]# vncserver [:號碼] [-geometry 解析度] [options]
[root@www ~]# vncserver [-kill :號碼]
選項與參數:
:號碼     :就是將 VNC server 開在哪個埠口,如果是 :1 則代表 VNC 5901 埠口
-geometry :就是解析度,例如 1024x768 或 800x600 之類的
options   :其他 X 相關的選項,例如 -query localhost 之類的
-kill     :將已經啟動的 VNC 埠口刪除!依據身份控制喔。

[root@www ~]# yum install vnc-server
# 這個是必須要的伺服器軟體

# 將 VNC server 啟動在 5903 埠口
[root@www ~]# vncserver :3

You will require a password to access your desktops.

Password:  <==輸入 VNC 的連線密碼,這是建立 VNC 時所需要的
Verify:    <==再輸入一次相同的密碼
xauth:  creating new authority file /root/.Xauthority
xauth: (stdin):1:  bad display name "www.centos.vbird:3" in "add" command

New 'www.centos.vbird:3 (root)' desktop is www.centos.vbird:3

Creating default startup script /root/.vnc/xstartup
Starting applications specified in /root/.vnc/xstartup
Log file is /root/.vnc/www.centos.vbird:3.log

[root@www ~]# netstat -tulnp | grep X
tcp        0      0 0.0.0.0:5803   0.0.0.0:*      LISTEN      6322/Xvnc
tcp        0      0 0.0.0.0:5903   0.0.0.0:*      LISTEN      6322/Xvnc
tcp        0      0 0.0.0.0:6003   0.0.0.0:*      LISTEN      6322/Xvnc
tcp        0      0 :::6003        :::*           LISTEN      6322/Xvnc
# 已經啟動所需要的埠口囉!

在上述的指令操作中,你要知道的幾個項目是:

  1. 密碼至少需要六個字元
  2. 依據使用 vncserver 的身份,將剛剛建立的密碼放置於該帳號家目錄下。例如上述的身份是使用 root 身份,因此密碼檔會放在 /root/.vnc/passwd 這個檔案中但是若該檔案已經存在,則不會出現建立密碼的畫面。
  3. 當用戶端連線成功後,伺服器將會傳送 /root/.vnc/startx 內的 X client 給用戶端喔!

那如果你想要修改 VNC 密碼呢?很簡單,那就使用 vncpasswd 吧!

[root@www ~]# ls -l /root/.vnc/passwd
-rw------- 1 root root 8  2月 22 12:31 /root/.vnc/passwd
[root@www ~]# vncpasswd
Password:  <==就是這裡開始輸入新的密碼啊!
Verify:
[root@www ~]# ls -l /root/.vnc/passwd
-rw------- 1 root root 8  2月 22 12:44 /root/.vnc/passwd
# 看吧!時間有更新喔!這個檔案的內容更動過囉!

接下來開始放行 5903 這個埠口的連線防火牆規則吧!因為預計可能會開放 11 個 VNC 的埠口,所以乾脆一口氣開放 11 個埠口吧!

[root@www ~]# vim /usr/local/virus/iptables/iptables.allow
iptables -A INPUT -i $EXTIF -s 192.168.1.0/24 -p tcp --dport 5900:5910 -j ACCEPT

[root@www ~]# /usr/local/virus/iptables/iptables.rule
[root@www ~]# iptables-save
-A INPUT -s 192.168.1.0/255.255.255.0 -p tcp -m tcp --dport 5900:5910 -j ACCEPT
# 要看得到上面這行才 OK 喔!

11.4.2 VNC 的用戶端連線軟體

與 xdmcp 很類似啦, VNC 用戶端在 Linux 系統上面有預設的軟體,但是在 Windows 系統上面則必須要額外安裝其他軟體。 我們先來談談 Linux 的 VNC 用戶軟體吧!

用在 Linux 用戶端的 VNC 程式,那就是 vncviewer。只是,這個軟體預設沒有安裝,所以你得要使用 yum 安裝完畢後再來連線吧!不過一樣要注意,伺服器端的防火牆一樣要設定妥當喔!然後開始在用戶端的圖形介面上執行底下資料:

[root@www ~]# yum install vnc
[root@www ~]# vncviewer 192.168.1.10:3
# 這個指令請一定一定要在圖形介面上面執行才行喔!很重要!別忘了!
在 Linux 用戶端執行 vncviewer 程序示意
圖 11.4-1、在 Linux 用戶端執行 vncviewer 程序示意

在上圖當中輸入剛剛的 root 的 VNC 連線密碼,請注意喔,是 VNC 的連線密碼,而不是 root 的登入密碼! 這兩者是差很多的!也由於啟動 VNC 的身份是 root ,因此這裡才使用 root 的 VNC 連線密碼。 所以,很多時刻,我們都是建議使用一般身份來啟動 VNC server 的啦!當你輸入正確的 VNC 連線密碼後, 會出現如下的圖示囉:

在 Linux 用戶端執行 vncviewer 程序示意
圖 11.4-2、在 Linux 用戶端執行 vncviewer 程序示意

你會發現在上圖中, VNC 的畫面真是醜啊!而且預設僅有一個終端機而已。這就是 twm 的醜醜畫面囉。 連線成功後,請在用戶端關閉這個 vncviewer 的連線,因為接下來我們要準備由 Windows 連線到伺服器的 port 5903 囉!

Windows 底下可用的 vnc client 軟體不少,但是鳥哥比較熟悉的是 realvnc 這家公司出品的 GNU 的自由軟體! 你可以在底下的連結下載到最簡單的版本,是不用錢的自由軟體版本喔!

請自行安裝它,裝好之後請由『開始』-->『程式集』-->『RealVNC』-->『VNC viewer 4』-->『Run VNC Viewer』,然後就會看到如下的畫面:

Windows Real VNC 用戶端連線示意圖
圖 11.4-3、Windows Real VNC 用戶端連線示意圖

如上圖所示,你在 server 欄位填上 IP:port 的資料即可,然後按下『OK』吧!

Windows Real VNC 用戶端連線示意圖
圖 11.4-4、Windows Real VNC 用戶端連線示意圖

由於 VNC server 需要的僅是連線的 VNC 密碼而已,因此上圖中的 Username 可以不用填,老實說,這個程式它也不會讓你填∼ 呵呵!填完按下『OK』即可!接下來就會出現正確的畫面囉!

Windows Real VNC 用戶端連線示意圖
圖 11.4-5、Windows Real VNC 用戶端連線示意圖

11.4.3 VNC 搭配本機的 Xdmcp 畫面

因為 VNC 預設的畫面是這麼的醜,而 xdmcp 才是這麼的漂亮,那麼有沒有辦法透過 VNC 連線來取得 xdmcp 畫面嗎? 可以的!那就直接在伺服器透過底下的指令來處理即可!要注意喔,你必須要已經啟動了 xdmcp 了喔! 而且,我們底下使用 student 的身份來啟動這個 VNC 吧!

# 1. 要確定 xdmcp 已經啟動了才可以:
[root@www ~]# netstat -tlunp | grep 177
udp        0      0 0.0.0.0:177   0.0.0.0:*      2901/gdm-binary
# OK 的!確實有啟動的啦!如果沒有看到 177 的話,回到 11.3 去處理處理

# 2. 切換成 student,並且啟動 VNC server 在 :5
[root@www ~]# su - student
[student@www ~]$ vncserver :5 -query localhost
You will require a password to access your desktops.

Password:
Verify:
xauth:  creating new authority file /home/student/.Xauthority
xauth: (stdin):1:  bad display name "www.centos.vbird:5" in "add" command

New 'www.centos.vbird:5 (student)' desktop is www.centos.vbird:5

Creating default startup script /home/student/.vnc/xstartup
Starting applications specified in /home/student/.vnc/xstartup
Log file is /home/student/.vnc/www.centos.vbird:5.log

# 3. 取消 xstartup 的啟動內容
[student@www ~]$ vim /home/student/.vnc/xstartup
#[ -x /etc/vnc/xstartup ] && exec /etc/vnc/xstartup
#[ -r $HOME/.Xresources ] && xrdb $HOME/.Xresources
#xsetroot -solid grey
#vncconfig -iconic &
#xterm -geometry 80x24+10+10 -ls -title "$VNCDESKTOP Desktop" &
#twm &
# 將這個檔案的內容,全部都加上 # 註解掉

# 4. 重新啟動 vncserver 喔!
[student@www ~]$ vncserver -kill :5
[student@www ~]$ vncserver :5 -query localhost

接下來請使用 root 的身份加入 5905 的埠口防火牆規則,然後自行使用 Linux 的 vncviewer 或 Windows 的 RealVNC 來連線,你就會發現如下的畫面:

透過 VNC 通道取得 xdmcp 畫面
圖 11.4-5、透過 VNC 通道取得 xdmcp 畫面

我們這隻 VNC 的連線程序是 student 身份,但是我們卻可以透過 xdmcp 的登入功能來登入 root 身份喔! 因為在伺服器上面的 Xvnc 程序是 student 擁有,這樣會比較好啦!瞭解呼?


11.4.4 開機就啟動 VNC server 的方法

請注意,你不要將 vncserver 的指令寫入在 /etc/rc.d/rc.local 中,否則可能會產生 localhost 無法登入的問題。 那該如何讓你的 VNC server 在一開機就啟動而不須要登入執行指令呢?可以的,但是你得要修改一下設定檔。 我們底下使用 student 的身份啟動 VNC server,而啟動的方式為使用 xdmcp 登入畫面,啟動的埠口就定在 5901 好了。 那你應該這樣作:

[root@www ~]# vim /etc/sysconfig/vncservers
VNCSERVERS="1:student"
VNCSERVERARGS[1]="-query localhost"
# 上述兩行的 1 指的就是那個埠口 5901 喔!要注意!

[root@www ~]# /etc/init.d/vncserver restart
[root@www ~]# chkconfig vncserver on

有夠好簡單吧!這樣每次開機就搞定你的 VNC server 囉!


11.4.5 同步的 VNC :可以透過圖示同步教學

另外,有些朋友一定會覺得奇怪,那就是,為甚麼我的 VNC 伺服器的 server / client 端畫面並不是同步的呢? 這是因為 Linux 本身提供多個 VNC server ,她們是各自獨立的,所以當然就不會與 tty7 的畫面同步了。 但是如果你想要與 Linux 的 tty7 同步的話,可以利用 VNC 釋出的給 X Server 使用的模組來加以設定即可。 如果你是 CentOS 5.x 這個 distribution 的話,恭喜你,系統預設已經將 vnc.so 這個模組釋出了。

那使用這個模組有甚麼好處啊?就是可以讓兩個圖形介面在 server/client 都是一樣的, 所以,如果你想要教你的朋友你是如何設定的,那就可以透過這個機制來處理,你的朋友在遠端就能夠知道你一步一步進行的過程! 這樣很不賴吧!詳細的作法可以參考底下的連結:

我們也來實做一下吧:

[root@www ~]# vim /etc/X11/xorg.conf
Section "Screen"
        Identifier "Screen0"
        Device     "Videocard0"
        DefaultDepth     24
        # VBird
        Option "passwordFile" "/home/student/.vnc/passwd"
        SubSection "Display"
                Viewport   0 0
                Depth     24
        EndSubSection
EndSection

# VBird
Section "Module"
    Load    "vnc"
EndSection
# 假設你的 vnc 密碼檔案放置在 /home/student/.vnc/passwd 裡頭,
# 這個時候就得要將密碼檔內容寫到 Screen 這個 section 當中了

[root@www ~]# gdm-restart
[root@www ~]# netstat -tlunp | grep X
tcp        0      0 0.0.0.0:5900   0.0.0.0:*      LISTEN      7445/Xorg
tcp        0      0 0.0.0.0:6000   0.0.0.0:*      LISTEN      7445/Xorg
tcp        0      0 :::6000        :::*           LISTEN      7445/Xorg
# 注意看喔!這幾個 port 啟動的 PID 都一樣喔!所以會啟動一個 port 5900 囉!

之後你可以使用『 vncviewer 192.168.1.10 』來連線即可,不需要加上 :0 之類的埠口。 然後你可以看一下用戶端與伺服器端的圖形介面,你會發現到兩者移動滑鼠時,兩者的畫面會同步運作喔! 非常有趣呢!只不過這個動作還是只允許一條 VNC 連線,不能讓所有用戶端都連到 port 5900 ,這真是太可惜了!


11.5 模擬的遠端桌面系統: XRDP 伺服器

使用上面的圖形介面的連線伺服器都有一個問題,除了連線機制的不同之外,上頭的 Xdmcp 與 VNC 原則上,資料都沒有加密。 因此上面的動作大多僅適合區域網路內運作,不要連上 Internet 比較好。那如果你真的想要透過加密的方式運作 VNC, 那可能得要透過下一小節的介紹才能夠有好的處理結果。那麼我們知道 Windows 的遠端桌面 (Remote Desktop Procotol, RDP, 註7) 其實是具有連線加密功能的,所以,能不能在 Linux 上面裝一個 RDP Server 呢?是可以的,那就是 XRDP 伺服器 (註8)。

很可惜的是,我們的 CentOS 5.x 預設並沒有提供 XRDP 的伺服器,如果你有興趣的話,可以自行編譯 xrdp 軟體, 但鳥哥有找到 Fedora 基金會提供的 RHEL 額外軟體計畫 (註9),你可以到底下的連結去找到你對應的版本:

鳥哥還是覺得 yum 是好東西,因此鳥哥找到的 CentOS 5.x i386 版本的網址後,將它設定在 yum 設定檔內,就可以使用 yum 安裝了:

[root@www ~]# vim /etc/yum.repos.d/fedora_epel.repo
[epel]
name=CentOS-$releasever - Epel
baseurl=http://download.fedora.redhat.com/pub/epel/5/i386/
gpgcheck=0
enabled=1

[root@www ~]# yum clean all
[root@www ~]# yum install xrdp

這樣就安裝好了 xrdp 軟體了,接著下來就得要開始來設定它囉!老實說,在一般的主機上面安裝好這個 xrdp 之後,你根本不需要調整任何設定檔,保留好設定檔就好了,然後啟動它,並且設定開機後啟動,未來只要用遠端連線連到這部主機, 系統就會啟動 5910~5920 以上的 VNC 埠口,然後你就能夠透過 RDP 的協定取得 VNC 的畫面,最後就能夠登入系統囉!

[root@www ~]# /etc/init.d/xrdp start
[root@www ~]# chkconfig xrdp on
[root@www ~]# netstat  | grep xrdp
tcp        0      0 127.0.0.1:3350  0.0.0.0:*     LISTEN    2606/xrdp-sesman
tcp        0      0 0.0.0.0:3389    0.0.0.0:*     LISTEN    2602/xrdp
# 遠端桌面的埠口是 3389 ,但是 xrdp 會再連到本機的 3350 去喚醒一個 VNC 的連線。
# 但是尚未連線之前,並不會起動任何的 VNC 埠口就是了。

如果你是使用 Windows 系統,那麼透過『開始』-->『程式集』-->『附屬應用程式』-->『遠端桌面連線』, 在出現的畫面中輸入這部 xrdp 伺服器的 IP 之後,如果順利連上就會出現如下的畫面:

連上伺服器的 XRDP 服務後,會出現的連線資訊
圖 11.5-1、連上伺服器的 XRDP 服務後,會出現的連線資訊

連上伺服器的 XRDP 服務後,會出現的連線資訊
圖 11.5-2、連上伺服器的 XRDP 服務後,會出現的連線資訊

輸入正確的帳號密碼,嘿嘿!搞定!畫面就出現囉!如果你還想要更進一步的瞭解 xrdp 的設定檔,那麼請到 /etc/xrdp/ 目錄底下瞧瞧,然後再透過 man 去看看相關的設定檔資訊,就能夠理解設定值囉!鳥哥測試過,不用修改任何設定, 使用遠端桌面就已經很順暢囉! ^_^

不過你要注意的是,因為 xrdp 最終會自動啟用 VNC ,因此你還是必須要安裝 vnc-server 才行! 否則 xrdp 應該還是無法運作的呦!


11.6 SSH 伺服器的進階應用

事實上 ssh 真的很好用!你甚至不需要啟動甚麼 xdmcp, vnc, xrdp 等等服務,使用 ssh 的加密通道就能夠在用戶端啟動圖形介面! 此外,我們知道很多服務都是沒有加密的,那麼能不能將這些服務透過 ssh 通道來加密呢?嘿嘿!當然是可以! 在這個章節當中,我們就來談談一些 ssh 的進階應用吧!


11.6.1 啟動 ssh 在非正規埠口 (非 port 22)

從前面的章節裡面我們就曾經提過, sshd 這個服務其實並不是很安全,所以很多 ISP 在入口處就已經將 port 22 關閉了!為什麼要這麼作呢?這是因為很多網站管理員並沒有定期的進行軟體 update ,而且為了方便,又很開心的將 port 22 對全世界開放。由於很多 cracker 會使用掃描程式亂掃整個 Internet 的埠口漏洞,這個 port 22 就是一個很常被掃描的埠口啦!為了杜絕這個問題,所以 ISP 先幫你把關,先將 port 22 關閉!這也是為了整個區網好!

只是,像鳥哥這種沒有 ssh 就快要活不下去的人,關閉了 port 22 那鳥哥的頭都痛了!沒有辦法工作啊! 那怎辦?沒關係,其實我們可以將 ssh 開放在非正規的埠口。如此一來, cracker 不會掃描到該埠口,而你的 ISP 又沒有對該埠口進行限制,那你就能夠使用 ssh 囉!很棒吧!那就來試看看。我們底下將 ssh 開放在 port 22 及 port 23 試看看 (請注意, port 23 不能夠有被使用喔!)。

[root@www ~]# vim /etc/ssh/sshd_config
Port 22
Port 23

[root@www ~]# /etc/init.d/sshd restart
[root@www ~]# netstat -tlunp | grep ssh
tcp        0      0 :::22        :::*         LISTEN      4254/sshd
tcp        0      0 :::23        :::*         LISTEN      4254/sshd

有沒有很簡單!這樣你就能夠使用 port 22 或 port 23 連線到你的 sshd 服務喔!

由於預設的 ssh, scp, sftp 都是連接到 port 22 的,那麼如何使用這些指令連線到 port 23 呢? 我們使用 ssh 當練習好了:

[root@www ~]# ssh -p 23 root@localhost
root@localhost's password:
Last login: Wed Feb 23 03:35:37 2011 from 192.168.1.171
[root@www ~]# netstat -tnp | grep 23
tcp  0  0 127.0.0.1:49109      127.0.0.1:23            ESTABLISHED 4290/ssh
tcp  0  0 ::ffff:127.0.0.1:23  ::ffff:127.0.0.1:49109  ESTABLISHED 4291/3
# 因為網路是雙向的,因此自己連自己 (localhost),就會抓到兩隻連線!

這樣,你就能夠避過一些 ISP 或者是 cracker 的掃描了!注意一下,不要將 port 開放在某些既知的埠口上, 例如你開放在 port 80 的話,那你就沒有辦法啟動正常的 WWW 服務啦!注意注意!


11.6.2 以 rsync 進行同步鏡像備份

我們曾在基礎篇第三版第二十五章裡頭談到 Linux 的備份策略, 該篇曾介紹常用的備份指令,包括 tar, dd, cp 等等,不過當時並未介紹網路,所以有個很棒的網路工具沒有介紹, 那就是這個地方要談到的 rsync 啦!這個 rsync 可以作為一個相當棒的異地備援系統的備份指令喔! 因為 rsync 可以達到類似『鏡相 (mirror) 』的功能呢!

rsync 最早是想要取代 rcp 這個指令的,因為 rsync 不但傳輸的速度快,而且他在傳輸時, 可以比對本地端與遠端主機欲複製的檔案內容,而僅複製兩端有差異的檔案而已,所以傳輸的時間就相對的降低很多! 此外, rsync 的傳輸方式至少可以透過三種方式來運作:

其實三種傳輸模式差異在於有沒有冒號 (:) 而已,本地端傳輸不需要冒號,透過 ssh 或 rsh 時,就得要利用一個冒號 (:), 如果是透過 rsync daemon 的話,就得要兩個冒號 (::) ,應該不難理解啦!因為本地端處理很簡單, 而我們的系統本來就有提供 ssh 的服務,所以,底下鳥哥將直接介紹利用 rsync 透過 ssh 來備份的動作喔。 不過,在此之前咱們先來看看 rsync 的語法吧!

[root@www ~]# rsync [-avrlptgoD] [-e ssh] [user@host:/dir] [/local/path]
選項與參數:
-v :觀察模式,可以列出更多的資訊,包括鏡像時的檔案檔名等;
-q :與 -v  相反,安靜模式,略過正常資訊,僅顯示錯誤訊息;
-r :遞迴複製!可以針對『目錄』來處理!很重要!
-u :僅更新 (update),若目標檔案較新,則保留新檔案不會覆蓋;
-l :複製連結檔的屬性,而非連結的目標原始檔案內容;
-p :複製時,連同屬性 (permission) 也保存不變!
-g :保存原始檔案的擁有群組;
-o :保存原始檔案的擁有人;
-D :保存原始檔案的裝置屬性 (device)
-t :保存原始檔案的時間參數;
-I :忽略更新時間 (mtime) 的屬性,檔案比對上會比較快速;
-z :在資料傳輸時,加上壓縮的參數!
-e :使用的通道協定,例如使用 ssh 通道,則 -e ssh
-a :相當於 -rlptgoD ,所以這個 -a 是最常用的參數了!
更多說明請參考 man rsync 的解說!

# 1. 將 /etc 的資料備份到 /tmp 底下:
[root@www ~]# rsync -av /etc /tmp
....(前面省略)....
sent 119500001 bytes  received 33260 bytes  6129910.82 bytes/sec
total size is 119372678  speedup is 1.00
[root@www ~]# ll -d /tmp/etc /etc
drwxr-xr-x 101 root root 12288  2月 23 03:55 /etc
drwxr-xr-x 101 root root 12288  2月 23 03:55 /tmp/etc <==瞧!兩個目錄一樣!
# 第一次運作時會花比較久的時間,因為首次建立嘛!如果再次備份呢?

[root@www ~]# rsync -av /etc /tmp
sent 61565 bytes  received 20 bytes  41056.67 bytes/sec
total size is 119372678  speedup is 1938.34
# 比較一下兩次 rsync 的傳輸與接受資料量,你就會發現立刻就跑完了!
# 傳輸的資料也很少!因為再次比對,僅有差異的檔案會被複製。

# 2. 利用 student 的身份登入 client.centos.vbird 後,將家目錄複製到本機 /tmp
[root@www ~]# rsync -av -e ssh student@192.168.1.20:~ /tmp 
student@192.168.1.20's password:  <==輸入對方主機的 student 密碼
receiving file list ... done
student/
student/.bash_logout
....(中間省略)....
sent 110 bytes  received 697 bytes  124.15 bytes/sec
total size is 333  speedup is 0.41

[root@www ~]# ll -d /tmp/student
drwx------ 3 student student 4096  2月 23 07:18 /tmp/student
# 瞧!這樣就做好備份啦!很簡單吧!

你可以利用上面的範例二來做為備份 script 的參考!不過要注意的是,因為 rsync 是透過 ssh 來傳輸資料的,所以你可以針對 student 這個傢伙製作出免用密碼登入的 ssh 金鑰! 如此一來往後異地備援系統就能夠自動的以 crontab 來進行備份了!簡單到爆!

免密碼的 ssh 帳號我們在上頭已經講過了,撰寫 shell script 的能力也是必須要有的!利用 rsync 來進行你的備份工作吧! ^_^!至於更多的 rsync 用法可以參考本章後面所列出的參考網站(註10)喔!

例題:
在 client.centos.vbird (192.168.1.20) 上面,使用 vbirdtsai 的身份建立一隻腳本,這隻腳本可以在每天的 2:00am 主動的以 rsync 配合 ssh 取得 www.centos.vbird (192.168.1.10) 的 /etc, /root, /home 三個目錄的鏡像到 client.centos.vbird 的 /backups/ 底下。
答:
由於必須要透過 ssh 通道,且必須要使用 crontab 例行工作排程,因此肯定要使用金鑰系統的免密碼帳號。我們在 11.2.6 小節已經談過相關作法, vbirdtsai 已經有了公鑰與私鑰檔案,因此不要再使用 ssh-keygen 了,直接將公鑰檔案複製到 www.centos.vbird 的 /root/.ssh/ 底下即可。 實際作法可以是這樣的:
# 1. 在 client.centos.vbird 將公鑰檔複製給 www.centos.vbird 的 root
[vbirdtsia@client ~]$ scp ~/.ssh/id_rsa.pub root@192.168.1.10:/root/

# 2. 在 www.centos.vbird 上面用 root 建置好 authorized_keys
[root@www ~]# ls -ld id_rsa.pub .ssh
-rw-r--r-- 1 root root  411  2月 23 07:34 id_rsa.pub <==有公鑰檔
drwx------ 2 root root 4096  2月 20 22:00 .ssh       <==有 ssh 設定目錄

[root@www ~]# cat id_rsa.pub >> ~/.ssh/authorized_keys
[root@www ~]# chmod 644 ~/.ssh/authorized_keys

# 3. 在 client.centos.vbird 上面撰寫 script 並測試執行:
[vbirdtsai@client ~]$ mkdir ~/bin ; vim ~/bin/backup_www.sh
#!/bin/bash
localdir=/backups
remotedir="/etc /root /home"
remoteip="192.168.1.128"

[ -d ${localdir} ] || mkdir ${localdir}
for dir in ${remotedir}
do
        rsync -av -e ssh root@${remoteip}:${dir} ${localdir}
done

[vbirdtsai@client ~]$ chmod 755 ~/bin/backup_www.sh
[vbirdtsai@client ~]$ ~/bin/backup_www.sh
# 上面在測試啦!第一次測試可能會失敗,因為鳥哥忘記 /backups 需要 root
# 的權限才能夠建立。所以,請您再以 root 的身份去 mkdir 及 chown 吧!

# 4. 建立 crontab 工作
[vbirdtsai@client ~]$ crontab -e
0 2 * * * /home/vbirdtsai/bin/backup_www.sh


11.6.3 透過 ssh 通道加密原本無加密的服務

現在我們知道 ssh 這個通道可以加密,而且,我們更知道 rsync 預設已經可以透過 ssh 通道來進行加密以進行鏡像傳輸。 既然如此,那麼其他的服務能不能透過這個 ssh 進行資料加密來傳送資訊呢?當然可以!很棒呢這個功能! 要介紹實做之前,我們先用圖示來談一下作法。

假設伺服器上面有啟動了 VNC 服務在 port 5901 ,用戶端則使用 vncviewer 要連線到伺服器上的 port 5901 就是了。 那現在我們在用戶端電腦上面啟動一個 5911 的埠口,然後再透過本地端的 ssh 連線到伺服器的 sshd 去,而伺服器的 sshd 再去連接伺服器的 VNC port 5901 。整個連線的圖示如下所示:

透過本地端的 ssh 加密連線到遠端的伺服器示意圖
圖 11.6-1、透過本地端的 ssh 加密連線到遠端的伺服器示意圖

假設你已經透過上述各個小節建立好伺服器 (www.centos.vbird) 上面的 VNC port 5901 ,而用戶端則沒有啟動任何的 VNC 埠口。 那麼你該如何透過 ssh 來進行加密呢?很簡單,你可以在用戶端電腦 (client.centos.vbird) 執行底下的指令:

[root@client ~]# ssh -L 本地埠口:127.0.0.1:遠端埠口 [-N] 遠端主機
選項與參數:
-N :僅啟動連線通道,不登入遠端 sshd 伺服器
本地埠口:就是開啟 127.0.0.1 上面一個監聽的埠口
遠端埠口:指定連線到後面遠端主機的 sshd 後,sshd 該連到哪個埠口進行傳輸

# 1. 在用戶端啟動所需要的埠口進行的指令
[root@client ~]# ssh -L 5911:127.0.0.1:5901 -N 192.168.1.10
root@192.168.1.10's password:
   <==沒有登入遠端,所以停止不能動作

# 2. 在用戶端在另一個終端機測試看看,這個動作不需要作,只是查閱而已
[root@client ~]# netstat -tnlp| grep ssh
tcp  0   0 127.0.0.1:5911       0.0.0.0:*            LISTEN      5441/ssh
tcp  0   0 :::22                :::*                 LISTEN      2075/sshd
tcp  0   0 ::1:5911             :::*                 LISTEN      5441/ssh
[root@client ~]# netstat -tnl| grep ssh
tcp  0   0 192.168.1.20:36740   192.168.1.10:22      ESTABLISHED 5441/ssh
# 在用戶端啟動 5911 的埠口是 ssh 啟動的,同一個 PID 也連線到遠端喔!

接下來你就可以在用戶端 (192.168.1.20, client.centos.vbird) 使用『 vncviewer localhost:5911 』來連線, 但是該連線卻會連到 www.centos.vbird (192.168.1.10) 那部主機的 port 5901 喔!不相信嗎? 當你達成 VNC 連線後,到 www.centos.vbird 那部主機上面瞧瞧就知道了:

# 3. 在伺服器端測試看看,這個動作不需要作,只是查閱而已
[root@www ~]# netstat -tnp | grep ssh
tcp   0  0 127.0.0.1:35030     127.0.0.1:5901      ESTABLISHED 6065/sshd: root
tcp   0  0 192.168.1.10:22     192.168.1.20:36740  ESTABLISHED 6065/sshd: root
# 明顯的看到 port 22 的程序同時連線到 port 5901 喔!

那如何取消這個連線呢?先關閉 VNC 之後,然後再將 client.centos.vbird 的第一個動作 (ssh -L ...) 按下 [ctrl]-c 就中斷這個加密通道囉!這樣會使用了嗎?你可以將這個動作用在任何服務上喔!


11.6.4 以 ssh 通道配合 X server 傳遞圖形介面

從前一個小節我們知道 ssh 可以進行程式的加密傳遞,亦即 ssh 通道啦!那麼可不可以用在 X 上面呢? 意思是說,那我能不能不要啟動甚麼很複雜的介面,就是在原有的介面底下使用 ssh 通道,將我所需要的伺服器上面的圖形介面傳過來就好了? 是可以的喔!鳥哥用一個 Windows 上面的 Xming X server 作範例好了。整個動作是這樣的:

那我們就開始來處理一下 Xming 這個程式吧!啟動 XLaunch 之後出現下圖模樣:

啟動 XLaunch 程式-選擇顯示模式
圖 11.6-2、啟動 XLaunch 程式-選擇顯示模式

記得上圖中要選擇 Multiple windows 會比較漂亮喔!然後按下『下一步』會出現下圖:

設定 XLaunch 程式-選擇連線方式
圖 11.6-3、設定 XLaunch 程式-選擇連線方式

我們要啟動一隻程式,並且是開放在 ssh/putty 之類的軟體幫忙進行 ssh 通道的建立喔!然後下一步吧。

設定 XLaunch 程式-設定遠端連線的相關參數
圖 11.6-4、設定 XLaunch 程式-設定遠端連線的相關參數

Xming 會主動的啟動一個 putty 的程序幫你連進 sshd 伺服器,所以這裡得要幫忙設定好帳號密碼的相關資訊。 鳥哥這裡假設你的 sshd 尚未取消 root 登入,因此這裡使用 root 的權限喔!

設定 XLaunch 程式-是否支援複製貼上功能
圖 11.6-5、設定 XLaunch 程式-是否支援複製貼上功能

使用預設值吧!直接下一步。

設定 XLaunch 程式-完成設定
圖 11.6-6、設定 XLaunch 程式-完成設定

很簡單!這樣就完成設定了!請按下完成,你就會看到 Windows 的桌面竟然出現如下的圖示了!

Windows 桌面出現的 X client 程式
圖 11.6-7、Windows 桌面出現的 X client 程式

上面這隻程式就是 xterm 這個 X 的終端機程式。你可以在上面輸入指令,該指令會傳送到 Linux server , 然後再將你要執行的圖形資料透過 ssh 通道傳送到目前的 Windows 上面的 Xming ,你的 Linux 完全不用啟動 VNC, X, xrdp 等服務!只要有 sshd 就搞定了!就是這麼簡單!例如鳥哥輸入幾個遊戲程式, 你的 Windows 視窗 (看工作列就知道了) 就會出現這樣的情況:

Windows 桌面出現的 X client 程式
圖 11.6-8、Windows 桌面出現的 X client 程式

重點回顧

本章習題

參考資料與延伸閱讀

2002/11/14:第一次完成
2003/03/08:加入標頭說明,與修改部分內容,例如 Telnet 伺服器軟體的安裝等等,以及 SSH 的 putty 使用中文狀態!
2003/09/09:將本文進行一些修訂,此外,加入了課後練習!
2005/07/02:將舊的文章移動到 這裡
2005/07/07:好不容易將 VNC 還有 XDMCP 給他寫了寫∼大家幫鳥哥參考看看啊∼
2005/07/09:加入了讓 VNC 與 tty7 同步的 vnc.so 模組的說明
2005/11/22:加入了 RSH 伺服器 的相關資料!
2006/09/18:將 putty 的介紹轉成 pietty 的介紹!因為 pietty 更好用!另外也將 rsh 重新改寫一下,校稿過!
2006/09/19:加入 rsync 的簡易說明與操作!最文末的習題可以瞧一瞧!
2011/02/15:將舊的基於 CentOS 4.x 的文章移動到 此處
2011/02/17:忍痛刪除 telnet 伺服器,畢竟真的很少用了∼包括那個 rsh 也不再介紹!有興趣的請參考 CentOS 4.x 的舊文章吧
2011/02/20:將 sshd 伺服器作個簡單的修改了,增加一些篇幅來說明相關例題與實做,尤其是 ~/.ssh/authorized_keys 的權限
2011/02/23:修改了許多 Xdmcp, VNC 的設定與圖示,最重要是加入 xrdp 的安裝與使用
2011/02/24:加入 Xming 透過 X11 forward from ssh 的方式!