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

通過第一篇的鍛鍊之後,現在你應該已經利用 Linux 連上 Internet 了。但是你的 Linux 現在恐怕還是不怎麼安全的。 因此,在開始伺服器設定之前,我們必須要讓你的系統強壯些!以避免被惡意的 cracker 所攻擊啊!在這一章當中, 我們會介紹封包的流向,然後根據該流向來制訂系統強化的流程!包括線上自動升級、服務管控以及 SELinux 等等。現在就來瞭解瞭解囉!

7.1 網路封包連線進入主機的流程
  7.1.1 封包進入主機的流程
  7.1.2 常見的攻擊手法與相關保護猜密碼, 漏洞, 社交工程, 程式誤用, rootkit, DDoS
  7.1.3 主機能作的保護:軟體更新、減少網路服務、啟動 SELinux
7.2 網路自動升級軟體
  7.2.1 如何進行軟體升級
  7.2.2 CentOS 的 yum 軟體更新、映射站使用的原理
  7.2.3 yum 的使用安裝, 軟體群組, 全系統更新
  7.2.4 挑選特定的映射站:修改 yum 設定檔與清除 yum 快取
7.3 限制連線埠口 (port)
  7.3.1 什麼是 port
  7.3.2 埠口的觀察netstat, nmap
  7.3.3 埠口與服務的啟動/關閉及開機時狀態設定服務類型, 開機啟動
  7.3.4 安全性考量-關閉網路服務埠口
7.4 SELinux 管理原則
  7.4.1 SELinux 的運作模式安全性本文, domain/type
  7.4.2 SELinux 的啟動、關閉與觀察getenforce, setenforce
  7.4.3 SELinux type 的修改chcon, restorecon, semanage
  7.4.4 SELinux 政策內的規則布林值修訂seinfo, sesearch, getsebool, setsebool
  7.4.5 SELinux 登錄檔記錄所需服務-以 httpd 為範例: setroubleshoot, sealert
7.5 被攻擊後的主機修復工作
  7.5.1 網管人員應具備的技能
  7.5.2 主機受攻擊後復原工作流程
7.6 重點回顧
7.7 本章習題
7.8 參考資料與延伸閱讀
7.9 針對本文的建議:http://phorum.vbird.org/viewtopic.php?p=114062

7.1 網路封包連線進入主機的流程

在這一章當中,我們要討論的是,當來自一個網路上的連線要求想進入我們的主機時, 這個網路封包在進入主機實際取得資料的整個流程是如何?瞭解了整個流程之後, 你才會發現:原來系統操作的基本概念是如此的重要! 而你也才會瞭解要如何保護你的主機安全吶!閒話少說,咱們趕緊來瞧一瞧先。


7.1.1 封包進入主機的流程

第一章我們就談過網路連線的流程, 當時舉的例子是希望你可以理解為啥架設伺服器需要瞭解作業系統的基本觀念。在這一章當中,我們要將該流程更細緻化說明, 因為,透過這個流程分析,你會知道為啥我們的主機需要進行過一些防護之後,系統才能夠比較強壯。此外,透過第二章的網路概念解釋後,你也瞭解了網路是雙向的,伺服器與用戶端都得要有 IP:port 才能夠讓彼此的軟體互相溝通。那麼現在,假設你的主機是 WWW 伺服器,透過底下的圖示,網路封包如何進入你的主機呢?

網路封包進入主機的流程
圖 7.1-1、網路封包進入主機的流程
  1. 經過防火牆的分析:

    Linux 系統有內建的防火牆機制,因此你的連線能不能成功,得要先看防火牆的臉色才行。預設的 Linux 防火牆就有兩個機制,這兩個機制都是獨立存在的,因此我們預設就有兩層防火牆喔。第一層是封包過濾式的 netfilter 防火牆, 另一個則是透過軟體控管的 TCP Wrappers 防火牆。

    • 封包過濾防火牆:IP Filtering 或 Net Filter
      要進入 Linux 本機的封包都會先通過 Linux 核心的預設防火牆,就是稱為 netfilter 的咚咚,簡單的說,就是 iptables 這個軟體所提供的防火牆功能。為何稱為封包過濾呢?因為他主要是分析 TCP/IP 的封包表頭來進行過濾的機制,主要分析的是 OSI 的第二、三、四層,主要控制的就是 MAC, IP, ICMP, TCP 與 UDP 的埠口與狀態 (SYN, ACK...) 等。詳細的資料我們會在防火牆章節中介紹。

    • 第二層防火牆:TCP Wrappers
      通過 netfilter 之後,網路封包會開始接受 Super daemonsTCP_Wrappers 的檢驗,那個是什麼呢? 說穿了就是 /etc/hosts.allow 與 /etc/hosts.deny 的設定檔功能囉。 這個功能也是針對 TCP 的 Header 進行再次的分析,同樣你可以設定一些機制來抵制某些 IP 或 Port ,好讓來源端的封包被丟棄或通過檢驗;

    透過防火牆的管控,我們可以將大部分來自網際網路的垃圾連線丟棄,只允許自己開放的服務的連線進入本機而已, 可以達到最基礎的安全防護。

  2. 服務 (daemon) 的基本功能:

    預設的防火牆是 Linux 的內建功能,但防火牆主要管理的是 MAC, IP, Port 等封包表頭方面的資訊,如果想要控管某些目錄可以進入, 某些目錄則無法使用的功能,那就得要透過權限以及伺服器軟體提供的相關功能了。舉例來說,你可以在 httpd.conf 這個設定檔之內規範某些 IP 來源不能使用 httpd 這個服務來取得主機的資料, 那麼即使該 IP 通過前面兩層的過濾,他依舊無法取得主機的資源喔!但要注意的是, 如果 httpd 這支程式本來就有問題的話,那麼 client 端將可直接利用 httpd 軟體的漏洞來入侵主機,而不需要取得主機內 root 的密碼!因此, 要小心這些啟動在網際網路上面的軟體喔!

  3. SELinux 對網路服務的細部權限控制:

    為了避免前面一個步驟的權限誤用,或者是程序有問題所造成的資安狀況,因此 Security Enhanced Linux (安全強化 Linux) 就來發揮它的功能啦!簡單的說,SELinux 可以針對網路服務的權限來設定一些規則 (policy) ,讓程序能夠進行的功能有限, 因此即使使用者的檔案權限設定錯誤,以及程序有問題時,該程序能夠進行的動作還是被限制的,即使該程序使用的是 root 的權限也一樣。舉例來說,前一個步驟的 httpd 真的被 cracker 攻擊而讓對方取得 root 的使用權,由於 httpd 已經被 SELinux 控制在 /var/www/html 裡面,且能夠進行的功能已經被規範住了,因此 cracker 就無法使用該程序來進行系統的進一步破壞囉。現在這個 SELinux 一定要開啟喔!

  4. 使用主機的檔案系統資源:

    想一想,你使用瀏覽器連接到 WWW 主機最主要的目的是什麼?當然就是讀取主機的 WWW 資料啦! 那 WWW 資料是啥?就是檔案啊!^_^!所以,最終網路封包其實是要向主機要求檔案系統的資料啦。 我們這裡假設你要使用 httpd 這支程式來取得系統的檔案資料,但 httpd 預設是由一個系統帳號名稱為 httpd 來啟動的,所以:你的網頁資料的權限當然就是要讓 httpd 這支程式可以讀取才行啊!如果你前面三關的設定都 OK ,最終權限設定錯誤,使用者依舊無法瀏覽你的網頁資料的。

在這些步驟之外,我們的 Linux 以及相關的軟體都可能還會支援登錄檔記錄的功能,為了記錄歷史歷程, 以方便管理者在未來的錯誤查詢與入侵偵測,良好的分析登錄檔的習慣是一定要建立的,尤其是 /var/log/messages 與 /var/log/secure 這些個檔案!雖然各大主要 Linux distribution 大多有推出適合他們自己的登錄檔分析軟體,例如 CentOS 的 logwatch ,不過畢竟該軟體並不見得適合所有的 distributions ,所以鳥哥嘗試自己寫了一個 logfile.sh 的 shell script,你可以在底下的網址下載該程式:

好了,那麼根據這些流程,你覺得 cracker 這些個壞蛋能夠怎樣的攻擊我們的系統呢?得要先到對方想要怎麼破壞, 我們才能夠想辦法來補強系統嘛!底下先講講基本的攻擊手法囉。


7.1.2 常見的攻擊手法與相關保護

我們由圖 7.1-1 瞭解到資料傳送到本機時所需要經過的幾道防線後,那個權限是最後的關鍵啦! 現在你應該比較清楚為何我們常常在基礎篇裡面一直談到設定正確的權限可以保護你的主機了吧? 那麼 cracker 是如何透過上述的流程還能夠攻擊你的系統啊?底下就讓我們來分析分析。


















7.1.3 主機能作的保護: 軟體更新、減少網路服務、啟動 SELinux

根據本章前面的分析,現在你知道封包的流向以及主機基本需要進行的防護了。不過你或許還是有疑慮,那就是, 既然我都已經有了防火牆,那麼權限的控管啦、密碼的嚴密性啦、伺服器軟體的更新啦、SELinux 啦等等的, 是否就沒有這麼重要呢?畢竟它是封包進入的第一關卡!這關把關嚴格,後續可以稍微寬鬆嗎?其實...你錯了! 對於開放某些服務的伺服器來說,你的防火牆『根本跟屁一樣,是沒有用的!』怎麼說呢?






根據這樣的分析,我們可以知道,隨時更新系統軟體、限制連線埠口以及透過啟動 SELinux 來限制網路服務的權限,經過這三個簡單的步驟,你的系統將可以獲得相當大的保護!當然啦, 後續的防火牆以及系統登錄檔分析工作仍是需要進行的。本章後續將依據這三點來深入介紹。


7.2 網路自動升級軟體

在現在的網際網路上面,cracker 實在是太多了!這些閒人會利用已經存在的系統漏洞,來進行偵測、入侵你的主機。 因此,除了未來架設防火牆之外,最重要的 Linux 日常管理工作,莫過於軟體的升級了! 不過,如果使用者還得要自己每天觀察網路安全通報,並主動去查詢各大 distribution 針對這些漏洞來提供升級軟體包, 那真是太不人性化了!因此,目前就有很多線上直接更新的機制出現了!有了這些線上直接更新軟體的手段與方法, 我們系統管理員在管理主機系統上面,可就輕鬆的多囉!


7.2.1 如何進行軟體升級

通常鳥哥安裝好 Linux 之後,會先開啟系統預設的防火牆機制,然後第一件事情就是進行全系統更新啦! 不論是哪一套 Linux 鳥哥都是這樣做的,因為要避免軟體資安的問題嘛!好了,那麼 Linux 上面的軟體該如何進行更新與升級呢? 還記得你是如何安裝軟體的嗎?不就是 rpm, tarball 與 dpkg 嗎? 所以囉,你的軟體如果想要升級,那就得依據當時你安裝該軟體的方式來進行升級啊!而每種方式都有其適用性:

舉例來說,如果你的系統是 CentOS ,我們知道他使用的是 RPM 類型的軟體管理模式,那如果你想要安裝 B2D 的軟體怎辦?要注意, B2D 是使用 debian 的 dpkg 來管理軟體的,兩者並不相同啊!要互相安裝太難了! 所以說,要升級的話,得先瞭解到你系統上的軟體安裝與管理的方法才行。

不過,有個特殊案例,那就是舊版本的 Linux (例如 Red Hat 9) 的軟體升級該如何是好? 由於舊版本的軟體支援度本來就比較差,商業公司或者是社群也沒有這麼多心力放在舊版本的支援上, 所以,你這個時候可以選擇: (1)升級到較新的版本,例如 CentOS 5.x,或者是 (2)利用 Tarball 來自行升級核心與軟體。不過,比較建議升級到新版本啦,因為要自行以手動方式由 Tarball 安裝到最新的版本,實在是很費時費力,而且還得要常常查閱官方網站所推出的最新消息, 漏過一則都可能發生無法預期的狀況。

我們都曉得在 Windows 的環境下,他有提供一個 Live update 的項目可以自動的線上升級, 甚至很多的防毒軟體與防木馬軟體也都有推出即時的線上更新,如此一來可以讓您的軟體維持在最新版的狀況, 真是好啊!咦!那我們的 Linux 是否有這樣的功能?如果有的話,那麼系統自動進行軟體升級, 不就可以輕鬆又快樂了?沒錯!確實是這樣的!所以就讓我們來談一談 Linux 的線上升級機制吧!

在 Linux 最常見的軟體安裝方式: RPM / Tarball / dpkg 當中,Tarball 由於取得的是原始碼, 所以要用 Tarball 來作線上自動更新是不太可能進行的,所以僅能用 RPM 或 dpkg 這兩種軟體管理的方式來進行線上更新了。

但 RPM 與 dpkg 不是有所謂的相依屬性嗎?這倒不需要擔心吶!因為我們的 RPM 與 dpkg 軟體檔案都有一些軟體的基本資訊, 並同時記錄了軟體的相依屬性 (記得使用 rpm -q 的查詢嗎),所以當分析這些基本資訊並使用一些機制將這些相依資訊記錄下來後, 再透過一些額外的網路功能,就能夠自動的分析你的系統與修補軟體之間的差異, 並可進一步幫你分析所需要升級與相依屬性的軟體,就可達成自動升級的理想啦!

由於各家 distributions 在管理系統上都有自己獨特的想法,所以在分析 RPM 或 dpkg 軟體與方式上面就有所不同, 也就有底下這些不同的線上升級機制啦:

講了這些升級機制並且與 distribution 作了對應,你就該瞭解到:『每個 distribution 可以使用的線上升級機制都不相同』的啊!所以請參考你的 distribution 所提供的文件來進行線上升級的設定喔!否則就得要自行手動下載安裝了! @_@

鳥哥這裡都是使用 CentOS 這個 Red Hat 相容的 distributions 來介紹的,因此,底下僅介紹了 yum 而已。 不過,yum 已經能夠適用於 CentOS, Red Hat Enterprise Linux, Fedora 等等,也應該是挺夠用的了! 另外,基礎篇裡面已經談過 rpm 與 yum 的用法,所以在這裡僅是加強介紹與更新有關的用法而已喔!


7.2.2 CentOS 的 yum 軟體更新、映射站使用的原理

我們曾經在基礎篇裡面談過 yum 了,基本上他的原理是,我們的 CentOS 會跑到 yum 伺服器上頭,下載了官方網站釋出的 RPM 表頭清單資料,該資料除了記載每個 RPM 軟體的相依性之外,也說明了 RPM 檔案所放置的容器 (repository) 所在。因此透過分析這些資料,我們的 CentOS 就能夠直接使用 yum 去下載與安裝所需要的軟體了! 詳細圖示與流程有點像這樣:

使用 yum 下載清單表頭與取得容器相關資料示意圖
圖 7.2-1、使用 yum 下載清單表頭與取得容器相關資料示意圖
  1. 先由設定檔判斷 yum server 所在 IP 位址;
  2. 連接到 yum server 後,先下載新的 RPM 檔案的表頭資料;
  3. 分析比較使用者所欲安裝/升級的檔案,並提供使用者確認;
  4. 下載使用者選擇的檔案到系統中的 /var/cache/yum ,並進行實際安裝;

由於你所下載的清單當中已經含有所有官方網站所釋出的 RPM 檔案的表頭相依屬性的關係, 所以如果你想要安裝的軟體包含某些尚未安裝的相依軟體時,我們的 yum 會順便幫你下載所需要的其他軟體,預先安裝後, 再安裝你所實際需要的軟體!從分析、下載到安裝,全部一口氣搞定!很簡單的啦!

不過,恐怕還是有問題。如果全世界使用 CentOS 的朋友通通連線到同一部 Yum 伺服器去下載所需要的 RPM 檔案,哇! 那頻寬不就很容易被塞爆!那怎辦?沒關係,有所謂的映射站啊! CentOS 在世界各地都有映射站,這些映射站會將官網的 yum 伺服器的資料複製一份,同時在映射站上面也提供同樣的 yum 功能,因此,你可以在任何一部 yum 伺服器的映射站上面下載與安裝軟體。底下是 CentOS 官網上面列出的亞洲地區映射站一覽表:

現在的 yum 又很聰明,它會自動的去分析離你的主機最近的那部映射站,然後直接使用該部映射主機作為你的 yum 來源, 因此,『理論上』你不需要更動任何設定,在台灣,你的 CentOS 就會使用台灣地區的 yum 伺服器囉!就這麼簡單! 所以,接下來就讓我們直接來談談怎麼使用 yum 吧!

yum 的原理與相關使用,我們在基礎篇裡面已經分門別類的介紹過了,因此底下僅就比較重要的部分介紹一下囉!

7.2.3 yum 的使用: 安裝, 軟體群組, 全系統更新

yum 可不止能夠線上自動升級而已,他還可以作查詢、軟體群組的安裝、整體版本的升級等等,好用的哩! 先來談論一下 yum 這個指令的用法吧:

[root@www ~]# yum [option] [查詢的工作項目] [相關參數]
選項與參數:
option:主要的參數,包括有:
   -y :當 yum 詢問使用者的意見時,主動回答 yes 而不需要由鍵盤輸入;

[查詢的工作項目]:由於不同的使用條件,而有一些選擇的項目,包括:
   install :指定安裝的軟體名稱,所以後面需接『 軟體名稱 』
   update  :進行整體升級的行為;當然也可以接某個軟體,僅升級一個軟體;
   remove  :移除某個軟體,後面需接軟體名稱;
   search  :搜尋某個軟體或者是重要關鍵字;
   list    :列出目前 yum 所管理的所有的軟體名稱與版本,有點類似 rpm -qa;
   info    :同上,不過有點類似 rpm -qai 的執行結果;
   clean   :下載的檔案被放到 /var/cache/yum ,可使用 clean 將他移除,
             可清除的項目:packages | headers | metadata | cache 等;

在[查詢的工作項目]部分還可以具有整個群組軟體的安裝方式,如下所示:
   grouplist   :列出所有可使用的『軟體群組』,例如 Development Tools 之類的;
   groupinfo   :後面接 group_name,則可瞭解該 group 內含的所有軟體名;
   groupinstall:這個好用!可以安裝一整組的軟體群組,相當的不錯用!
                 更常與 --installroot=/some/path 共用來安裝新系統
   groupremove :移除某個軟體群組;

# 範例一:搜尋 CentOS 官網提供的軟體名稱是否有與 RAID 有關的?
[root@www ~]# yum search raid
Loaded plugins: fastestmirror
Determining fastest mirrors     <==這裡就是在測試最快的映射站
 * addons: ftp.twaren.net       <==共有四個容器內容
 * base: ftp.twaren.net         <==每個容器都在 ftp.twaren.net 上
 * extras: ftp.twaren.net
 * updates: ftp.twaren.net
addons                          |  951 B     00:00    <==下載軟體的表頭清單中
base                            | 2.1 kB     00:00
extras                          | 2.1 kB     00:00
extras/primary_db               | 187 kB     00:00
updates                         | 1.9 kB     00:00
=============== Matched: raid ======================  <==找到的結果如下
....(中間省略)....
lvm2.i386 : 圖形化的邏輯卷冊管理工具
mdadm.i386 : mdadm 控制 Linux md 裝置(軟體 RAID 陣列)
mkinitrd.i386 : 建立預載模組所需的初始 ramdisk 映像檔。

# 範例二:上述輸出結果中, mdadm 的功能為何?
[root@www ~]# yum info mdadm
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
 * addons: ftp.twaren.net
 * base: ftp.twaren.net
 * extras: ftp.twaren.net
 * updates: ftp.twaren.net
Installed Packages  <==這裡說明這是已經安裝的軟體!
Name       : mdadm
Arch       : i386
Version    : 2.6.9
Release    : 3.el5
Size       : 1.8 M
Repo       : installed
Summary    : mdadm 控制 Linux md 裝置(軟體 RAID 陣列)
URL        : http://www.kernel.org/pub/linux/utils/raid/mdadm/
License    : GPL
....(底下省略)....

yum 真是個很好用的東西,它可以直接查詢是否有某些特殊的軟體名稱。舉例來說,你可以利用底下的兩個方式取得軟體名稱:

然後再以正規表示法取得關鍵字,或者是『 yum list "軟體名稱" 』就能夠知道該軟體的用途,最後再決定要不要安裝啊!上面的範例一就是在找出磁碟陣列的管理軟體。 如果確定要安裝時,那就參考參考底下的流程吧!


# 範例三:安裝某個軟體吧!以 mdadm 這個軟體名為例:
[root@www ~]# yum install mdadm
....(前面省略)....
Setting up Install Process
Package mdadm-2.6.9-3.el5.i386 already installed and latest version
Nothing to do

[root@www ~]# yum install mdadma
Setting up Install Process
No package mdadma available.
Nothing to do

仔細的看上述的兩個指令,第二個指令鳥哥故意寫錯字,讓軟體名稱由 mdadm 變成 mdadma 了!模擬同學如果打錯字時所輸出的訊息。由上述的訊息你可以知道,同樣結果是『Nothing to do』,但是 yum 會告訴你該軟體是『已安裝 (installed and lastest version)』還是『沒有該軟體 (No package mdadma avaliable)』。作這個範例是希望朋友們能夠仔細的看輸出的訊息啦!好啦!我們還是來安裝一個不曾裝過的, 就拿 javacc 這套軟體來裝看看好了!

[root@www ~]# yum list javacc*
Available Packages
javacc.i386             4.0-3jpp.3       base
javacc-demo.i386        4.0-3jpp.3       base
javacc-manual.i386      4.0-3jpp.3       base
# 共有三套軟體,分別是 javacc, javacc-demo, javacc-manual ,版本為 4.0-3jpp.3,
# 軟體是放置到名稱為 base 的容器當中存放的。

[root@www ~]# yum install javacc
....(前面省略)....
Setting up Install Process
Resolving Dependencies
--> Running transaction check  <==開始檢查有沒有相依屬性的軟體問題
---> Package javacc.i386 0:4.0-3jpp.3 set to be updated
--> Finished Dependency Resolution

Dependencies Resolved

=======================================================
 Package     Arch      Version         Repository Size
=======================================================
Installing:
 javacc      i386      4.0-3jpp.3      base      850 k

Transaction Summary
=======================================================
Install       1 Package(s)  <==安裝軟體彙整,共安裝 1 個,升級 0 個軟體
Upgrade       0 Package(s)

Total download size: 850 k
Is this ok [y/N]: y
Downloading Packages:
javacc-4.0-3jpp.3.i386.rpm      | 850 kB     00:00
Running rpm_check_debug
Running Transaction Test
Finished Transaction Test
Transaction Test Succeeded
Running Transaction
  Installing     : javacc                          1/1

Installed:
  javacc.i386 0:4.0-3jpp.3

Complete!

瞧!經過 yum 我們可以很輕鬆的就安裝好一個軟體,並且這個軟體已經主動的幫我們做好相依屬性的克服了, 真是方便到爆!另外,CentOS 5.x 預設的情況下,yum 下載的資料除了每個容器的表頭清單檔案之外,所有下載的 RPM 檔案都會在安裝完畢之後予以刪除! 這樣你的系統就不會有容量被下載的資料塞爆的問題。但如果你想要下載的 RPM 檔案繼續保留在 /var/cache/yum 當中,就得要修改 /etc/yum.conf 設定檔了!

[root@www ~]# vim /etc/yum.conf
[main]
cachedir=/var/cache/yum
keepcache=1
debuglevel=2
logfile=/var/log/yum.log
distroverpkg=redhat-release
tolerant=1
exactarch=1
obsoletes=1
gpgcheck=1
plugins=1

上述的特殊字體地方將 0 改成 1 ,這樣就能夠讓你的 RPM 檔案保存下來。不過,除非你有好多部主機要更新, 你想利用一台先 yum 升級且下載,然後將所有的 RPM 檔案收集起來給內網的機器升級 (rpm -Fvh *.rpm) 之外, 上面的 vim 修改動作不建議修改!因為你的 /var 恐怕會被塞爆啊!再次提醒!


什麼是『軟體群組』呢?由於 RPM 軟體將一個大專案分成好幾個小計畫來執行,每個小計畫都可以獨立安裝, 這樣的好處是可以讓使用者與軟體發展者安裝不同的環境!舉例來說,我們使用 KDE 桌面,就是一般用戶的使用而已, 並沒有需要在 Linux 底下安裝 KDE 的發展工具組吧?而 KDE 專案計畫將軟體分成一般使用環境 "KDE (K Desktop Environment)" 及發展者 "KDE Software Development" 環境,每個軟體群組內又含有多個不同的 RPM 軟體檔案! 這樣做的用途是方便使用者安裝一整套的專案啦!

那麼系統有多少軟體群組呢?又該如何觀察某個軟體群組有擁有的 RPM 檔案呢?我們就利用 KDE 這個專案來說明一下囉:

# 範例四:查詢系統有的軟體群組有多少個?
[root@www ~]# LANG=C yum grouplist
Installed Groups:             <==這個是已安裝的軟體群組
   Administration Tools
   DNS Name Server
   Dialup Networking Support
   Editors
   FTP Server
....(中間省略)....
Available Groups:             <==這個是尚可安裝的軟體群組
   Authoring and Publishing
   Base
   Beagle
   Cluster Storage
....(中間省略)....
   KDE (K Desktop Environment)
   KDE Software Development
....(後面省略)....

# 範例五:那麼 KDE (K Desktop Environment) 內含多少個 RPM 軟體呢?
[root@www ~]# yum groupinfo "KDE (K Desktop Environment)"
Group: KDE 桌面環境
 Description: KDE 是個功能強大的圖形使用者介面,它含有面板、桌面、系統圖示 
              以及圖形檔案管理員。
 Mandatory Packages:
   arts
   kdebase
 Default Packages:    <==主要的會被安裝的軟體有這些
   desktop-printing
   im-chooser
   kdeaccessibility
   kdeaddons
....(中間省略)....
 Optional Packages:   <==此外你尚可挑選的軟體有這些
   kdeadmin
# 如果你確定要安裝這個軟體群組的話,那就這樣做:

[root@www ~]# yum groupinstall "KDE (K Desktop Environment)"

利用這個『 yum groupinstall "軟體群組名" 』可以讓你一口氣安裝很多的軟體, 而不必擔心某個軟體忘記裝了!實在是很不錯啦∼而且利用 groupinfo 的功能你也可以發現一些不錯的軟體資料, 如此一來,你就可以更方便的管理你的 Linux 系統了,很不錯吧!


我們都知道使用『yum update』就可以進行軟體的更新。不過你曉得嗎? yum update 也可以直接進行同一版本的升級喔!舉例來說,你可以從 5.5 升級到 5.6 版本哩!而且中間過程完全無痛呦! 就跟一般軟體升級而已,並沒有不同呦!夠愉快吧!

不過,如果你是想要從較舊版的 CentOS 4.x 升級到 5.x 的話,那麼可能就得要多費些功夫了。為啥不要重灌比較快呢?因為你可能已經有些資料設定好,所以不想變更嘛! 但老實說,不同版本 (ex> 4.x --> 5.x) 間的升級最好還是不要嘗試啦!重新安裝可能是最好的狀況。 底下列出酷學園的前輩提供的升級方式,以及 CentOS 官網直接提供的升級方式給你參考參考:

例題:
請設定一下工作排程,讓你的 centOS 可以每天自動更新系統
答:
可以使用『 crontab -e 』來動作,也可以編輯『 vim /etc/crontab 』來動作, 由於這個更新是系統方面的,所以鳥哥習慣使用 vim /etc/crontab 來進行指令的說明。 其實內容很簡單:
40 5 * * * root yum -y update && yum clean packages
這樣就可以自動更新了, 時間訂在每天的凌晨 5:40 。


7.2.4 挑選特定的映射站:修改 yum 設定檔與清除 yum 快取

雖然 yum 是你的主機能夠連線上 Internet 就可以直接使用的,不過,由於 CentOS 的映射站台可能會選錯, 舉例來說,我們在台灣,但是 CentOS 的映射站台卻選擇到了大陸北京或者是日本去,有沒有可能發生啊! 有啊!鳥哥教學方面就常常發生這樣的問題,要知道,我們連線到大陸或日本的速度是非常慢的呢!那怎辦? 當然就是手動的修改一下 yum 的設定檔就好囉!

在台灣,鳥哥熟悉的 CentOS 映射站台主要有高速網路中心與義首大學,鳥哥近來比較偏好高速網路中心, 似乎更新的速度比較快,而且連接台灣學術網路也非常快速哩!因此,鳥哥底下建議台灣的朋友使用高速網路中心的 ftp 主機資源來作為 yum 伺服器來源喔!目前高速網路中心對於 CentOS 所提供的相關網址如下:

如果你連接到上述的網址後,就會發現裡面有一堆連結,那些連結就是這個 yum 伺服器所提供的容器了! 所以高速網路中心也提供了 addons, centosplus, extras, fasttrack, os, updates 等容器,最好認的容器就是 os (系統預設的軟體) 與 updates (軟體升級版本) 囉!由於鳥哥在我的測試用主機是利用 i386 的版本, 因此那個 os 再點進去就會得到如下的可提供安裝的網址:

為什麼在上述的網址內呢?有什麼特色!最重要的特色就是那個『 repodata 』的目錄!該目錄就是分析 RPM 軟體後所產生的軟體屬性相依資料放置處!因此,當你要找容器所在網址時, 最重要的就是該網址底下一定要有個名為 repodata 的目錄存在!那就是容器的網址了! 其他的容器正確網址,就請各位看倌自行尋找一下喔!現在讓我們修改設定檔吧!

[root@www ~]# vim /etc/yum.repos.d/CentOS-Base.repo
[base]
name=CentOS-$releasever - Base
mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=os
#baseurl=http://mirror.centos.org/centos/$releasever/os/$basearch/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-5

如上所示,鳥哥僅列出 base 這個容器內容而已,其他的容器內容請自行查閱囉!上面的資料需要注意的是:

瞭解這個設定檔之後,接下來讓我們修改整個檔案的內容,讓我們這部主機可以直接使用高速網路中心的資源吧! 修改的方式鳥哥僅列出 base 這個容器項目而已,其他的項目請您自行依照上述的作法來處理即可!

[root@www ~]# vim /etc/yum.repos.d/CentOS-Base.repo
[base]
name=CentOS-$releasever - Base
baseurl=http://ftp.twaren.net/Linux/CentOS/5/os/i386/
gpgcheck=1
gpgkey=http://mirror.centos.org/centos/RPM-GPG-KEY-CentOS-5
# 底下其他的容器項目,請自行到高速網路中心去查詢後自己處理!

接下來當然就是給他測試一下囉!如何測試呢?再次使用 yum 即可啊!

# 範例:列出目前 yum server 所使用的容器有哪些?
[root@www ~]# yum repolist all
repo id         repo name                status
addons          CentOS-5 - Addons        enabled:     0
base            CentOS-5 - Base          enabled: 2,599
c5-media        CentOS-5 - Media         disabled
centosplus      CentOS-5 - Plus          disabled
contrib         CentOS-5 - Contrib       disabled
extras          CentOS-5 - Extras        enabled:   335
updates         CentOS-5 - Updates       enabled:   488
repolist: 3,422
# 在 status 上寫 enabled 才是有啟動的!由於 /etc/yum.repos.d/
# 有多個設定檔,所以你會發現還有其他的容器存在。


由於我們是修改系統預設的設定檔,事實上,我們應該要在 /etc/yum.repos.d/ 底下新建一個檔案, 該副檔名必須是 .repo 才行!但因為我們使用的是指定特定的映射站台,而不是其他軟體開發生提供的容器, 因此才修改系統預設設定檔。但是可能由於使用的容器版本有新舊之分,你得要知道, yum 會先下載容器的清單到本機的 /var/cache/yum 裡面去!那我們修改了網址卻沒有修改容器名稱 (中刮號內的文字), 可能就會造成本機的清單與 yum 伺服器的清單不同步,此時就會出現無法更新的問題了!

那怎麼辦啊?很簡單,就清除掉本機上面的舊資料即可!需要手動處理嗎?不需要的, 透過 yum 的 clean 項目來處理即可!

[root@www ~]# yum clean [packages|headers|all] 
選項與參數:
 packages:將已下載的軟體檔案刪除
 headers :將下載的軟體檔頭刪除
 all     :將所有容器資料都刪除!

# 範例:刪除已下載過的所有容器的相關資料 (含軟體本身與清單)
[root@www ~]# yum clean all
例題:
有一個網址: http://free.nchc.org.tw/drbl-core/i386/RPMS.drbl-stable/ ,裡面包含了台灣的國家高速網路中心所發展的自由軟體。 請依據該網址提供的資料,做成系統可以自動網路安裝的 yum 格式。
答:
由於 http://free.nchc.org.tw/drbl-core/i386/RPMS.drbl-stable/ 裡面就有 repodata/ 目錄,因此,這個網址可以直接做成 yum 的容器設定檔。 你可以這麼做的:
[root@www ~]# vim /etc/yum.repos.d/drbl.repo
[drbl]
name=This is DRBL site
baseurl=http://free.nchc.org.tw/drbl-core/i386/RPMS.drbl-stable/
enable=1
gpgcheck=0

[root@www ~]# yum search drbl
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
============================== Matched: drbl ==============================
clonezilla.i386 : Opensource Clone System (ocs), clonezilla
drbl.i386 : DRBL (Diskless Remote Boot in Linux) package.
drbl-chntpw.i386 : Offline NT password and registry editor
....(底下省略)....

[root@www ~]# yum repolist all
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
repo id         repo name                status
addons          CentOS-5 - Addons        enabled:     0
base            CentOS-5 - Base          enabled: 2,599
c5-media        CentOS-5 - Media         disabled
centosplus      CentOS-5 - Plus          disabled
contrib         CentOS-5 - Contrib       disabled
drbl            This is DRBL site        enabled:    16
extras          CentOS-5 - Extras        enabled:   335
updates         CentOS-5 - Updates       enabled:   488
repolist: 3,438
drbl 這個新增的容器裡面,擁有 16 個軟體喔!這樣夠清楚嗎?


7.3 限制連線埠口 (port)

為什麼我們的主機會回應網路上面的一些要求封包呢?例如我們設定了一部 WWW 主機後,當有來自 Internet 的 WWW 要求時,我們的主機就會予以回應,這是因為我們的主機有啟用了 WWW 的監聽埠口啊!所以,當我們啟用了一個 daemon 時,就可能會造成主機的埠口在進行監聽的動作,此時該 daemon 就是已經對網路上面提供服務了!萬一這個 daemon 程式有漏洞,因為他提供了 Internet 的服務,所以就容易被 Internet 上面的 cracker 所攻擊了!所以說,仔細的檢查自己系統上面的埠口到底開了多少個,並且予以嚴格的管理,才能夠降低被攻擊的可能性啊!


7.3.1 什麼是 port

快講到爛掉了!當妳啟動一個網路服務,這個服務會依據 TCP/IP 的相關通訊協定啟動一個埠口在進行監聽, 那就是 TCP/UDP 封包的 port (埠口) 了。我們從第二章也知道網路連線是雙向的,伺服器端得要啟動一個監聽的埠口, 用戶端得要隨機啟動一個埠口來接收回應的資料才行。那麼伺服器端的服務是否需要啟動在固定的埠口? 用戶端的埠口是否又是固定的呢?我們將第二章中與 port 有關的資料給她彙整一下先:


7.3.2 埠口的觀察: netstat, nmap

好了,我們現在知道這個 port 是什麼鬼東西了,再來就是要來瞭解一下,我們的主機到底是開了多少的 port 呢?由於 port 的啟動與服務有關,那麼『服務』跟『 port 』對應的檔案是哪一個?再提醒一次呦!是『 /etc/services 』啦!而常用來觀察 port 的則有底下兩個程式:

見他的大頭王!怎麼使用 nmap 會違法?由於 nmap 的功能太強大了,所以很多 cracker 會直接以他來偵測別人的主機,這個時候就可能造成違法啦!只要你使用 nmap 的時候不要去偵測別人的電腦主機,那麼就不會有問題啦!底下我們分別來說一說這兩個寶貝吧!



在做為伺服器的 Linux 系統中,開啟的網路服務越少越好! 因為較少的服務可以較容易除錯 (debug) 與瞭解安全漏洞,並可避免不必要的入侵管道! 所以,這個時候請瞭解一下您的系統當中有沒有哪些服務被開啟了呢? 要瞭解自己的系統當中的服務項目,最簡便的方法就是使用 netstat 了!這個東西不但簡單,而且功能也是很不錯的。 這個指令的使用方法在 Linux 常用網路功能指令介紹當中提過了, 底下我們僅提供如何使用這個工具的方法囉!


如果你要偵測的設備並沒有可讓你登入的作業系統時,那該怎麼辦?舉例來說,你想要瞭解一下公司的網路印表機是否有開放某些協定時, 那該如何處理啊?現在你知道 netstat 可以用來查閱本機上面的許多監聽中的通訊協定, 那例如網路印表機這樣的非本機的設備,要如何查詢啊?呵呵!用 nmap 就對了!

nmap (註1)的軟體說明之名稱為:『Network exploration tool and security / port scanner』,顧名思義, 這個東西是被系統管理員用來管理系統安全性查核的工具!他的具體描述當中也提到了, nmap 可以經由程式內部自行定義的幾個 port 對應的指紋資料,來查出該 port 的服務為何,所以我們也可以藉此瞭解我們主機的 port 到底是幹嘛用的!在 CentOS 裡頭是有提供 nmap 的, 如果你沒有安裝,那麼就使用 yum 去安裝他吧!

[root@www ~]# nmap [掃瞄類型] [掃瞄參數] [hosts 位址與範圍]
選項與參數:
[掃瞄類型]:主要的掃瞄類型有底下幾種:
    -sT:掃瞄 TCP 封包已建立的連線 connect() !
    -sS:掃瞄 TCP 封包帶有 SYN 標籤的資料
    -sP:以 ping 的方式進行掃瞄
    -sU:以 UDP 的封包格式進行掃瞄
    -sO:以 IP 的協定 (protocol) 進行主機的掃瞄
[掃瞄參數]:主要的掃瞄參數有幾種:
    -PT:使用 TCP 裡頭的 ping 的方式來進行掃瞄,可以獲知目前有幾部電腦存活(較常用)
    -PI:使用實際的 ping (帶有 ICMP 封包的) 來進行掃瞄
    -p :這個是 port range ,例如 1024-, 80-1023, 30000-60000 等等的使用方式
[Hosts 位址與範圍]:這個有趣多了,有幾種類似的類型
    192.168.1.100  :直接寫入 HOST IP 而已,僅檢查一部;
    192.168.1.0/24 :為 C Class 的型態,
    192.168.*.*  :嘿嘿!則變為 B Class 的型態了!掃瞄的範圍變廣了!
    192.168.1.0-50,60-100,103,200 :這種是變形的主機範圍啦!很好用吧!

# 範例一:使用預設參數掃瞄本機所啟用的 port (只會掃瞄 TCP)
[root@www ~]# nmap localhost
PORT    STATE SERVICE
22/tcp  open  ssh
25/tcp  open  smtp
111/tcp open  rpcbind
631/tcp open  ipp
# 在預設的情況下, nmap 僅會掃瞄 TCP 的協定喔!

nmap 的用法很簡單吶!就直接在指令後面接上 IP 或者是主機名稱即可。不過,在預設的情況下 nmap 僅會幫你分析 TCP 這個通訊協定而已,像上面這個例子的輸出結果。但優點是順道也將開啟該埠口的服務也列出來了, 真是好! ^_^!那如果想要同時分析 TCP/UDP 這兩個常見的通訊協定呢?可以這樣做:

# 範例二:同時掃瞄本機的 TCP/UDP 埠口
[root@www ~]# nmap -sTU localhost
PORT    STATE         SERVICE
22/tcp  open          ssh
25/tcp  open          smtp
111/tcp open          rpcbind
631/tcp open          ipp
137/udp open|filtered netbios-ns
138/udp open|filtered netbios-dgm
631/udp open|filtered unknown

嘿嘿!與前面的範例比較一下,你會發現這次多了幾個 UDP 的埠口,這樣分析好多了!然後, 如果你想要瞭解一下到底有幾部主機活在你的網路當中時,則可以這樣做:

# 範例三:透過 ICMP 封包的檢測,分析區網內有幾部主機是啟動的
[root@www ~]# nmap -sP 192.168.1.0/24
Starting Nmap 4.11 ( http://www.insecure.org/nmap/ ) at 2010-09-15 00:30 CST
Host www.centos.vbird (192.168.1.11) appears to be up.
Host 192.168.1.254 appears to be up.
MAC Address: 00:0C:6E:85:D5:69 (Asustek Computer)
Nmap finished: 256 IP addresses (2 hosts up) scanned in 5.596 seconds

看到否?鳥哥的環境當中有兩部主機活著吶!並且該 IP 所對應的 MAC 也會被記錄下來, 很不錯吧!如果你還想要將各個主機的啟動的 port 作一番偵測的話,那就得要使用:

[root@www ~]# nmap 192.168.1.0/24

之後你就會看到一堆 port number 被輸出到螢幕上囉∼如果想要隨時記錄整個網段的主機是否不小心開放了某些服務, 嘿嘿!利用 nmap 配合資料流重導向 (>, >> 等) 來輸出成為檔案, 那隨時可以掌握住您區域網路內每部主機的服務啟動狀況啊! ^_^

請特別留意,這個 nmap 的功能相當的強大,也是因為如此,所以很多剛在練習的黑客會使用這個軟體來偵測別人的電腦。 這個時候請您特別留意,目前很多的人已經都有『特別的方式』來進行登錄的工作!例如以 TCP_Wrappers (/etc/hosts.allow, /etc/hosts.deny) 的功能來記錄曾經偵測過該 port 的 IP! 這個軟體用來『偵測自己機器的安全性』是很不錯的一個工具,但是如果用來偵測別人的主機, 可是會『吃上官司』的!特別留意!!


7.3.3 埠口與服務的啟動/關閉及開機時狀態設定

從第二章的資料我們就知道,其實 port 是由執行某些軟體之後被軟體啟動的。所以要關閉某些 port 時,那就直接將某個程式給他關閉就是了!關閉的方法你當然可以使用 kill,不過這畢竟不是正統的解決之道,因為 kill 這個指令通常具有強制關閉某些程式的功能,但我們想要正常的關閉該程式啊! 所以,就利用系統給我們的 script 來關閉就好了啊。 在此同時,我們就得再來稍微複習一下,一般傳統的服務有哪幾種類型?


我們在基礎學習篇內談到,在一般正常的 Linux 系統環境下,服務的啟動與管理主要有兩種方式:

關於更詳細的服務說明,請參考基礎篇的認識服務一文, 鳥哥在這裡不再贅述。好,那麼如果我想要將我系統上面的 port 631 關掉的話, 那應該如何關閉呢?最簡單的作法就是先找出那個 port 631 的啟動程式喔!

[root@www ~]# netstat -tnlp | grep 631
tcp        0      0 127.0.0.1:631   0.0.0.0:*     LISTEN   2058/cupsd
# 原來用的是 cupsd 這個服務程式!

[root@www ~]# which cupsd
/usr/sbin/cupsd
# 找到檔案後,再以 rpm 處理處理

[root@www ~]# rpm -qf /usr/sbin/cupsd
cups-1.3.7-18.el5_5.4
# 找到了!就是這個軟體!所以將他關閉的方法可能就是:

[root@www ~]# rpm -qc cups | grep init
/etc/rc.d/init.d/cups
[root@www ~]# /etc/init.d/cups stop

透過上面的這個分析的流程,你可以利用系統提供的很多方便的工具來達成某個服務的關閉! 為啥這麼麻煩?不是利用 kill -9 2058 就可以刪掉該服務了嗎? 是沒錯啦!不過,你知道該服務是做啥用的嗎?你知道將他關閉之後,你的系統會出什麼問題嗎? 如果不知道的話,那麼利用上面的流程不就可以找出該服務套件,再利用 rpm 查詢功能, 不就能夠知道該服務的作用了?所以說,這個方式還是對您會有幫助的啦! 底下請您試著將您 CentOS 或者是其他版本的 Linux 的 Telnet 打開試看看。

例題:
我們知道系統的 Telnet 服務通常是以 super daemon 來控管的,請您啟動您系統的 telnet 試看看。
答:
  1. 要啟動 telnet 首先必須要已經安裝了 telnet 的伺服器才行,所以請先以 rpm 查詢看看是否有安裝 telnet-server 呢? 『rpm -qa | grep telnet-server』如果沒有安裝的話,請利用原版光碟來安裝,或者使用『yum install telnet-server』 安裝一下先;
  2. 由於是 super daemon 控管,所以請編輯 /etc/xinetd.d/telnet 這個檔案,將其中的『disable = yes』改成 『disable = no』之後以『/etc/init.d/xinetd restart』重新啟動 super daemon 吧!
  3. 利用 netstat -tnlp 察看是否有啟動 port 23 呢?


剛剛上頭的作法僅是『立即將該服務啟動或關閉』喔!並不會影響到下次開機時,這個服務是否預設啟動的情況。 如果你想要在開機的時候就啟動或不啟動某項服務時,那就得要瞭解一下基礎學習篇裡面談到的開機流程管理的內容啦!在 Unix like 的系統當中我們都是透過 run level 來設定某些執行等級需要啟動的服務,以 Red Hat 系統來說,這些 run level 啟動的資料都是放置在 /etc/rc.d/rc[0-6].d/ 裡面的,那如何管理該目錄下的 script 呢?手動處理嗎?會瘋掉的吶!所以你必須要熟悉 chkconfigRed Hat 系統的 ntsysv 這幾個指令才行!

這幾個指令不熟嗎?這個時候鳥哥不得不說了:『有 man 堪用直需用,莫待無 man 空自猜』趕緊給他 man 下去啦!
例題:
(1)如何查閱 portmap 這個程式一開機就執行? (2)如果開機就執行,如何將他改為開機時不要啟動? (3)如何立即關閉這個 portmap 服務?
答:
  1. 可以透過『 chkconfig --list | grep portmap 』與『 runlevel 』確認一下你的環境與 portmap 是否啟動?
  2. 如果有啟動,可透過『 chkconfig --level 35 portmap off 』來設定開機時不要啟動;
  3. 可以透過『 /etc/init.d/portmap stop 』來立即關閉他!

聰明的你一定會問說:『鳥哥,你的意思是只要將系統所有的服務都關閉,那系統就會安全囉?』 當然....不是!因為『很多的系統服務是必須要存在的,否則系統將會出問題』 舉例來說,那個保持系統可以具有工作排程的 crond 服務就一定要存在,而那個記錄系統狀況的 syslogd 也當然要存在∼否則怎知道系統出了啥問題?所以囉,除非你知道每個服務的目的是啥,否則不要隨便關閉該服務。 底下鳥哥列出幾個常見的必須要存在的系統服務給大家參考參考先!這些服務請不要關閉啊!

服務名稱服務內容
acpid新版的電源管理模組,通常建議開啟,不過,某些筆記型電腦可能不支援此項服務,那就得關閉
atd在管理單一預約命令執行的服務,應該要啟動的
crond在管理工作排程的重要服務,請務必要啟動啊!
haldaemon作系統硬體變更偵測的服務,與 USB 設備關係很大
iptablesLinux 內建的防火牆軟體,這個也可以啟動啦!
network這個重要了吧?要網路就要有他啊!
sendmail系統內部郵件傳遞服務,不要隨便關閉他!
sshd這是系統預設會啟動的,可以讓你在遠端以文字型態的終端機登入喔!
syslog系統的登錄檔記錄,很重要的,務必啟動啊!
xinetd就是那個 super daemon 嘛!所以也要啟動啦!
xfs用來管理 X Window 字形資料的服務,如果你會需要 X Window 時,這個服務要啟動。

上面列出的是主機需要的重點服務,請您不要關閉他!除非你知道作了之後會有什麼後果。舉例來說,你如果不需要 X window , 那麼將 xfs 關閉也沒有關係啊!如果你不需要提供遠端連線功能,那麼 sshd 也可以關閉啊!那其他你不知道的服務怎辦? 沒關係,只要不是網路服務,你都可以保留他!如果是網路服務呢?那...鳥哥建議你不知道的服務就先關閉他! 以後我們談到每個相關的服務時,再一個一個打開即可。底下我們就來做作看這個部分!


7.3.4 安全性考量-關閉網路服務埠口

我們的 Linux distribution 很好心的幫使用者想到很多了,所以在一安裝完畢之後, 系統會開啟一堆有的沒有的網路服務,例如那個 portmap 之類的咚咚,以及網路印表機的 cups 服務等等, 這些東西你或許知道或許不知道,不過他就是有開啟∼但我們的主機明明就是用來做為伺服器的, 所以這些本來預計要給 client 使用的服務其實有點『多此一舉』的感覺∼ 所以啦,請你將他關閉吧!底下我們舉個簡單的例子來處理,將你的網路服務關閉就好,其他在系統內部的服務, 就暫時保留吧!

例題:
找出目前系統上面正在運作中的服務,並且找到相對應的啟動腳本 (在 /etc/init.d 內的檔名之意)。
答:
要找出服務,就利用 netstat -tunlp 即可找到!以鳥哥從第一章安裝的示範機為例,鳥哥目前啟動的網路服務有底下這些:
[root@www ~]# netstat -tlunp
Active Internet connections (only servers)
Proto  Local Address        State     PID/Program name
tcp    127.0.0.1:2208       LISTEN    2026/hpiod
tcp    0.0.0.0:139          LISTEN    2155/smbd
tcp    0.0.0.0:111          LISTEN    1790/portmap
tcp    127.0.0.1:631        LISTEN    2053/cupsd
tcp    127.0.0.1:25         LISTEN    2085/sendmail: acce
tcp    0.0.0.0:732          LISTEN    1822/rpc.statd
tcp    0.0.0.0:445          LISTEN    2155/smbd
tcp    127.0.0.1:2207       LISTEN    2031/python
tcp    :::22                LISTEN    2044/sshd
udp    192.168.1.11:137               2158/nmbd
udp    0.0.0.0:137                    2158/nmbd
udp    192.168.1.11:138               2158/nmbd
udp    0.0.0.0:138                    2158/nmbd
udp    0.0.0.0:726                    1822/rpc.statd
udp    0.0.0.0:729                    1822/rpc.statd
udp    0.0.0.0:111                    1790/portmap
udp    0.0.0.0:631                    2053/cupsd
# 上述的輸出鳥哥有稍微簡化一些喔,所以有些欄位不見了。
# 這個重點只是要展現出最後一個欄位而已啦!
看起來總共有 cupsd, hpiod, nmbd, portmap, python, rpc.statd, sendmail, smbd, sshd 等這幾個服務,對照前一小節的資料內容來看, sendmail, sshd 不能關掉,那麼其他的就予以關閉啊!透過前兩個小節的介紹,使用 which 與 rpm 搜尋吧!舉例來說, hpiod 的啟動腳本在:『rpm -qc $(rpm -qf $(which hpiod) ) | grep init』這樣找,結果是在『/etc/rc.d/init.d/hplip』這裡! 比較特殊的是 python 啦!不過還好他是啟動在 127.0.0.1 ,可以暫時忽略他。因此最終的結果如下:
cupsd     /etc/rc.d/init.d/cups
hpiod     /etc/rc.d/init.d/hplip
nmbd      /etc/rc.d/init.d/smb
portmap   /etc/rc.d/init.d/portmap
rpc.statd /etc/rc.d/init.d/nfs
          /etc/rc.d/init.d/nfslock
          /etc/rc.d/init.d/rpcgssd
          /etc/rc.d/init.d/rpcidmapd
          /etc/rc.d/init.d/rpcsvcgssd
smbd      /etc/rc.d/init.d/smb
接下來就是將該服務關閉,並且設定為開機不啟動吧!
[root@www ~]# vim closedaemon.sh
for daemon in cups hplip smb portmap nfs nfslock rpcgssd \
              rpcidmapd rpcsvcgssd smb
do
	chkconfig $daemon off
	/etc/init.d/$daemon stop
done
[root@www ~]# sh closedaemon.sh

做完上面的例子之後,你再次下達 netstat -tlunp 之後,會得到僅剩 port 25, 22 而已! 如此一來,絕大部分伺服器用不到的服務就被你關閉,而且即使重新開機也不會被啟動的啦! ^_^


7.4 SELinux 管理原則

SELinux 使用所謂的委任式存取控制 (Mandatory Access Control, MAC) ,他可以針對特定的程序與特定的檔案資源來進行權限的控管! 也就是說,即使你是 root ,那麼在使用不同的程序時,你所能取得的權限並不一定是 root ,而得要看當時該程序的設定而定。 如此一來,我們針對控制的『主體』變成了『程序』而不是『使用者』喔!因此,這個權限的管理模式就特別適合網路服務的『程序』了! 因為,即使你的程序使用 root 的身份去啟動,如果這個程序被攻擊而被取得操作權,那該程序能作的事情還是有限的, 因為被 SELinux 限制住了能進行的工作了嘛!

舉例來說, WWW 伺服器軟體的達成程序為 httpd 這支程式, 而預設情況下, httpd 僅能在 /var/www/ 這個目錄底下存取檔案,如果 httpd 這個程序想要到其他目錄去存取資料時,除了規則設定要開放外,目標目錄也得要設定成 httpd 可讀取的模式 (type) 才行喔!限制非常多! 所以,即使不小心 httpd 被 cracker 取得了控制權,他也無權瀏覽 /etc/shadow 等重要的設定檔喔!


7.4.1 SELinux 的運作模式

再次的重複說明一下,SELinux 是透過 MAC 的方式來控管程序,他控制的主體是程序, 而目標則是該程序能否讀取的『檔案資源』!所以先來說明一下這些咚咚的相關性啦!

SELinux 運作的各元件之相關性
圖 7.4-1、SELinux 運作的各元件之相關性(本圖參考小州老師的上課講義)

上圖的重點在『主體』如何取得『目標』的資源存取權限! 由上圖我們可以發現,(1)主體程序必須要通過 SELinux 政策內的規則放行後,就可以與目標資源進行安全性本文的比對, (2)若比對失敗則無法存取目標,若比對成功則可以開始存取目標。問題是,最終能否存取目標還是與檔案系統的 rwx 權限設定有關喔!如此一來,加入了 SELinux 之後,出現權限不符的情況時,你就得要一步一步的分析可能的問題了!


CentOS 5.x 的 target 政策已經幫我們制訂好非常多的規則了,因此你只要知道如何開啟/關閉某項規則的放行與否即可。 那個安全性本文比較麻煩!因為你可能需要自行設定檔案的安全性本文呢!為何需要自行設定啊? 舉例來說,你不也常常進行檔案的 rwx 的重新設定嗎?這個安全性本文你就將他想成 SELinux 內必備的 rwx 就是了!這樣比較好理解啦。

安全性本文存在於主體程序中與目標檔案資源中。程序在記憶體內,所以安全性本文可以存入是沒問題。 那檔案的安全性本文是記錄在哪裡呢?事實上,安全性本文是放置到檔案的 inode 內的,因此主體程序想要讀取目標檔案資源時,同樣需要讀取 inode , 這 inode 內就可以比對安全性本文以及 rwx 等權限值是否正確,而給予適當的讀取權限依據。

那麼安全性本文到底是什麼樣的存在呢?我們先來看看 /root 底下的檔案的安全性本文好了。 觀察安全性本文可使用『 ls -Z 』去觀察如下:(注意:你必須已經啟動了 SELinux 才行!若尚未啟動,這部份請稍微看過一遍即可。底下會介紹如何啟動 SELinux 喔!)

[root@www ~]# ls -Z
drwxr-xr-x  root root root:object_r:user_home_t   Desktop
-rw-r--r--  root root root:object_r:user_home_t   install.log
-rw-r--r--  root root root:object_r:user_home_t   install.log.syslog
# 上述特殊字體的部分,就是安全性本文的內容!

如上所示,安全性本文主要用冒號分為三個欄位,這三個欄位的意義為:

Identify:role:type
身份識別:角色:類型


那麼這三個欄位如何利用呢?首先我們來瞧瞧主體程序在這三個欄位的意義為何!透過身份識別與角色欄位的定義, 我們可以約略知道某個程序所代表的意義喔!基本上,這些對應資料在 targeted 政策下的對應如下:

身份識別角色該對應在 targeted 的意義
rootsystem_r代表供 root 帳號登入時所取得的權限
system_usystem_r由於為系統帳號,因此是非交談式的系統運作程序
user_usystem_r一般可登入使用者的程序囉!

但就如上所述,其實最重要的欄位是類型欄位,主體與目標之間是否具有可以讀寫的權限,與程序的 domain 及檔案的 type 有關!這兩者的關係我們可以使用達成 WWW 伺服器功能的 httpd 這支程式與 /var/www/html 這個網頁放置的目錄來說明。 首先,看看這兩個咚咚的安全性本文內容先:

[root@www ~]# ll -Zd /usr/sbin/httpd /var/www/html
-rwxr-xr-x  root root system_u:object_r:httpd_exec_t   /usr/sbin/httpd
drwxr-xr-x  root root system_u:object_r:httpd_sys_content_t /var/www/html
# 兩者的角色欄位都是 object_r ,代表都是檔案!而 httpd 屬於 httpd_exec_t 類型,
# /var/www/html 則屬於 httpd_sys_content_t 這個類型!

httpd 屬於 httpd_exec_t 這個可以執行的類型,而 /var/www/html 則屬於 httpd_sys_content_t 這個可以讓 httpd 領域 (domain) 讀取的類型。文字看起來不太容易瞭解吧!我們使用圖示來說明這兩者的關係!

主體程序取得的 domain 與目標檔案資源的 type 相互關係
圖 7.4-2、主體程序取得的 domain 與目標檔案資源的 type 相互關係

上圖的意義我們可以這樣看的:

  1. 首先,我們觸發一個可執行的目標檔案,那就是具有 httpd_exec_t 這個類型的 /usr/sbin/httpd
  2. 該檔案的類型會讓這個檔案所造成的主體程序 (Subject) 具有 httpd 這個領域 (domain), 我們的政策針對這個領域已經制定了許多規則,其中包括這個領域可以讀取的目標資源類型;
  3. 由於 httpd domain 被設定為可以讀取 httpd_sys_content_t 這個類型的目標檔案 (Object), 因此你的網頁放置到 /var/www/html/ 目錄下,就能夠被 httpd 那支程序所讀取了;
  4. 但最終能不能讀到正確的資料,還得要看 rwx 是否符合 Linux 權限的規範!

上述的流程告訴我們幾個重點,第一個是政策內需要制訂詳細的 domain/type 相關性;第二個是若檔案的 type 設定錯誤, 那麼即使權限設定為 rwx 全開的 777 ,該主體程序也無法讀取目標檔案資源的啦!不過如此一來, 也就可以避免使用者將他的家目錄設定為 777 時所造成的權限困擾。


7.4.2 SELinux 的啟動、關閉與觀察

並非所有的 Linux distributions 都支援 SELinux 的,所以你必須要先觀察一下你的系統版本為何! 鳥哥這裡介紹的 CentOS 5.x 本身就有支援 SELinux 啦!所以你不需要自行編譯 SELinux 到你的 Linux 核心中! 目前 SELinux 支援三種模式,分別如下:

那你怎麼知道目前的 SELinux 模式呢?就透過 getenforce 吧!

[root@www ~]# getenforce
Enforcing  <==諾!就顯示出目前的模式為 Enforcing 囉!

另外,我們又如何知道 SELinux 的政策 (Policy) 為何呢?這時可以來觀察設定檔啦:

[root@www ~]# vim /etc/selinux/config
SELINUX=enforcing     <==調整 enforcing|disabled|permissive
SELINUXTYPE=targeted  <==目前僅有 targeted 與 strict


上面是預設的政策與啟動的模式!你要注意的是,如果改變了政策則需要重新開機;如果由 enforcing 或 permissive 改成 disabled ,或由 disabled 改成其他兩個,那也必須要重新開機。這是因為 SELinux 是整合到核心裡面去的, 你只可以在 SELinux 運作下切換成為強制 (enforcing) 或寬容 (permissive) 模式,不能夠直接關閉 SELinux 的! 如果剛剛你發現 getenforce 出現 disabled 時,請到上述檔案修改成為 enforcing 然後重新開機吧!

不過你要注意的是,如果從 disable 轉到啟動 SELinux 的模式時, 由於系統必須要針對檔案寫入安全性本文的資訊,因此開機過程會花費不少時間在等待重新寫入 SELinux 安全性本文 (有時也稱為 SELinux Label) ,而且在寫完之後還得要再次的重新開機一次喔!你必須要等待粉長一段時間! 等到下次開機成功後,再使用 getenforce 來觀察看看有否成功的啟動到 Enforcing 的模式囉!

如果你已經在 Enforcing 的模式,但是可能由於一些設定的問題導致 SELinux 讓某些服務無法正常的運作, 此時你可以將 Enforcing 的模式改為寬容 (permissive) 的模式,讓 SELinux 只會警告無法順利連線的訊息, 而不是直接抵擋主體程序的讀取權限。讓 SELinux 模式在 enforcing 與 permissive 之間切換的方法為:

[root@www ~]# setenforce [0|1]
選項與參數:
0 :轉成 permissive 寬容模式;
1 :轉成 Enforcing 強制模式

# 範例一:將 SELinux 在 Enforcing 與 permissive 之間切換與觀察
[root@www ~]# setenforce 0
[root@www ~]# getenforce
Permissive
[root@www ~]# setenforce 1
[root@www ~]# getenforce
Enforcing

不過請注意, setenforce 無法在 Disabled 的模式底下進行模式的切換喔!


7.4.3 SELinux type 的修改

既然 SELinux 的類型欄位 (type) 這麼重要,那如何修改與變更這個欄位,當然就是最重要的一件事囉。 首先,我們來看看如果複製一個檔案到不同的目錄去,會發生什麼狀況吧!

# 範例:將 /etc/hosts 複製到 root 家目錄,並觀察相關的 SELinux 類型變化
[root@www ~]# cp /etc/hosts /root
[root@www ~]# ls -dZ /etc/hosts /root/hosts /root
-rw-r--r--  root root system_u:object_r:etc_t          /etc/hosts
drwxr-x---  root root root:object_r:user_home_dir_t    /root
-rw-r--r--  root root root:object_r:user_home_t        /root/hosts

# 範例:將 /root/hosts 移動到 /tmp 下,並觀察相關的 SELinux 類型變化
[root@www ~]# mv /root/hosts /tmp
[root@www ~]# ls -dZ /tmp /tmp/hosts
drwxrwxrwt  root root system_u:object_r:tmp_t          /tmp
-rw-r--r--  root root root:object_r:user_home_t        /tmp/hosts

看到沒有?當你單純的複製時,SELinux 的 type 欄位是會繼承目標目錄的,所以 /root/hosts 的類型就會變成 user_home_t 這個類型了。但是如果是移動呢?那麼連同 SELinux 的類型也會被移動過去,因此 /tmp/hosts 會依舊保持 user_home_t 而不會變成 /tmp 的 tmp_t 這個類型呦!要注意!要注意!那麼,如何將 /tmp/hosts 變更成為最原始的 etc_t 這個類型呢?那就得要使用 chcon 囉!



[root@www ~]# chcon [-R] [-t type] [-u user] [-r role] 檔案
[root@www ~]# chcon [-R] --reference=範例檔 檔案
選項與參數:
-R  :連同該目錄下的次目錄也同時修改;
-t  :後面接安全性本文的類型欄位!例如 httpd_sys_content_t ;
-u  :後面接身份識別,例如 system_u;
-r  :後面街角色,例如 system_r;
--reference=範例檔:拿某個檔案當範例來修改後續接的檔案的類型!

# 範例:將剛剛的 /tmp/hosts 類型改為 etc_t 的類型
[root@www ~]# chcon -t etc_t /tmp/hosts
[root@www ~]# ll -Z /tmp/hosts
-rw-r--r--  root root root:object_r:etc_t              /tmp/hosts

# 範例:以 /var/spool/mail/ 為依據,將 /tmp/hosts 修改成該類型
[root@www ~]# ll -dZ /var/spool/mail
drwxrwxr-x  root mail system_u:object_r:mail_spool_t   /var/spool/mail
[root@www ~]# chcon --reference=/var/spool/mail /tmp/hosts
[root@www ~]# ll -Z /tmp/hosts
-rw-r--r--  root root system_u:object_r:mail_spool_t   /tmp/hosts

chcon 的修改方式中,我們必須要知道最終我們的 SELinux type 是啥類型後,才能夠變更成功。 如果你想要作的是『復原成原有的 SELinux type』呢?那可以參考底下的指令來進行呦!



[root@www ~]# restorecon [-Rv] 檔案或目錄
選項與參數:
-R  :連同次目錄一起修改;
-v  :將過程顯示到螢幕上

# 範例:將剛剛 /tmp/hosts 移動至 /root 並以預設的安全性本文改正過來
[root@www ~]# mv /tmp/hosts /root
[root@www ~]# ll -Z /root/hosts
-rw-r--r--  root root system_u:object_r:mail_spool_t   /root/hosts
[root@www ~]# restorecon -Rv /root
restorecon reset /root/hosts context system_u:object_r:mail_spool_t:s0->
root:object_r:user_home_t:s0
# 上面這兩行其實是同一行喔!表示將 hosts 由 mail_spool_t 改為 user_home_t


透過上面這幾個練習,你就會知道啦,SELinux type 恐怕會在檔案的複製/移動時產生一些變化,因此需要善用 chcon, restorecon 等指令來進行修訂。那你應該還是會想到一件事,那就是, restorecon 怎麼會知道每個目錄記載的預設 SELinux type 類型呢?這是因為系統有記錄嘛!記錄在 /etc/selinux/targeted/contexts,但是該目錄內有很多不同的資料, 要使用文字編輯器去查閱很麻煩,此時,我們可以透過 semanage 這個指令的功能來查詢與修改喔!

[root@www ~]# semanage {login|user|port|interface|fcontext|translation} -l
[root@www ~]# semanage fcontext -{a|d|m} [-frst] file_spec
選項與參數:
fcontext :主要用在安全性本文方面的用途, -l 為查詢的意思;
-a :增加的意思,你可以增加一些目錄的預設安全性本文類型設定;
-m :修改的意思;
-d :刪除的意思。

# 範例:查詢一下 /var/www/ 的預設安全性本文設定為何!
[root@www ~]# semanage fcontext -l | grep '/var/www'
SELinux fcontext      type       Context
/var/www(/.*)?        all files  system_u:object_r:httpd_sys_content_t:s0
....(後面省略)....

從上面的說明,我們知道其實 semanage 可以處理非常多的任務,不過,在這個小節我們主要想瞭解的是每個目錄的預設安全性本文。 如上面範例所示,我們可以查詢的到每個目錄的安全性本文啦!而目錄的設定可以使用正規表示法去指定一個範圍。那麼如果我們想要增加某些自訂的目錄的安全性本文呢? 舉例來說,我想要制訂 /srv/vbird 成為 public_content_t 的類型時,應該如何指定呢?

# 範例:利用 semanage 設定 /srv/vbird 目錄的預設安全性本文為 public_content_t
[root@www ~]# mkdir /srv/vbird
[root@www ~]# ll -Zd /srv/vbird
drwxr-xr-x  root root root:object_r:var_t    /srv/vbird
# 如上所示,預設的情況應該是 var_t 這個咚咚的!

[root@www ~]# semanage fcontext -l | grep '/srv'
/srv/.*                   all files  system_u:object_r:var_t:s0 <==看這裡
/srv/([^/]*/)?ftp(/.*)?   all files  system_u:object_r:public_content_t:s0
....(底下省略)....
# 上面則是預設的 /srv 底下的安全性本文資料,不過,並沒有指定到 /srv/vbird 啦

[root@www ~]# semanage fcontext -a -t public_content_t "/srv/vbird(/.*)?"
[root@www ~]# semanage fcontext -l | grep '/srv/vbird'
/srv/vbird(/.*)?          all files  system_u:object_r:public_content_t:s0

[root@www ~]# cat /etc/selinux/targeted/contexts/files/file_contexts.local
# This file is auto-generated by libsemanage
# Please use the semanage command to make changes
/srv/vbird(/.*)?    system_u:object_r:public_content_t:s0
# 其實就是寫入這個檔案的囉! ^_^

[root@www ~]# restorecon -Rv /srv/vbird* <==嘗試恢復預設值
[root@www ~]# ll -Zd /srv/vbird
drwxr-xr-x  root root system_u:object_r:public_content_t /srv/vbird
# 有預設值,以後用 restorecon 來修改比較簡單!

semanage 的功能很多,不過鳥哥主要用到的僅有 fcontext 這個項目的動作而已。如上所示, 你可以使用 semanage 來查詢所有的目錄預設值,也能夠使用他來增加預設值的設定!如果您學會這些基礎的工具, 那麼 SELinux 對你來說,也不是什麼太難的咚咚囉!


7.4.4 SELinux 政策內的規則布林值修訂

前面講到,要通過 SELinux 的驗證之後才能開始檔案權限 rwx 的判斷,而 SELinux 的判斷主要是 (1)政策內的規則比對與 (2)程序與檔案的 SELinux type 要符合才能夠放行。前一個小節談的是 SELinux 的 type ,這個小節就是要談一下政策內的規則囉, 包括如何查詢與修改相關的規則放行與否囉。


CentOS 5.x 預設使使用 targeted 政策,那麼這個政策提供多少相關的規則呢?此時可以透過 seinfo 來查詢喔!

[root@www ~]# seinfo [-Atrub]
選項與參數:
-A  :列出 SELinux 的狀態、規則布林值、身份識別、角色、類別等所有資訊
-t  :列出 SELinux 的所有類別 (type) 種類
-r  :列出 SELinux 的所有角色 (role) 種類
-u  :列出 SELinux 的所有身份識別 (user) 種類
-b  :列出所有規則的種類 (布林值)

# 範例一:列出 SELinux 在此政策下的統計狀態
[root@www ~]# seinfo
Statistics for policy file: /etc/selinux/targeted/policy/policy.21
Policy Version & Type: v.21 (binary, MLS) <==列出政策所在檔與版本

   Classes:            61    Permissions:       220
   Types:            1831    Attributes:        214
   Users:               3    Roles:               6
   Booleans:          263    Cond. Expr.:       246
   Sensitivities:       1    Categories:       1024
   Allow:          128513    Neverallow:          0
   Auditallow:         42    Dontaudit:        7215
   Role allow:          5    Role trans:          0
....(底下省略)....
# 從上面我們可以看到這個政策是 targeted ,此政策的 SELinux type 有 1831 個;
# 而針對網路服務的規則 (Booleans) 共制訂了 263 條規則!

# 範例二:列出與 httpd 有關的規則 (booleans) 有哪些?
[root@www ~]# seinfo -b | grep httpd
Rule loading disabled
Conditional Booleans: 263
   allow_httpd_mod_auth_pam
   allow_httpd_bugzilla_script_anon_write
   httpd_enable_ftp_server
....(底下省略)....
# 你可以看到,有非常多的與 httpd 有關的規則訂定呢!

從上面我們可以看到與 httpd 有關的布林值,同樣的,如果你想要找到有 httpd 字樣的安全性本文類別時, 就可以使用『 seinfo -t | grep httpd 』來查詢了!如果查詢到相關的類別或者是布林值後,想要知道詳細的規則時, 就得要使用 sesearch 這個指令了!

[root@www ~]# sesearch [-a] [-s 主體類別] [-t 目標類別] [-b 布林值]
選項與參數:
-a  :列出該類別或布林值的所有相關資訊
-t  :後面還要接類別,例如 -t httpd_t
-b  :後面還要接布林值的規則,例如 -b httpd_enable_ftp_server

# 範例一:找出目標檔案資源類別為 httpd_sys_content_t 的有關資訊
[root@www ~]# sesearch -a -t httpd_sys_content_t
Found 95 av rules:
   allow rpm_t httpd_sys_content_t : file { ioctl read write ... };
   allow semanage_t httpd_sys_content_t : file { ioctl read  ... };
   allow rpm_t httpd_sys_content_t : dir { ioctl read write  ... };
....(底下省略)....
# 『 allow  主體程序安全性本文類別  目標檔案安全性本文類別 』
# 如上,說明這個類別可以被那個主題程序的類別所讀取,以及目標檔案資源的格式。

# 範例二:找出主體程序為 httpd_t 且目標檔案類別為 httpd 相關的所有資訊
[root@www ~]# sesearch -s httpd_t -t httpd_* -a
Found 205 av rules:
....(中間省略)....
   allow httpd_t httpd_sys_content_t : file { ioctl read getattr lock };
   allow httpd_t httpd_sys_content_t : dir { ioctl read getattr lock search };
   allow httpd_t httpd_sys_content_t : lnk_file { ioctl read getattr lock };
....(後面省略)....
# 從上面的資料就可以看出當程序為 httpd_t 這個類別,是可以讀取 
# httpd_sys_content_t 的!

你可以很輕易的查詢到某個主體程序 (subject) 可以讀取的目標檔案資源 (Object) , 從我們上面的練習,我們也可以很輕鬆的就知道,為何 httpd_t 可以讀取 httpd_sys_content_t 囉! 那如果是布林值呢?裡面又規範了什麼?讓我們來看看先:

# 範例三:我知道有個布林值為 httpd_enable_homedirs ,請問該布林值規範多少規則?
[root@www ~]# sesearch -b httpd_enable_homedirs -a
Found 21 av rules:
   allow httpd_suexec_t user_home_dir_t : dir { getattr search };
   allow httpd_suexec_t cifs_t : file { ioctl read getattr ... };
   allow httpd_suexec_t cifs_t : dir { ioctl read getattr  ... };
....(後面省略)....

從這個布林值的設定我們可以看到裡面規範了非常多的主體程序與目標檔案資源的放行與否! 所以你知道了,實際規範這些規則的,就是布林值的項目啦!那也就是我們之前所說的一堆規則是也! 你的主體程序能否對某些目標檔案進行存取,與這個布林值非常有關係喔!因為布林值可以將規則設定為啟動 (1) 或者是關閉 (0) 啦!


上面我們透過 sesearch 知道了,其實 Subject 與 Object 能否有存取的權限,是與布林值有關的, 那麼系統有多少布林值可以透過 seinfo -b 來查詢,但,每個布林值是啟動的還是關閉的呢?這就來查詢看看吧:

[root@www ~]# getsebool [-a] [布林值條款]
選項與參數:
-a  :列出目前系統上面的所有布林值條款設定為開啟或關閉值

# 範例一:查詢本系統內所有的布林值設定狀況
[root@www ~]# getsebool -a
NetworkManager_disable_trans --> off
aisexec_disable_trans --> off
allow_console_login --> off
....(底下省略)....
# 您瞧!這就告訴你目前的布林值狀態囉!

那麼如果查詢到某個布林值,並且以 sesearch 知道該布林值的用途後,想要關閉或啟動他,又該如何處置?

[root@www ~]# setsebool [-P] 布林值=[0|1]
選項與參數:
-P  :直接將設定值寫入設定檔,該設定資料未來會生效的!

# 範例一:查詢 httpd_enable_homedirs 是否為關閉,若不為關閉,請關閉他!
[root@www ~]# getsebool httpd_enable_homedirs
httpd_enable_homedirs --> on  <==結果是 on ,依題意給他關閉!

[root@www ~]# setsebool -P httpd_enable_homedirs=0
[root@www ~]# getsebool httpd_enable_homedirs
httpd_enable_homedirs --> off

這個 setsebool 最好記得一定要加上 -P 的選項!因為這樣才能將此設定寫入設定檔! 這是非常棒的工具組!你一定要知道如何使用 getsebool 與 setsebool 才行!


7.4.5 SELinux 登錄檔記錄所需服務

上述的指令功能當中,尤其是 setsebool, chcon, restorecon 等,都是為了當你的某些網路服務無法正常提供相關功能時, 才需要進行修改的一些指令動作。但是,我們怎麼知道哪個時候才需要進行這些指令的修改啊?我們怎麼知道系統因為 SELinux 的問題導致網路服務不對勁啊?如果都要靠用戶端連線失敗才來哭訴,那也太沒有效率了!所以,我們的 CentOS 5.x 有提供一支偵測的服務在登錄 SELinux 產生的錯誤喔!那就是 setroubleshoot 。


幾乎所有 SELinux 相關的程式都會以 se 為開頭,這個服務也是以 se 為開頭!而 troubleshoot 大家都知道是錯誤克服, 因此這個 setroubleshoot 自然就得要啟動他啦!這個服務會將關於 SELinux 的錯誤訊息與克服方法記錄到 /var/log/messages 裡頭,所以你一定得要啟動這個服務才好。啟動這個服務之前當然就是得要安裝它啦!這玩意兒總共需要兩個軟體,分別是 setroublshoot 與 setroubleshoot-server,如果你沒有安裝,請自行使用 yum 安裝吧! 那如何在開機的時候就啟動 setroubleshoot 呢?這樣處理先:

[root@www ~]# chkconfig --list setroubleshoot
setroubleshoot  0:off  1:off  2:off 3:on  4:on  5:on  6:off
# 我們的 Linux 運作模式是在 3 或 5 號,因此這兩個要 on 即可。

[root@www ~]# chkconfig setroubleshoot on
# 關於 chkconfig 我們會在後面章節介紹, --list 是列出目前的執行等級是否有啟動,
# 如果加上 on ,則是在開機時啟動,若為 off 則開機時不啟動。

這支服務預設幾乎都會啟動啦!除非你看到 3:off 或 5:off 時,才需要以『 chkconfig setroubleshoot on 』 去設定一下。那麼如果有發生錯誤時,訊息像什麼呢?我們使用 httpd 這支程式產生的錯誤來說明好了。假設你需要啟動 WWW 伺服器, 我們的 WWW 是由 httpd 這支服務提供的,因此你必須要安裝且啟動它才行:

[root@www ~]# yum install httpd
[root@www ~]# /etc/init.d/httpd start
[root@www ~]# netstat -tlnp | grep http
tcp     0   0 :::80   :::*              LISTEN      2455/httpd
tcp     0   0 :::443  :::*              LISTEN      2455/httpd
# 看到沒?有啟動 port 80 了!這是重點!

這個時候我們的 WWW 伺服器就安裝妥當了。我們的首頁其實是放置到 /var/www/html 目錄下的,且檔名必須要是 index.html。 那如果我使用底下的模式來進行首頁的處理時,可能就會產生 SELinux 的問題了!我們就來模擬一下出問題的狀況吧!

[root@www ~]# echo "My first selinux check" & index.html
[root@www ~]# ll index.html
-rw-r--r-- 1 root root 23  9月 20 23:27 index.html  <==權限沒問題
[root@www ~]# mv index.html /var/www/html

此時我們就可以打開瀏覽器,然後在瀏覽器上面輸入 Linux 自己的 IP 來查察看,看能不能連上自己的 WWW 首頁。 記得網址列需要這樣輸入才行:http://localhost/index.html,你會看到如下的畫面喔:

SELinux 出錯示意圖
圖 7.4-3、SELinux 出錯示意圖

畫面最明顯的地方就是告訴你,你並沒有權限可以存取 index.html 的!見鬼了!明明權限是對的喔!那怎辦? 沒關係,就透過 setroubleshoot 的功能去檢查看看。此時請分析一下 /var/log/messages 的內容吧!有點像這樣:

[root@www ~]# cat /var/log/messages | grep setroubleshoot
Sep 20 23:29:55 www setroubleshoot: SELinux is preventing the httpd from 
using potentially mislabeled files (/var/www/html/index.html). For complete 
SELinux messages. run sealert -l 077202c1-561a-4f27-9ba7-bf08e134f006

上面的錯誤訊息可是同一行喔!大綱說的是『SElinux 被用來避免 httpd 讀取到錯誤的安全性本文, 想要查閱完整的資料,請執行 sealert -l ...』沒錯!你注意到了!重點就是 sealert -l 啦! 上面提供的資訊並不完整,想要更完整的說明得要靠 sealert 配合偵測到的錯誤代碼來處理。 實際處理後會像這樣:

[root@www ~]# sealert -l 077202c1-561a-4f27-9ba7-bf08e134f006
Summary:

SELinux is preventing the httpd from using potentially mislabeled files
(/var/www/html/index.html).  <==就是剛剛 /var/log/messages 的訊息

Detailed Description:        <==底下是更完整的描述!要看!

SELinux has denied httpd access to potentially mislabeled file(s)
(/var/www/html/index.html). This means that SELinux will not allow httpd to use
these files. It is common for users to edit files in their home directory or tmp
directories and then move (mv) them to system directories. The problem is that
the files end up with the wrong file context which confined applications are not
allowed to access.

Allowing Access:   <==若要允許存取,你需要進行的動作!

If you want httpd to access this files, you need to relabel them using
restorecon -v '/var/www/html/index.html'. You might want to relabel the entire
directory using restorecon -R -v '/var/www/html'.
....(底下省略)....

重點就是上面特殊字體顯示的地方!你只要照著『Allowing Access』裡面的提示去進行處理, 就能夠完成你的 SELinux 類型設定了!比對剛剛我們上個小節提到的 restoreconchcon 你就能夠知道, setroubleshoot 提供的訊息有多有效了吧! 不管出了啥 SELinux 的問題,絕大部分在 setroubleshoot 的服務中就會告訴你解決之道!所以,很多東西都不用背的!


如果每次測試都得要到 /var/log/messages 去分析,那真是挺麻煩的啊!沒關係,我們可以透過 email 或 console 的方式來將資訊產生! 也就是說,我們可以讓 setroubleshoot 主動的發送產生的資訊到我們指定的 email ,這樣可以方便我們即時的分析喔!怎麼辦到? 就修改 setroubleshoot 的設定檔即可。你可以查閱 /etc/setroubleshoot/setroubleshoot.cfg 這個檔案的內容, 我們只需要修改的地方如下:

[root@www ~]# vim /etc/setroubleshoot/setroubleshoot.cfg
[email]
# 大約在 76 行左右,這行要存在才行!
recipients_filepath = /var/lib/setroubleshoot/email_alert_recipients

# 大約在 169 行左右,將原本的 False 修改成 True 先!
console = True

[root@www ~]# vim /var/lib/setroubleshoot/email_alert_recipients
root@localhost
your@email.address

[root@www ~]# /etc/init.d/setroubleshoot restart

之後你就可以透過分析你的 email 來取得 SELinux 的錯誤訊息囉!非常的簡單吧!只是要注意,上述的填寫 email 的檔案中, 不能只寫帳號,你要連同 @localhost 都寫上,這樣本機上面的 root 才能收到信件喔!就這麼簡單哩! ^_^


我們來簡單的做個總結吧!因為你的網路連線要通過 SELinux 才的權限判定後才能夠繼續 rwx 的權限比對。而 SELinux 的比對主要又分為: (1)需要通過政策的各項規則比對後 (2)才能夠進行 SELinux type 安全性本文的比對,這兩項工作都得要正確才行。而後續的 SELinux 修改主要是透過 chcon, restorecon, setsebool 等指令來處理的。但是如何處理呢?可以透過分析 /var/log/messages 內提供的 setroubleshoot 的資訊來處置!這樣就很輕鬆的可以管理你的 SELinux 囉!

但是如果因為某些原因,舉例來說 CentOS 沒有規範到的 setroubleshoot 資訊時,可能你還是無法瞭解到事情到底是哪裡出錯。 那此時我們會這樣建議:

  1. 在服務與 rwx 權限都沒有問題,卻無法成功的使用網路服務時;
  2. 先使用 setenforce 0 設定為寬容模式;
  3. 再次使用該網路服務,如果這樣就能用,表示 SELinux 出問題,請往下繼續處理。如果這樣還不能用,那問題就不是在 SELinux 上面!請再找其他解決方法,底下的動作不適合你;
  4. 分析 /var/log/messages 內的資訊,找到 sealert -l 相關的資訊並且執行;
  5. 找到 Allow Access 的關鍵字,照裡面的動作來進行 SELinux 的錯誤克服;
  6. 處理完畢重新 setenforce 1 ,再次測試網路服務吧!

這樣就能夠很輕鬆的管理你的 SELinux 啦!不需要想太多!分析登錄檔就對啦!


7.5 被攻擊後的主機修復工作

如果你的主機被攻擊而被取得操縱權的話,而你也由於瞭解到主機監控的需要,所以在最短的時間內發現此一事件, 那麼該如何針對這個被入侵的主機來修復?那如果你要修復的話,你這個網管人員還需要哪些額外的技能? 底下我們就來談一談。


7.5.1 網管人員應具備的技能

從本章第一小節的分析當中,你會發現網管還真的是挺累的,他需要對作業系統有一定程度的熟悉, 對於程序的運作與權限概念則需要更瞭解,否則就麻煩了!那除了作業系統的基本概念之外, 咱們網管還需要啥特殊技巧呢?當然需要啊!其實一部主機最常發生問題的狀況, 都是由『內部的網路誤用所產生的』,所以啊,你只管好主機而已是『沒有辦法杜絕問題』的啦! 底下就來談談你還需要啥技巧呢?


7.5.2 主機受攻擊後復原工作流程

所謂『百密一疏』啊,人不是神,總會有考慮不週的情況,萬一你的主機就因為這『一疏』導致被入侵了, 那該怎麼辦?由上面的說明當中,我們知道『木馬』是很嚴重的,因為他會在你的系統下開個後門 (Back door) 讓攻擊者可以登入你的主機,而且還會竄改你 Linux 上面的程式,讓你找不到該木馬程式!怎麼辦?

很多朋友都習慣『反正只要將 root 的密碼改回來就好了』 這樣的觀點,事實上,那樣一部主機還是有被做為中繼站的危險啊!所以, 萬一你的主機被入侵了,最好的方法還是『重新安裝Linux 』會比較乾淨

那該如何重新安裝呢?很多朋友一再地安裝,卻一再地被入侵∼為什麼呢?因為他沒有『記取教訓』啊!呵呵! 底下我們就來談一談,一部被入侵的主機應該如何修復比較好?

  1. 立即拔除網路線:

    既然發現被入侵了,那麼第一件事情就是拿掉網路功能!拿掉網路功能最簡單的作法自然就是拔掉網路線了! 事實上,拿掉網路線最主要的功能除了保護自己之外,還可以保護同網域的其他主機。怎麼說呢?舉個 2003 年 8 月發病的疾風病毒好了,他會感染同網域之內的其他主機喔!所以,拔除網路線之後,遠端的攻擊者立即就無法進入你的 Linux 主機,而且你還可以保護網域內的其他相關主機啊!

  2. 分析登錄檔資訊,搜尋可能的入侵途徑:

    被入侵之後,決不是只要重新安裝就好,還需要額外分析 『為什麼我的主機這一次會被入侵,對方是如何入侵的?』, 如果你能夠找出問題點,那麼不但你的 Linux 功力立刻增強了,主機也會越來越安全喔! 而如果你不知道如何找出被入侵的可能途徑,那麼重新安裝後,下次還是可能被以同樣的方法入侵啊! 粉麻煩的啦!好了,那該如何找出入侵的途徑呢?

    • 分析登錄檔:低級的 cracker 通常僅是利用工具軟體來入侵你的系統,所以我們可以藉由分析一些主要的登錄檔來找出對方的 IP 以及可能有問題的漏洞。可以分析 /var/log/messages, /var/log/secure 還有利用 last 指令來找出上次登入者的資訊。

    • 檢查主機開放的服務:很多 Linux 使用者常常不曉得自己的系統上面開了多少的服務?我們說過,每個服務都有其漏洞或者是不應該啟用的增強型或者是測試型功能, 所以,找出你系統上面的服務,並且檢查一下每個服務是否有漏洞,或者是在設定上面有了缺失,然後一個一個的整理吧!

    • 查詢 Internet 上面的安全通報: 透過安全通報來瞭解一下最新的漏洞資訊,說不定你的問題就在上面!

  3. 重要資料備份:

    主機被入侵後,顯得問題相當的嚴重,為什麼呢?因為主機上面有相當重要的資料啊!如果主機上面沒有重要的資料, 那麼直接重新安裝就好了!所以,被入侵之後,檢查完了入侵途徑,再來就是要備份重要的資料了。 好了,問個問題,什麼是『重要資料』?who, ps, ls 等等指令是重要資料嗎?還是 httpd.conf 等設定檔是重要資料?又或者是 /etc/passwd, /etc/shadow 才是重要資料?

    呵呵!基本上,重要的資料應該是『非 Linux 系統上面原有的資料』,例如 /etc/passwd, /etc/shadow, WWW 網頁的資料, /home 裡面的使用者重要檔案等等,至於 /etc/*, /usr/, /var 等目錄下的資料,就不見得需要備份了。 注意:不要備份一些 binary 執行檔,因為 Linux 系統安裝完畢後本來就有這些檔案,此外, 這些檔案也很有可能『已經被竄改過了』,那備份這些資料,反而造成下次系統還是不乾淨!

  4. 重新全新安裝:

    備份完了資料,再來就是重新安裝 Linux 系統了。而在這次的安裝中, 你最好選擇適合你自己的安裝套件即可,不要全部套件都給他安裝上去啊!挺危險的!

  5. 套件的漏洞修補:

    記得啊,重新安裝完畢之後,請立即更新你的系統套件,否則還是會被入侵的啦!鳥哥喜歡先在其他比較乾淨的環境下將 Internet 上面的漏洞修補套件下載下來,然後燒錄起來,然後拿到自己的剛剛安裝完成的系統上面,mount CD 之後全部給他更新,更新之後,並且設定了相關的防火牆機制,同時進行下一步驟『 關閉或移除不需要的服務』後,我才將網路線插上主機的網路卡上! 因為鳥哥不敢確定在安裝完畢後,連上 Internet 去更新套件的這段時間,會不會又受到入侵攻擊說....

  6. 關閉或移除不需要的服務:

    這個重要性不需要再講了吧?!啟用越少的服務,系統當然可以被入侵的可能性就比較低。

  7. 資料回復與恢復服務設定:

    剛剛備份的資料要趕緊的複製回來系統,同時將系統的服務再次的重新開放,請注意, 這些服務的設定最好能夠再次的確認一下,避免一些不恰當的設定參數在裡頭喔!

  8. 連上 Internet:

    所有的工作都進行的差不多了,那麼才將剛剛拿掉的網路線接上來吧!恢復主機的運作了!

經過這一連串的動作後,你的主機應該會恢復到比較乾淨的環境,此時還不能掉以輕心, 最好還是參考防火牆的設定,並且多方面的參考 Internet 上面一些老手的經驗,好讓你的主機可以更安全一些!


重點回顧

課後練習

參考資料與延伸閱讀

2002/08/12:第一次完成日期!
2003/08/23:重新編排與增加重點回顧、課後練習
2006/08/31:將舊的文章移動到此處
2006/09/06:增加 SELinux 的簡單說明,增加 ACL 的控制項目!
2010/09/06:將舊的基於 CentOS 4.x 撰寫的文章移動至此處
2010/09/09:因為單純使用 CentOS ,因此取消了 apt 的更新功能囉!
2010/09/21:將舊的 限制連線埠口網路升級套件 挪動到新的目錄去了!
2010/09/21:還有許多資料包括(1)重點回顧/(2)課後練習/(3)延伸閱讀的部分都還沒有彙整好。只是先公告這一版而已。