Linux伺服器 Linux伺服器

伺服器建置實務上課教材

伺服器建置實務 > 課程內容 > 第 6 堂課 - 基礎的系統防護處理

第 6 堂課 - 基礎的系統防護處理

上次更新日期 2018/11/04

上次的課程談到過,其實,防火牆只是用來防護某些你不想讓它進入的來源 IP 位址,或者是某些你要保護的服務而已。 事實上,針對開放的服務,例如對外放行的 WWW 服務來說,防火牆是完全沒有用途的!因此,這個時候確定你的服務沒有問題, 同時如果有用到程式碼的話,那麼你也得確認你的程式碼 (PHP 之類的) 沒問題才行喔!

  • 6.1: 本機防護工作分析
  • 6.2: 軟體更新
  • 6.3: 網路服務的觀察與關閉
  • 6.4: 本日練習
  • 6.5: 課後練習

6.1: 本機防護工作分析

如果是沒有上網的主機系統,你不要防火牆、完全不要更新軟體,只是單純的使用,那是沒有問題的!畢竟,只有你可以使用『物理接觸』的方式去接觸它, 所以,當然沒有任何防護也沒關係。反而是你可能需要增加物理鎖,或者是增加本機登入時的身份認證功能即可。但是,以目前的電腦系統操作而言, 這是很奇怪的一件事!因為,幾乎所有的作業系統都是網路作業系統,都有提供網路,主機也預設已經都有網路卡,所以, 想要沒有網路,還真是困難。因此,我們才需要進行本機的防護啊!

那麼,本機應該如何進行來自網路的攻擊呢?我們先來分析一下封包進入本機時,要經過什麼流程。同時,你得要知道, 為什麼人家要連線到你的主機啊?通常就是你有提供什麼資料給人家使用啊!舉例來說,網頁設計完畢放在網路上, 人家就是讀你的網頁檔案。資料庫系統購物車做好了,人家來到你的主機就是要讀寫資料庫!因此,都跟你的主機資源有關。 好了,那麼封包進入你的主機流程就是這樣的:

封包進入本機的流程

上述的圖示可以這樣展示:

  1. 先要通過 TCP/IP 的相關規範才能夠連線到本機的網路門口 (所以要有 public IP)
  2. 要先通過防火牆的規則管制,才可以進入到本機使用本機的服務 (防火牆設計)
  3. 能否取得服務與這個服務是否啟用與相關設定有關 (發生問題可以查登錄檔)
  4. 能否實際存取資料,首先要看有沒有啟動 SELinux 這個細部權限設定項目?目前建議直接取消此項工作。
  5. 全部都放行後,最後能不能存取資料,還是跟資料檔案的權限 (rwx) 有關!
  • 關閉 SELinux 成為 Permissive 模式

關於上述的 1, 2, 3, 5 重點,我們前面的課程大約已經講過了,你得要先有一些概念才行。那麼那個 SELinux 是啥呢?基本上, 他是一個細部權限設定的機制,對於初次接觸 Linux 的朋友來說,這個東西很有點困擾!同時,它對於自己寫的程式碼 (類似 PHP) 有點限制,對於大家未來設計畢業專題,會有點傷腦筋。因此,建議初次接觸的朋友,先將它關閉,未來有興趣再來玩它。 那麼如何關閉呢?基本上,上 getenforce 出現 Permissive 這個關鍵字就可以了!流程如下:

# 先確認目前的 SELinux 是在哪一種模式底下:
[root@localhost ~]# getenforce
Enforcing

# 我們希望是在 Permissive 模式,因此,請修改設定檔:
[root@localhost ~]# vim /etc/selinux/config
# 找到底下這一行:
SELINUX=enforcing
# 改成這個樣子
SELINUX=permissive

# 嘗試重新開機
[root@localhost ~]# reboot

# 開機完畢重新登入,再次測驗 SELinux 模式:
[root@localhost ~]# getenforce
Permissive
  • 哪一個流程管制最有效?是防火牆、軟體升級?

很多初次接觸主機系統的朋友,都很容易被『防火牆』這個專有名詞搞混~真的有防火牆就一切沒有問題嘛?來來來! 讓我們來分析一下,防火牆有沒有效果呢?

  1. 防火牆對於一般正常的服務,是沒有保護效果的
    從前一個項目的圖示來看,如果你是 WWW 伺服器,那一定就是要放行 port 80,因此,若 port 80 出問題,那你的防火牆當然一點用處也沒有。
  2. 如果是限制某些來源的登入,那防火牆是一定需要的保護:
    如果你的服務中,例如 ssh 的服務,僅放行給部份的來源 IP 位址,則此時防火牆保護危險的服務,就很有用處了!
  3. 升級軟體才是王道:
    一般來說,軟體如果沒有問題,或沒有加入新功能,是不會隨意升級的。因此,如果官網有公告最新的軟體升級資訊, 當然最好就是一定要升級到最新!至少能夠預防一大堆可能的系統漏洞

所以說,不要再被騙了!防火牆其實只能用於保護你想要保護的服務,就是說,防火牆只能保護比較危險的服務 (通常就是有 login 功能的軟體)。 但是對於直接對 Internet 放行的服務來說,防火牆是沒屁用的!這點你一定要很明白清楚!

6.2: 軟體更新

根據本章最早的一張圖示,我們知道防火牆前面的章節已經介紹過,網路的參數設定,也已經談過了,那麼再來當然就是要達成:

  • 伺服器軟體的更新
  • 僅開放需要的伺服器軟體
  • 指定最近的 yum 更新伺服器達成本機系統更新

上面這兩件大事了。關於伺服器軟體的更新,我們在網路參數設計裡面已經處理過了,但是,當時處理的是讓系統自己找出最恰當的伺服器, 自動進行升級。不過,有時候系統會找錯耶~我們已經知道崑山自己內部有 FTP 伺服器提供了 CentOS 7 的升級套件, 那麼,能不能『指定我們的系統從崑山去抓取資料,而不要連到外部系統』呢?當然是可以的!按照底下的作法來處理即可:

  1. 先從 http://ftp.ksu.edu.tw 找到正確的容器對應網址 (請在虛擬機做):
    1. 點選上面的連結,進入新的頁面,點下 CentOS 之後,會看到一堆目錄。
    2. 在我們的版本,就是 7 的版本上面按下右鍵,選擇『新分頁開啟』
    3. 新出現的連結中,跟我們系統的預設資料對應如下 (左側是網頁,右側是 Linux 系統的名稱對應):
      • 原版光碟釋出的軟體:os --> base
      • 系統運作期間出現的更新軟體: updates --> updates
      • 原廠額外提供的其他軟體: extras --> extras
    4. 但是由於系統還有所謂的 32 位元與 64 位元的差別,點進去上面的任何一個連結,還會有個 x86_64 的目錄,再點進去後, 你看到一個關鍵目錄,名稱為『 repodata 』那個目錄是軟體清單的列表目錄,看到該目錄即可, 不要點進去!此時的網址,就是你需要的網址了!舉例來說,原本光碟的網址應該就是:
      http://ftp.ksu.edu.tw/FTP/Linux/CentOS/7/os/x86_64/
  2. 修改 /etc/yum.repos.d/ 這個目錄的內容,基本上,以原廠的資訊來說,我們要修改的是 /etc/yum.repos.d/CentOS-Base.repo 這個檔案, 同時依照上面找到的網址,你可以進行如下的修改 (記得,要改三個地方喔!)
    [root@localhost ~]# vim /etc/yum.repos.d/CentOS-Base.repo
    # 原本的模樣:
    [base]
    name=CentOS-$releasever - Base
    mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=os&infra=$infra
    #baseurl=http://mirror.centos.org/centos/$releasever/os/$basearch/
    gpgcheck=1
    gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
    
    # 應該要改成這樣
    [base]
    name=CentOS-$releasever - Base
    #mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=os&infra=$infra
    baseurl=http://ftp.ksu.edu.tw/FTP/Linux/CentOS/7/os/x86_64/
    gpgcheck=1
    gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
    
    其他兩個地方 (updates, extras) 請自行修改喔!
  3. 由於我們更新過設定檔,因此需要將過去的快取資料清除,之後才進行整體更新。大致的處理流程為:
    [root@localhost ~]# yum clean all
    [root@localhost ~]# yum update
    

這樣就可以取用最近的 CentOS 更新伺服器來進行我們本機系統的更新行為~比較快之外,也可以節省頻寬喔! 不過,有升級到核心或重要的函式庫,最好重新開機,才能使用到最新的核心與函式庫功能,這點也需要留意! 通常,第一次進行全系統更新後,應該就是要重新開機啦。

  • 讓系統自動定期更新的手段

基本上,系統管理員大概不會手動操作系統更新的 (除了第一次),通常是進行一些例行工作排程,讓系統自動的在某個時間點更新。 要注意的是,系統預設的最短時間點為『分鐘』,所以,你可能沒有辦法規範秒鐘來執行工作的。

系統的工作排程主要是透過 crond 這個服務,所以,請檢查 crond 有沒有啟動呢?

[root@localhost ~]# systemctl status crond
● crond.service - Command Scheduler
   Loaded: loaded (/usr/lib/systemd/system/crond.service; enabled; vendor preset: enabled)
   Active: active (running) since 日 2018-11-04 23:48:42 CST; 34min ago
 Main PID: 7866 (crond)
    Tasks: 1
   CGroup: /system.slice/crond.service
           └─7866 /usr/sbin/crond -n

確認啟動之後,接下來我們就可以去查看 /etc/crontab 這個檔案了!在打開這個檔案後,你會看到一堆東西! 基本上,就是 5 個數字,一個身份,加上一串指令這樣。那 5 個數字口訣:『分、時、日、月、周』,很簡單吧! 詳細的來說,大概就如同下表:

代表意義分鐘小時 日期月份指令
數字範圍0-590-231-311-120-7 指令最好使用絕對路徑

週的數字為 0 或 7 時,都代表『星期天』的意思!另外,還有一些輔助的字符,大概有底下這些:

特殊字符代表意義
*(星號)代表任何時刻都接受的意思!舉例來說,範例一內那個日、月、週都是 * , 就代表著『不論何月、何日的禮拜幾的 12:00 都執行後續指令』的意思!
,(逗號)代表分隔時段的意思。舉例來說,如果要下達的工作是 3:00 與 6:00 時,就會是:
0 3,6 * * * command
時間參數還是有五欄,不過第二欄是 3,6 ,代表 3 與 6 都適用!
-(減號)代表一段時間範圍內,舉例來說, 8 點到 12 點之間的每小時的 20 分都進行一項工作:
20 8-12 * * * command
仔細看到第二欄變成 8-12 喔!代表 8,9,10,11,12 都適用的意思!
/n(斜線)那個 n 代表數字,亦即是『每隔 n 單位間隔』的意思,例如每五分鐘進行一次,則:
*/5 * * * * command
用 * 與 /5 來搭配,也可以寫成 0-59/5 ,相同意思!

我要讓系統自動的在每天的 2 點,使用 root 的身份進行自動更新的行為。同時,將更新的過程寫入到 /root/yum.log 檔案去。 你應該要注意的是:
  • 修改哪一個檔案
  • 使用哪個身份來進行?
  • 要使用 /bin/yum update 還是 /bin/yum -y update 比較好?
  • 輸出訊息可以使用 &>> 來處理資料導向的問題。

6.3: 網路服務的觀察與關閉

如果你的主機並沒有啟用任何的網路服務,亦即沒有啟動任何的埠口時,老實說,你沒有安裝或啟動防火牆, 其實都沒有影響的!想像一下,銀行的窗口 (port) 裡面沒有人 (service),那你 (cracker) 是要跟誰溝通? 沒辦法,對吧!因此,在一部對外公開服務的伺服器上,減少不必要的網路服務,對你來說,應該是最重要的!

  • 觀察本機的網路服務埠口

觀察埠口就是透過 netstat -tlunp 來處理,那你現在也知道了 TCP 與 UDP 的封包格式,所以 -t, -u 也都知道原因了! 那就來觀察看看:

[root@localhost ~]# netstat -tlulnp
Proto Recv-Q Send-Q Local Address      Foreign Address     State     PID/Program name
tcp        0      0 0.0.0.0:22         0.0.0.0:*           LISTEN    7392/sshd
tcp        0      0 127.0.0.1:631      0.0.0.0:*           LISTEN    7308/cupsd
tcp        0      0 127.0.0.1:25       0.0.0.0:*           LISTEN    1140/master
tcp6       0      0 :::22              :::*                LISTEN    7392/sshd
tcp6       0      0 ::1:631            :::*                LISTEN    7308/cupsd
tcp6       0      0 ::1:25             :::*                LISTEN    1140/master
udp        0      0 0.0.0.0:5353       0.0.0.0:*                     7476/avahi-daemon:
udp        0      0 0.0.0.0:53436      0.0.0.0:*                     7476/avahi-daemon:

如上所示,目前現階段除了 port 22, port 25 之外,其他的埠口基本上都能夠關閉才好!因此,請關閉除了 22 及 25 之外的其他埠口吧! 我們以關閉 port 631 為例,基本上可以這樣做:

# 1. 先找到該服務的名稱:
[root@localhost ~]# systemctl list-unit-files | grep cups
cups.path                                     enabled
cups-browsed.service                          disabled
cups.service                                  enabled
cups.socket                                   enabled

# 2. 將上面 enabled 的服務,通通『立刻』關閉
[root@localhost ~]# systemctl stop cups.path cups.service cups.socket

# 3. 將上面的幾個服務通通設定為『下次開機不會啟動』的模樣:
[root@localhost ~]# systemctl disable cups.path cups.service cups.socket

如上所示,最終那個 port 631 就會被關閉了!

完成如下的練習:
  1. 先用 netstat 檢查一下本機有啟動的網路埠口共有哪些?
  2. 先自己分析一下,哪些是需要的埠口?哪些是不需要的埠口?
  3. 透過 systemctl 關閉不要的埠口,且下次開機,這些埠口也不會啟用!
  4. 最後只剩下 port 22 及 port 25 !

6.4: 本日練習

現在來複習一下今日的動作,作為本日的點名與查驗資訊。請在目前的雲端機器上面完成底下的實做,要完成且讓老師檢查完畢後,才可以離開教室喔!

  1. 讓 SELinux 永遠在 permissive 的模式下
  2. 讓系統關閉到剩下 port 22 以及 port 25 ,其他的埠口請暫時關閉,且重新開機這個服務也不會啟動。
  3. 讓你的 yum 指向崑山的 FTP 伺服器,且放行 os, updates 與 extras
  4. 讓你的系統每天 2:15 點自動進行一次全系統升級

完成之後請告知老師你的學號與 IP 尾數,老師即可檢測你的設定狀態了。

6.5: 課後練習

請撰寫一個 word 檔案,檔名為:『 unit06-A050cxxx-你的名字.docx 』,內容回答下列問題,然後每週作業上傳到對應的 EP 上面去:

  1. 例行工作排程主要的服務是哪一個?
  2. 例行性工作排程中,我們主要修改的設定檔的檔名為何?
  3. 上述的檔案中,裡面有 5 個數值,請寫出口訣:
  4. 哪一個指令搭配的參數可以觀察你的機器啟動的埠口號碼以及列出 PID 與程式名稱
  5. 如何『立刻』關閉名為 abc 的服務?
  6. 如何『讓下次開機也不會啟動』這個名為 abc 的服務?
  7. yum 的設定檔主要是哪一個?
  8. 如何進行全系統升級 (指令與參數)

同場加映:不用上傳的資料,請 google 一下打字時,手指與鍵盤指法的對應,然後自由練習底下的資訊:

  • 小寫的 a~z (abcdefg...xyz) ,共打 10 次
  • 小寫的 0~9,a~z (012..89abcdefg...xyz) ,共打 10 次
  • 不要啟動大寫燈,用組合按鍵輸入 A-Z (ABCD...XYZ),共 10 次

每天上課各練一次,最慢 10 天,你的打字就會嚇嚇叫了!