認識 daemons 可重要了,能夠更清楚的瞭解服務的啟動與運作方式!
在 Unix-Like 的系統中,你會常常聽到 daemon 這個字眼!那麼什麼是傳說中的 daemon 呢?這些 daemon 放在什麼地方?他的功能是什麼?該如何啟動這些 daemon ?又如何有效的將這些 daemon 管理妥當?此外,要如何視察這些 daemon 開了多少個 ports ?又這些 ports 要如何關閉?還有還有,曉得你系統的這些 port 各代表的是什麼服務嗎? 這些都是最基礎需要注意的呢!尤其是在架設網站之前,這裡的觀念就顯的更重要了。
從 CentOS 7.x 這一版之後,傳統的 init 已經被捨棄,取而代之的是 systemd 這個傢伙~這傢伙跟之前的 init 有什麼差異? 優缺點為何?如何管理不同種類的服務類型?以及如何取代原本的『執行等級』等等,很重要的改變喔!
我們在第十六章就曾經談過『服務』這東西! 當時的說明是『常駐在記體體中的程序,且可以提供一些系統或網路功能,那就是服務』。而服務一般的英文說法是『 service 』。
但如果你常常上網去查看一些資料的話,尤其是 Unix-Like 的相關作業系統,應該常常看到『請啟動某某 daemon 來提供某某功能』,唔!那麼 daemon 與 service 有關囉?否則為什麼都能夠提供某些系統或網路功能?此外,這個 daemon 是什麼東西呀? daemon 的字面上的意思就是『守護神、惡魔?』還真是有點奇怪呦!^_^""!
簡單的說,系統為了某些功能必須要提供一些服務 (不論是系統本身還是網路方面),這個服務就稱為 service 。 但是 service 的提供總是需要程式的運作吧!否則如何執行呢?所以達成這個 service 的程式我們就稱呼他為 daemon 囉! 舉例來說,達成循環型例行性工作排程服務 (service) 的程式為 crond 這個 daemon 啦!這樣說比較容易理解了吧!
一般來說,當我們以文字模式或圖形模式 (非單人維護模式) 完整開機進入 Linux 主機後, 系統已經提供我們很多的服務了!包括列印服務、工作排程服務、郵件管理服務等等; 那麼這些服務是如何被啟動的?他們的工作型態如何?底下我們就來談一談囉!
還記得我們在第一章談到過 Unix 的 system V 版本吧?那個很純種的 Unix 版本~ 在那種年代底下,我們啟動系統服務的管理方式被稱為 SysV 的 init 腳本程式的處理方式!亦即系統核心第一支呼叫的程式是 init , 然後 init 去喚起所有的系統所需要的服務,不論是本機服務還是網路服務就是了。
基本上 init 的管理機制有幾個特色如下:
基本上 init 主要的功能都寫在上頭了,重要的指令包括 daemon 本身自己的腳本 (/etc/init.d/daemon) 、xinetd 這個特殊的總管程式 (super daemon)、設定預設開機啟動的 chkconfig, 以及會影響到執行等級的 init N 等。雖然 CentOS 7 已經不使用 init 來管理服務了,不過因為考量到某些腳本沒有辦法直接塞入 systemd 的處理,因此這些腳本還是被保留下來, 所以,我們在這裡還是稍微介紹了一下。更多更詳細的資料就請自己查詢舊版本囉!如下就是一個可以參考的版本:
從 CentOS 7.x 以後,Red Hat 系列的 distribution 放棄沿用多年的 System V 開機啟動服務的流程,就是前一小節提到的 init 啟動腳本的方法, 改用 systemd 這個啟動服務管理機制~那麼 systemd 有什麼好處呢?
雖然如此,不過 systemd 也是有些地方無法完全取代 init 的!包括:
不過,光是同步啟動服務腳本這個功能就可以節省你很多開機的時間~同時 systemd 還有很多特殊的服務類型 (type) 可以提供更多有趣的功能!確實值得學一學~ 而且 CentOS 7 已經用了 systemd 了!想不學也不行啊~哈哈哈!好~既然要學,首先就得要針對 systemd 管理的 unit 來了解一下。
基本上, systemd 將過去所謂的 daemon 執行腳本通通稱為一個服務單位 (unit),而每種服務單位依據功能來區分時,就分類為不同的類型 (type)。 基本的類型有包括系統服務、資料監聽與交換的插槽檔服務 (socket)、儲存系統狀態的快照類型、提供不同類似執行等級分類的操作環境 (target) 等等。 哇!這麼多類型,那設定時會不會很麻煩呢?其實還好,因為設定檔都放置在底下的目錄中:
也就是說,到底系統開機會不會執行某些服務其實是看 /etc/systemd/system/ 底下的設定,所以該目錄底下就是一大堆連結檔。而實際執行的 systemd 啟動腳本設定檔, 其實都是放置在 /usr/lib/systemd/system/ 底下的喔!因此如果你想要修改某個服務啟動的設定,應該要去 /usr/lib/systemd/system/ 底下修改才對! /etc/systemd/system/ 僅是連結到正確的執行腳本設定檔而已。所以想要看執行腳本設定,應該就得要到 /usr/lib/systemd/system/ 底下去查閱才對!
那 /usr/lib/systemd/system/ 以下的資料如何區分上述所謂的不同的類型 (type) 呢?很簡單!看副檔名!舉例來說,我們來瞧瞧上一章談到的 vsftpd 這個範例的啟動腳本設定, 還有 crond 與純文字模式的 multi-user 設定:
[root@study ~]# ll /usr/lib/systemd/system/ | grep -E '(vsftpd|multi|cron)' -rw-r--r--. 1 root root 284 7月 30 2014 crond.service -rw-r--r--. 1 root root 567 3月 6 06:51 multipathd.service -rw-r--r--. 1 root root 524 3月 6 13:48 multi-user.target drwxr-xr-x. 2 root root 4096 5月 4 17:52 multi-user.target.wants lrwxrwxrwx. 1 root root 17 5月 4 17:52 runlevel2.target -> multi-user.target lrwxrwxrwx. 1 root root 17 5月 4 17:52 runlevel3.target -> multi-user.target lrwxrwxrwx. 1 root root 17 5月 4 17:52 runlevel4.target -> multi-user.target -rw-r--r--. 1 root root 171 6月 10 2014 vsftpd.service -rw-r--r--. 1 root root 184 6月 10 2014 vsftpd@.service -rw-r--r--. 1 root root 89 6月 10 2014 vsftpd.target # 比較重要的是上頭提供的那三行特殊字體的部份!
所以我們可以知道 vsftpd 與 crond 其實算是系統服務 (service),而 multi-user 要算是執行環境相關的類型 (target type)。根據這些副檔名的類型, 我們大概可以找到幾種比較常見的 systemd 的服務類型如下:
副檔名 | 主要服務功能 |
.service | 一般服務類型 (service unit):主要是系統服務,包括伺服器本身所需要的本機服務以及網路服務都是!比較經常被使用到的服務大多是這種類型! 所以,這也是最常見的類型了! |
.socket | 內部程序資料交換的插槽服務 (socket unit):主要是 IPC (Inter-process communication) 的傳輸訊息插槽檔 (socket file) 功能。 這種類型的服務通常在監控訊息傳遞的插槽檔,當有透過此插槽檔傳遞訊息來說要連結服務時,就依據當時的狀態將該用戶的要求傳送到對應的 daemon, 若 daemon 尚未啟動,則啟動該 daemon 後再傳送用戶的要求。 使用 socket 類型的服務一般是比較不會被用到的服務,因此在開機時通常會稍微延遲啟動的時間 (因為比較沒有這麼常用嘛!)。一般用於本機服務比較多,例如我們的圖形界面很多的軟體都是透過 socket 來進行本機程序資料交換的行為。 (這與早期的 xinetd 這個 super daemon 有部份的相似喔!) |
.target | 執行環境類型 (target unit):其實是一群 unit 的集合,例如上面表格中談到的 multi-user.target 其實就是一堆服務的集合~也就是說, 選擇執行 multi-user.target 就是執行一堆其他 .service 或/及 .socket 之類的服務就是了! |
.mount .automount |
檔案系統掛載相關的服務 (automount unit / mount unit):例如來自網路的自動掛載、NFS 檔案系統掛載等與檔案系統相關性較高的程序管理。 |
.path | 偵測特定檔案或目錄類型 (path unit):某些服務需要偵測某些特定的目錄來提供佇列服務,例如最常見的列印服務,就是透過偵測列印佇列目錄來啟動列印功能! 這時就得要 .path 的服務類型支援了! |
.timer | 循環執行的服務 (timer unit):這個東西有點類似 anacrontab 喔!不過是由 systemd 主動提供的,比 anacrontab 更加有彈性! |
其中又以 .service 的系統服務類型最常見了!因為我們一堆網路服務都是透過這種類型來設計的啊!接下來,讓我們來談談如何管理這些服務的啟動與關閉。
基本上, systemd 這個啟動服務的機制,主要是透過一隻名為 systemctl 的指令來處理的!跟以前 systemV 需要 service / chkconfig / setup / init 等指令來協助不同, systemd 就是僅有 systemctl 這個指令來處理而已呦!所以全部的行為都得要使用 systemctl 的意思啦!有沒有很難?其實習慣了之後, 鳥哥是覺得 systemctl 還挺好用的! ^_^
在開始這個小節之前,鳥哥要先來跟大家報告一下,那就是:一般來說,服務的啟動有兩個階段,一個是『開機的時候設定要不要啟動這個服務』, 以及『你現在要不要啟動這個服務』,這兩者之間有很大的差異喔!舉個例子來說,假如我們現在要『立刻取消 atd 這個服務』時,正規的方法 (不要用 kill) 要怎麼處理?
[root@study ~]# systemctl [command] [unit] command 主要有: start :立刻啟動後面接的 unit stop :立刻關閉後面接的 unit restart :立刻關閉後啟動後面接的 unit,亦即執行 stop 再 start 的意思 reload :不關閉後面接的 unit 的情況下,重新載入設定檔,讓設定生效 enable :設定下次開機時,後面接的 unit 會被啟動 disable :設定下次開機時,後面接的 unit 不會被啟動 status :目前後面接的這個 unit 的狀態,會列出有沒有正在執行、開機預設執行否、登錄等資訊等! is-active :目前有沒有正在運作中 is-enabled:開機時有沒有預設要啟用這個 unit 範例一:看看目前 atd 這個服務的狀態為何? [root@study ~]# systemctl status atd.service atd.service - Job spooling tools Loaded: loaded (/usr/lib/systemd/system/atd.service; enabled) Active: active (running) since Mon 2015-08-10 19:17:09 CST; 5h 42min ago Main PID: 1350 (atd) CGroup: /system.slice/atd.service └─1350 /usr/sbin/atd -f Aug 10 19:17:09 study.centos.vbird systemd[1]: Started Job spooling tools. # 重點在第二、三行喔~ # Loaded:這行在說明,開機的時候這個 unit 會不會啟動,enabled 為開機啟動,disabled 開機不會啟動 # Active:現在這個 unit 的狀態是正在執行 (running) 或沒有執行 (dead) # 後面幾行則是說明這個 unit 程序的 PID 狀態以及最後一行顯示這個服務的登錄檔資訊! # 登錄檔資訊格式為:『時間』 『訊息發送主機』 『哪一個服務的訊息』 『實際訊息內容』 # 所以上面的顯示訊息是:這個 atd 預設開機就啟動,而且現在正在運作的意思! 範例二:正常關閉這個 atd 服務 [root@study ~]# systemctl stop atd.service [root@study ~]# systemctl status atd.service atd.service - Job spooling tools Loaded: loaded (/usr/lib/systemd/system/atd.service; enabled) Active: inactive (dead) since Tue 2015-08-11 01:04:55 CST; 4s ago Process: 1350 ExecStart=/usr/sbin/atd -f $OPTS (code=exited, status=0/SUCCESS) Main PID: 1350 (code=exited, status=0/SUCCESS) Aug 10 19:17:09 study.centos.vbird systemd[1]: Started Job spooling tools. Aug 11 01:04:55 study.centos.vbird systemd[1]: Stopping Job spooling tools... Aug 11 01:04:55 study.centos.vbird systemd[1]: Stopped Job spooling tools. # 目前這個 unit 下次開機還是會啟動,但是現在是沒在運作的狀態中!同時, # 最後兩行為新增加的登錄訊息,告訴我們目前的系統狀態喔!
上面的範例中,我們已經關掉了 atd 囉!這樣作才是對的!不應該使用 kill 的方式來關掉一個正常的服務喔!否則 systemctl 會無法繼續監控該服務的! 那就比較麻煩。而使用 systemtctl status atd 的輸出結果中,第 2, 3 兩行很重要~因為那個是告知我們該 unit 下次開機會不會預設啟動,以及目前啟動的狀態! 相當重要!最底下是這個 unit 的登錄檔~如果你的這個 unit 曾經出錯過,觀察這個地方也是相當重要的!
那麼現在問個問題,你的 atd 現在是關閉的,未來重新開機後,這個服務會不會再次的啟動呢?答案是?當然會! 因為上面出現的第二行中,它是 enabled 的啊!這樣理解所謂的『現在的狀態』跟『開機時預設的狀態』兩者的差異了嗎?
好!再回到 systemctl status atd.service 的第三行,不是有個 Active 的 daemon 現在狀態嗎?除了 running 跟 dead 之外, 有沒有其他的狀態呢?有的~基本上有幾個常見的狀態:
既然 daemon 目前的狀態就有這麼多種了,那麼 daemon 的預設狀態有沒有可能除了 enable/disable 之外,還有其他的情況呢?當然有!
問題:
找到系統中名為 chronyd 的服務,觀察此服務的狀態,觀察完畢後,將此服務設定為: 1)開機不會啟動 2)現在狀況是關閉的情況!
回答:
我們直接使用指令的方式來查詢與設定看看:
# 1. 觀察一下狀態,確認是否為關閉/未啟動呢? [root@study ~]# systemctl status chronyd.service hronyd.service - NTP client/server Loaded: loaded (/usr/lib/systemd/system/chronyd.service; enabled) Active: active (running) since Mon 2015-08-10 19:17:07 CST; 24h ago .....(底下省略)..... # 2. 由上面知道目前是啟動的,因此立刻將他關閉,同時開機不會啟動才行! [root@study ~]# systemctl stop chronyd.service [root@study ~]# systemctl disable chronyd.service rm '/etc/systemd/system/multi-user.target.wants/chronyd.service' # 看得很清楚~其實就是從 /etc/systemd/system 底下刪除一條連結檔案而已~ [root@study ~]# systemctl status chronyd.service chronyd.service - NTP client/server Loaded: loaded (/usr/lib/systemd/system/chronyd.service; disabled) Active: inactive (dead) # 如此則將 chronyd 這個服務完整的關閉了! |
上面是一個很簡單的練習,妳先不要知道 chronyd 是啥東西,只要知道透過這個方式,可以將一個服務關閉就是了!好!那再來一個練習, 看看有沒有問題呢?
問題:
因為我根本沒有印表機安裝在伺服器上,目前也沒有網路印表機,因此我想要將 cups 服務整個關閉,是否可以呢?
回答:
同樣的,眼見為憑,我們就動手作看看:
# 1. 先看看 cups 的服務是開還是關? [root@study ~]# systemctl status cups.service cups.service - CUPS Printing Service Loaded: loaded (/usr/lib/systemd/system/cups.service; enabled) Active: inactive (dead) since Tue 2015-08-11 19:19:20 CST; 3h 29min ago # 有趣得很!竟然是 enable 但是卻是 inactive 耶!相當特別! # 2. 那就直接關閉,同時確認沒有啟動喔! [root@study ~]# systemctl stop cups.service [root@study ~]# systemctl disable cups.service rm '/etc/systemd/system/multi-user.target.wants/cups.path' rm '/etc/systemd/system/sockets.target.wants/cups.socket' rm '/etc/systemd/system/printer.target.wants/cups.service' # 也是非常特別!竟然一口氣取消掉三個連結檔!也就是說,這三個檔案可能是有相依性的問題喔! [root@study ~]# netstat -tlunp | grep cups # 現在應該不會出現任何資料!因為根本沒有 cups 的任務在執行當中~所以不會有 port 產生 # 3. 嘗試啟動 cups.socket 監聽用戶端的需求喔! [root@study ~]# systemctl start cups.socket [root@study ~]# systemctl status cups.service cups.socket cups.path cups.service - CUPS Printing Service Loaded: loaded (/usr/lib/systemd/system/cups.service; disabled) Active: inactive (dead) since Tue 2015-08-11 22:57:50 CST; 3min 41s ago cups.socket - CUPS Printing Service Sockets Loaded: loaded (/usr/lib/systemd/system/cups.socket; disabled) Active: active (listening) since Tue 2015-08-11 22:56:14 CST; 5min ago cups.path - CUPS Printer Service Spool Loaded: loaded (/usr/lib/systemd/system/cups.path; disabled) Active: inactive (dead) # 確定僅有 cups.socket 在啟動,其他的並沒有啟動的狀態! # 4. 嘗試使用 lp 這個指令來列印看看? [root@study ~]# echo "testing" | lp lp: Error - no default destination available. # 實際上就是沒有印表機!所以有錯誤也沒關係! [root@study ~]# systemctl status cups.service cups.service - CUPS Printing Service Loaded: loaded (/usr/lib/systemd/system/cups.service; disabled) Active: active (running) since Tue 2015-08-11 23:03:18 CST; 34s ago [root@study ~]# netstat -tlunp | grep cups tcp 0 0 127.0.0.1:631 0.0.0.0:* LISTEN 25881/cupsd tcp6 0 0 ::1:631 :::* LISTEN 25881/cupsd # 見鬼!竟然 cups 自動被啟動了!明明我們都沒有驅動他啊!怎麼回事啊? |
上面這個範例的練習在讓您了解一下,很多服務彼此之間是有相依性的!cups 是一種列印服務,這個列印服務會啟用 port 631 來提供網路印表機的列印功能。 但是其實我們無須一直啟動 631 埠口吧?因此,多了一個名為 cups.socket 的服務,這個服務可以在『用戶有需要列印時,才會主動喚醒 cups.service 』的意思! 因此,如果你僅是 disable/stop cups.service 而忘記了其他兩個服務的話,那麼當有用戶向其他兩個 cups.path, cups.socket 提出要求時, cups.service 就會被喚醒!所以,你關掉也沒用!
比較正規的作法是,要關閉 cups.service 時,連同其他兩個會喚醒 service 的 cups.socket 與 cups.path 通通關閉,那就沒事了! 比較不正規的作法是,那就強迫 cups.service 註銷吧!透過 mask 的方式來將這個服務註銷看看!
# 1. 保持剛剛的狀態,關閉 cups.service,啟動 cups.socket,然後註銷 cups.servcie [root@study ~]# systemctl stop cups.service [root@study ~]# systemctl mask cups.service ln -s '/dev/null' '/etc/systemd/system/cups.service' # 喔耶~其實這個 mask 註銷的動作,只是讓啟動的腳本變成空的裝置而已! [root@study ~]# systemctl status cups.service cups.service Loaded: masked (/dev/null) Active: inactive (dead) since Tue 2015-08-11 23:14:16 CST; 52s ago [root@study ~]# systemctl start cups.service Failed to issue method call: Unit cups.service is masked. # 再也無法喚醒!
上面的範例你可以仔細推敲一下~原來整個啟動的腳本設定檔被連結到 /dev/null 這個空裝置~因此,無論如何你是再也無法啟動這個 cups.service 了! 透過這個 mask 功能,你就可以不必管其他相依服務可能會啟動到這個想要關閉的服務了!雖然是非正規,不過很有效! ^_^
那如何取消註銷呢?當然就是 unmask 即可啊!
[root@study ~]# systemctl unmask cups.service rm '/etc/systemd/system/cups.service' [root@study ~]# systemctl status cups.service cups.service - CUPS Printing Service Loaded: loaded (/usr/lib/systemd/system/cups.service; disabled) Active: inactive (dead) since Tue 2015-08-11 23:14:16 CST; 4min 35s ago # 好佳在有恢復正常!
上一小節談到的是單一服務的啟動/關閉/觀察,以及相依服務要註銷的功能。那系統上面有多少的服務存在呢?這個時候就得要透過 list-units 及 list-unit-files 來觀察了! 細部的用法如下:
[root@study ~]# systemctl [command] [--type=TYPE] [--all] command: list-units :依據 unit 列出目前有啟動的 unit。若加上 --all 才會列出沒啟動的。 list-unit-files :依據 /usr/lib/systemd/system/ 內的檔案,將所有檔案列表說明。 --type=TYPE:就是之前提到的 unit type,主要有 service, socket, target 等 範例一:列出系統上面有啟動的 unit [root@study ~]# systemctl UNIT LOAD ACTIVE SUB DESCRIPTION proc-sys-fs-binfmt_mis... loaded active waiting Arbitrary Executable File Formats File System sys-devices-pc...:0:1:... loaded active plugged QEMU_HARDDISK sys-devices-pc...0:1-0... loaded active plugged QEMU_HARDDISK sys-devices-pc...0:0-1... loaded active plugged QEMU_DVD-ROM .....(中間省略)..... vsftpd.service loaded active running Vsftpd ftp daemon .....(中間省略)..... cups.socket loaded failed failed CUPS Printing Service Sockets .....(中間省略)..... LOAD = Reflects whether the unit definition was properly loaded. ACTIVE = The high-level unit activation state, i.e. generalization of SUB. SUB = The low-level unit activation state, values depend on unit type. 141 loaded units listed. Pass --all to see loaded but inactive units, too. To show all installed unit files use 'systemctl list-unit-files'. # 列出的項目中,主要的意義是: # UNIT :項目的名稱,包括各個 unit 的類別 (看副檔名) # LOAD :開機時是否會被載入,預設 systemctl 顯示的是有載入的項目而已喔! # ACTIVE :目前的狀態,須與後續的 SUB 搭配!就是我們用 systemctl status 觀察時,active 的項目! # DESCRIPTION :詳細描述囉 # cups 比較有趣,因為剛剛被我們玩過,所以 ACTIVE 竟然是 failed 的喔!被玩死了! ^_^ # 另外,systemctl 都不加參數,其實預設就是 list-units 的意思! 範例二:列出所有已經安裝的 unit 有哪些? [root@study ~]# systemctl list-unit-files UNIT FILE STATE proc-sys-fs-binfmt_misc.automount static dev-hugepages.mount static dev-mqueue.mount static proc-fs-nfsd.mount static .....(中間省略)..... systemd-tmpfiles-clean.timer static 336 unit files listed.
使用 systemctl list-unit-files 會將系統上所有的服務通通列出來~而不像 list-units 僅以 unit 分類作大致的說明。 至於 STATE 狀態就是前兩個小節談到的開機是否會載入的那個狀態項目囉!主要有 enabled / disabled / mask / static 等等。
假設我不想要知道這麼多的 unit 項目,我只想要知道 service 這種類別的 daemon 而已,而且不論是否已經啟動,通通要列出來! 那該如何是好?
[root@study ~]# systemctl list-units --type=service --all # 只剩下 *.service 的項目才會出現喔! 範例一:查詢系統上是否有以 cpu 為名的服務? [root@study ~]# systemctl list-units --type=service --all | grep cpu cpupower.service loaded inactive dead Configure CPU power related settings # 確實有喔!可以改變 CPU 電源管理機制的服務哩!
透過上個小節我們知道系統上所有的 systemd 的 unit 觀察的方式,那麼可否列出跟操作界面比較有關的 target 項目呢? 很簡單啊!就這樣搞一下:
[root@study ~]# systemctl list-units --type=target --all
UNIT LOAD ACTIVE SUB DESCRIPTION
basic.target loaded active active Basic System
cryptsetup.target loaded active active Encrypted Volumes
emergency.target loaded inactive dead Emergency Mode
final.target loaded inactive dead Final Step
getty.target loaded active active Login Prompts
graphical.target loaded active active Graphical Interface
local-fs-pre.target loaded active active Local File Systems (Pre)
local-fs.target loaded active active Local File Systems
multi-user.target loaded active active Multi-User System
network-online.target loaded inactive dead Network is Online
network.target loaded active active Network
nss-user-lookup.target loaded inactive dead User and Group Name Lookups
paths.target loaded active active Paths
remote-fs-pre.target loaded active active Remote File Systems (Pre)
remote-fs.target loaded active active Remote File Systems
rescue.target loaded inactive dead Rescue Mode
shutdown.target loaded inactive dead Shutdown
slices.target loaded active active Slices
sockets.target loaded active active Sockets
sound.target loaded active active Sound Card
swap.target loaded active active Swap
sysinit.target loaded active active System Initialization
syslog.target not-found inactive dead syslog.target
time-sync.target loaded inactive dead System Time Synchronized
timers.target loaded active active Timers
umount.target loaded inactive dead Unmount All Filesystems
LOAD = Reflects whether the unit definition was properly loaded.
ACTIVE = The high-level unit activation state, i.e. generalization of SUB.
SUB = The low-level unit activation state, values depend on unit type.
26 loaded units listed.
To show all installed unit files use 'systemctl list-unit-files'.
喔!在我們的 CentOS 7.1 的預設情況下,就有 26 個 target unit 耶!而跟操作界面相關性比較高的 target 主要有底下幾個:
正常的模式是 multi-user.target 以及 graphical.target 兩個,救援方面的模式主要是 rescue.target 以及更嚴重的 emergency.target。 如果要修改可提供登入的 tty 數量,則修改 getty.target 項目。基本上,我們最常使用的當然就是 multi-user 以及 graphical 囉! 那麼我如何知道目前的模式是哪一種?又得要如何修改呢?底下來玩一玩吧!
[root@study ~]# systemctl [command] [unit.target] 選項與參數: command: get-default :取得目前的 target set-default :設定後面接的 target 成為預設的操作模式 isolate :切換到後面接的模式 範例一:我們的測試機器預設是圖形界面,先觀察是否真為圖形模式,再將預設模式轉為文字界面 [root@study ~]# systemctl get-default graphical.target # 果然是圖形界面喔! [root@study ~]# systemctl set-default multi-user.target [root@study ~]# systemctl get-default multi-user.target 範例二:在不重新開機的情況下,將目前的操作環境改為純文字模式,關掉圖形界面 [root@study ~]# systemctl isolate multi-user.target 範例三:若需要重新取得圖形界面呢? [root@study ~]# systemctl isolate graphical.target
要注意,改變 graphical.target 以及 multi-user.target 是透過 isolate 來處理的!鳥哥剛剛接觸到 systemd 的時候,在 multi-user.target 環境下轉成 graphical.target 時, 可以透過 systemctl start graphical.target 喔!然後鳥哥就以為關閉圖形界面即可回到 multi-user.target 的!但使用 systemctl stop graphical.target 卻完全不理鳥哥~這才發現錯了...在 service 部份用 start/stop/restart 才對,在 target 項目則請使用 isolate (隔離不同的操作模式) 才對!
在正常的切換情況下,使用上述 isolate 的方式即可。不過為了方便起見, systemd 也提供了數個簡單的指令給我們切換操作模式之用喔! 大致上如下所示:
[root@study ~]# systemctl poweroff 系統關機 [root@study ~]# systemctl reboot 重新開機 [root@study ~]# systemctl suspend 進入暫停模式 [root@study ~]# systemctl hibernate 進入休眠模式 [root@study ~]# systemctl rescue 強制進入救援模式 [root@study ~]# systemctl emergency 強制進入緊急救援模式
關機、重新開機、救援與緊急模式這沒啥問題,那麼什麼是暫停與休眠模式呢?
我們在本章一開始談到 systemd 的時候就有談到相依性的問題克服,那麼,如何追蹤某一個 unit 的相依性呢? 舉例來說好了,我們怎麼知道 graphical.target 會用到 multi-user.target 呢?那 graphical.target 底下還有哪些東西呢? 底下我們就來談一談:
[root@study ~]# systemctl list-dependencies [unit] [--reverse] 選項與參數: --reverse :反向追蹤誰使用這個 unit 的意思! 範例一:列出目前的 target 環境下,用到什麼特別的 unit [root@study ~]# systemctl get-default multi-user.target [root@study ~]# systemctl list-dependencies default.target ├─abrt-ccpp.service ├─abrt-oops.service ├─vsftpd.service ├─basic.target │ ├─alsa-restore.service │ ├─alsa-state.service .....(中間省略)..... │ ├─sockets.target │ │ ├─avahi-daemon.socket │ │ ├─dbus.socket .....(中間省略)..... │ ├─sysinit.target │ │ ├─dev-hugepages.mount │ │ ├─dev-mqueue.mount .....(中間省略)..... │ └─timers.target │ └─systemd-tmpfiles-clean.timer ├─getty.target │ └─getty@tty1.service └─remote-fs.target
因為我們前一小節的練習將預設的操作模式變成 multi-user.target 了,因此這邊使用 list-dependencies 時,所列出的 default.target 其實是 multi-user.target 的內容啦!根據線條連線的流程,我們也能夠知道, multi-user.target 其實還會用到 basic.target + getty.target + remote-fs.target 三大項目, 而 basic.target 又用到了 sockets.target + sysinit.target + timers.target... 等一堆~所以囉,從這邊就能夠清楚的查詢到每種 target 模式底下還有的相依模式。 那麼如果要查出誰會用到 multi-user.target 呢?就這麼作!
[root@study ~]# systemctl list-dependencies --reverse
default.target
└─graphical.target
reverse 本來就是反向的意思,所以加上這個選項,代表『誰還會用到我的服務』的意思~所以看得出來, multi-user.target 主要是被 graphical.target 所使用喔! 好~那再來,graphical.target 又使用了多少的服務呢?可以這樣看:
[root@study ~]# systemctl list-dependencies graphical.target graphical.target ├─accounts-daemon.service ├─gdm.service ├─network.service ├─rtkit-daemon.service ├─systemd-update-utmp-runlevel.service └─multi-user.target ├─abrt-ccpp.service ├─abrt-oops.service .....(底下省略).....
所以可以看得出來,graphical.target 就是在 multi-user.target 底下再加上 accounts-daemon, gdm, network, rtkit-deamon, systemd-update-utmp-runlevel 等服務而已! 這樣會看了嗎?了解 daemon 之間的相關性也是很重要的喔!出問題時,可以找到正確的服務相依流程!
我們在前幾小節曾經談過比較重要的 systemd 啟動腳本設定檔在 /usr/lib/systemd/system/, /etc/systemd/system/ 目錄下,那還有哪些目錄跟系統的 daemon 運作有關呢? 基本上是這樣的:
我們知道 systemd 裡頭有很多的本機會用到的 socket 服務,裡頭可能會產生很多的 socket file ~那你怎麼知道這些 socket file 放置在哪裡呢? 很簡單!還是透過 systemctl 來管理!
[root@study ~]# systemctl list-sockets
LISTEN UNIT ACTIVATES
/dev/initctl systemd-initctl.socket systemd-initctl.service
/dev/log systemd-journald.socket systemd-journald.service
/run/dmeventd-client dm-event.socket dm-event.service
/run/dmeventd-server dm-event.socket dm-event.service
/run/lvm/lvmetad.socket lvm2-lvmetad.socket lvm2-lvmetad.service
/run/systemd/journal/socket systemd-journald.socket systemd-journald.service
/run/systemd/journal/stdout systemd-journald.socket systemd-journald.service
/run/systemd/shutdownd systemd-shutdownd.socket systemd-shutdownd.service
/run/udev/control systemd-udevd-control.socket systemd-udevd.service
/var/run/avahi-daemon/socket avahi-daemon.socket avahi-daemon.service
/var/run/cups/cups.sock cups.socket cups.service
/var/run/dbus/system_bus_socket dbus.socket dbus.service
/var/run/rpcbind.sock rpcbind.socket rpcbind.service
@ISCSIADM_ABSTRACT_NAMESPACE iscsid.socket iscsid.service
@ISCSID_UIP_ABSTRACT_NAMESPACE iscsiuio.socket iscsiuio.service
kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service
16 sockets listed.
Pass --all to see loaded but inactive sockets, too.
這樣很清楚的就能夠知道正在監聽本機服務需求的 socket file 所在的檔名位置囉!
從第十六章與前一小節對服務的說明後,你應該要知道的是, 系統所有的功能都是某些程序所提供的,而程序則是透過觸發程式而產生的。同樣的,系統提供的網路服務當然也是這樣的! 只是由於網路牽涉到 TCP/IP 的概念,所以顯的比較複雜一些就是了。
玩過網際網路 (Internet) 的朋友應該知道 IP 這玩意兒,大家都說 IP 就是代表你的主機在網際網路上面的『門牌號碼』。 但是你的主機總是可以提供非常多的網路服務而不止一項功能而已,但我們僅有一個 IP 呢!當用戶端連線過來我們的主機時, 我們主機是如何分辨不同的服務要求呢?那就是透過埠號 (port number) 啦!埠號簡單的想像,他就是你家門牌上面的第幾層樓! 這個 IP 與 port 就是網際網路連線的最重要機制之一囉。我們拿底下的網址來說明:
有沒有發現,兩個網址都是指向 ftp.ksu.edu.tw 這個崑山科大的 FTP 網站,但是瀏覽器上面顯示的結果卻是不一樣的? 是啊!這是因為我們指向不同的服務嘛!一個是 http 這個 WWW 的服務,一個則是 ftp 這個檔案傳輸服務,當然顯示的結果就不同了。
事實上,為了統一整個網際網路的埠號對應服務的功能,好讓所有的主機都能夠使用相同的機制來提供服務與要求服務, 所以就有了『通訊協定』這玩意兒。也就是說,有些約定俗成的服務都放置在同一個埠號上面啦!舉例來說, 網址列上面的 http 會讓瀏覽器向 WWW 伺服器的 80 埠號進行連線的要求!而 WWW 伺服器也會將 httpd 這個軟體啟動在 port 80, 這樣兩者才能夠達成連線的!
嗯!那麼想一想,系統上面有沒有什麼設定可以讓服務與埠號對應在一起呢?那就是 /etc/services 啦!
[root@study ~]# cat /etc/services ....(前面省略).... ftp 21/tcp ftp 21/udp fsp fspd ssh 22/tcp # The Secure Shell (SSH) Protocol ssh 22/udp # The Secure Shell (SSH) Protocol ....(中間省略).... http 80/tcp www www-http # WorldWideWeb HTTP http 80/udp www www-http # HyperText Transfer Protocol ....(底下省略).... # 這個檔案的內容是以底下的方式來編排的: # <daemon name> <port/封包協定> <該服務的說明>
像上面說的是,第一欄為 daemon 的名稱、第二欄為該 daemon 所使用的埠號與網路資料封包協定, 封包協定主要為可靠連線的 TCP 封包以及較快速但為非連線導向的 UDP 封包。 舉個例子說,那個遠端連線機制使用的是 ssh 這個服務,而這個服務的使用的埠號為 22 !就是這樣啊!
當你第一次使用 systemctl 去觀察本機伺服器啟動的服務時,不知道有沒有嚇一跳呢?怎麼隨隨便便 CentOS 7.x 就給我啟動了幾乎 100 多個以上的 daemon? 會不會有事啊?沒關係啦!因為 systemd 將許多原本不被列為 daemon 的程序都納入到 systemd 自己的管轄監測範圍內,因此就多了很多 daemon 存在! 那些大部分都屬於 Linux 系統基礎運作所需要的環境,沒有什麼特別需求的話,最好都不要更動啦!除非你自己知道自己需要什麼。
除了本機服務之外,其實你一定要觀察的,反而是網路服務喔!雖然網路服務預設有 SELinux 管理,不過,在鳥哥的立場上, 我還是建議非必要的網路服務就關閉他!那麼什麼是網路服務呢?基本上,會產生一個網路監聽埠口 (port) 的程序,你就可以稱他是個網路服務了! 那麼如何觀察網路埠口?就這樣追蹤啊!
[root@study ~]# netstat -tlunp
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 1340/sshd
tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 2387/master
tcp6 0 0 :::555 :::* LISTEN 29113/vsftpd
tcp6 0 0 :::22 :::* LISTEN 1340/sshd
tcp6 0 0 ::1:25 :::* LISTEN 2387/master
udp 0 0 0.0.0.0:5353 0.0.0.0:* 750/avahi-daemon: r
udp 0 0 0.0.0.0:36540 0.0.0.0:* 750/avahi-daemon: r
如上表所示,我們的系統上至少開了 22, 25, 555, 5353, 36540 這幾個埠口~而其中 5353, 36540 是由 avahi-daemon 這個東西所啟動的! 接下來我們使用 systemctl 去觀察一下,到底有沒有 avahi-daemon 為開頭的服務呢?
[root@study ~]# systemctl list-units --all | grep avahi-daemon
avahi-daemon.service loaded active running Avahi mDNS/DNS-SD Stack
avahi-daemon.socket loaded active running Avahi mDNS/DNS-SD Stack Activation Socket
透過追查,知道這個 avahi-daemon 的目的是在區域網路進行類似網芳的搜尋,因此這個服務可以協助你在區網內隨時了解隨插即用的裝置! 包括筆記型電腦等,只要連上你的區網,你就能夠知道誰進來了。問題是,你可能不要這個協定啊!所以,那就關閉他吧!
[root@study ~]# systemctl stop avahi-daemon.service [root@study ~]# systemctl stop avahi-daemon.socket [root@study ~]# systemctl disable avahi-daemon.service avahi-daemon.socket [root@study ~]# netstat -tlunp 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 1340/sshd tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 2387/master tcp6 0 0 :::555 :::* LISTEN 29113/vsftpd tcp6 0 0 :::22 :::* LISTEN 1340/sshd tcp6 0 0 ::1:25 :::* LISTEN 2387/master
一般來說,你的本機伺服器至少需要 25 號埠口,而 22 號埠口則最好加上防火牆來管理遠端連線登入比較妥當~因此,上面的埠口中, 除了 555 是我們上一章因為測試而產生的之外,這樣的系統能夠被爬牆的機會已經少很多了! ^_^!OK!現在如果你的系統裡面有一堆網路埠口在監聽, 而你根本不知道那是幹麻用的,鳥哥建議你,現在就透過上面的方式,關閉他吧!
以前,我們如果想要建立系統服務,就得要到 /etc/init.d/ 底下去建立相對應的 bash shell script 來處理。那麼現在 systemd 的環境底下, 如果我們想要設定相關的服務啟動環境,那應該如何處理呢?這就是本小節的任務囉!
現在我們知道服務的管理是透過 systemd,而 systemd 的設定檔大部分放置於 /usr/lib/systemd/system/ 目錄內。但是 Red Hat 官方文件指出, 該目錄的檔案主要是原本軟體所提供的設定,建議不要修改!而要修改的位置應該放置於 /etc/systemd/system/ 目錄內。舉例來說,如果你想要額外修改 vsftpd.service 的話, 他們建議要放置到哪些地方呢?
基本上,在設定檔裡面你都可以自由設定相依服務的檢查,並且設定加入到哪些 target 裡頭去。但是如果是已經存在的設定檔,或者是官方提供的設定檔, Red Hat 是建議你不要修改原設定,而是到上面提到的幾個目錄去進行額外的客製化設定比較好!當然,這見仁見智~如果你硬要修改原始的 /usr/lib/systemd/system 底下的設定檔,那也是 OK 沒問題的!並且也能夠減少許多設定檔的增加~鳥哥自己認為,這樣也不錯!反正,就完全是個人喜好囉~
了解了設定檔的相關目錄與檔案之後,再來,當然得要了解一下設定檔本身的內容了!讓我們先來瞧一瞧 sshd.service 的內容好了! 原本想拿 vsftpd.service 來講解,不過該檔案的內容比較陽春,還是看一下設定項目多一些的 sshd.service 好了!
[root@study ~]# cat /usr/lib/systemd/system/sshd.service [Unit] # 這個項目與此 unit 的解釋、執行服務相依性有關 Description=OpenSSH server daemon After=network.target sshd-keygen.service Wants=sshd-keygen.service [Service] # 這個項目與實際執行的指令參數有關 EnvironmentFile=/etc/sysconfig/sshd ExecStart=/usr/sbin/sshd -D $OPTIONS ExecReload=/bin/kill -HUP $MAINPID KillMode=process Restart=on-failure RestartSec=42s [Install] # 這個項目說明此 unit 要掛載哪個 target 底下 WantedBy=multi-user.target
分析上面的設定檔,我們大概能夠將整個設定分為三個部份,就是:
至於設定檔內有些設定規則還是得要說明一下:
每個部份裡面還有很多的設定細項,我們使用一個簡單的表格來說明每個項目好了!
[Unit] 部份 | |
設定參數 | 參數意義說明 |
Description | 就是當我們使用 systemctl list-units 時,會輸出給管理員看的簡易說明!當然,使用 systemctl status 輸出的此服務的說明,也是這個項目! |
Documentation | 這個項目在提供管理員能夠進行進一步的文件查詢的功能!提供的文件可以是如下的資料:
|
After | 說明此 unit 是在哪個 daemon 啟動之後才啟動的意思!基本上僅是說明服務啟動的順序而已,並沒有強制要求裡頭的服務一定要啟動後此 unit 才能啟動。 以 sshd.service 的內容為例,該檔案提到 After 後面有 network.target 以及 sshd-keygen.service,但是若這兩個 unit 沒有啟動而強制啟動 sshd.service 的話, 那麼 sshd.service 應該還是能夠啟動的!這與 Requires 的設定是有差異的喔! |
Before | 與 After 的意義相反,是在什麼服務啟動前最好啟動這個服務的意思。不過這僅是規範服務啟動的順序,並非強制要求的意思。 |
Requires | 明確的定義此 unit 需要在哪個 daemon 啟動後才能夠啟動!就是設定相依服務啦!如果在此項設定的前導服務沒有啟動,那麼此 unit 就不會被啟動! |
Wants | 與 Requires 剛好相反,規範的是這個 unit 之後最好還要啟動什麼服務比較好的意思!不過,並沒有明確的規範就是了!主要的目的是希望建立讓使用者比較好操作的環境。 因此,這個 Wants 後面接的服務如果沒有啟動,其實不會影響到這個 unit 本身! |
Conflicts | 代表衝突的服務!亦即這個項目後面接的服務如果有啟動,那麼我們這個 unit 本身就不能啟動!我們 unit 有啟動,則此項目後的服務就不能啟動! 反正就是衝突性的檢查啦! |
接下來了解一下在 [Service] 當中有哪些項目可以使用!
[Service] 部份 | |
設定參數 | 參數意義說明 |
Type | 說明這個 daemon 啟動的方式,會影響到 ExecStart 喔!一般來說,有底下幾種類型
|
EnvironmentFile | 可以指定啟動腳本的環境設定檔!例如 sshd.service 的設定檔寫入到 /etc/sysconfig/sshd 當中!你也可以使用 Environment= 後面接多個不同的 Shell 變數來給予設定! |
ExecStart | 就是實際執行此 daemon 的指令或腳本程式。你也可以使用 ExecStartPre (之前) 以及 ExecStartPost (之後) 兩個設定項目來在實際啟動服務前,進行額外的指令行為。 但是你得要特別注意的是,指令串僅接受『指令 參數 參數...』的格式,不能接受 <, >, >>, |, & 等特殊字符,很多的 bash 語法也不支援喔! 所以,要使用這些特殊的字符時,最好直接寫入到指令腳本裡面去!不過,上述的語法也不是完全不能用,亦即,若要支援比較完整的 bash 語法,那你得要使用 Type=oneshot 才行喔! 其他的 Type 才不能支援這些字符。 |
ExecStop | 與 systemctl stop 的執行有關,關閉此服務時所進行的指令。 |
ExecReload | 與 systemctl reload 有關的指令行為 |
Restart | 當設定 Restart=1 時,則當此 daemon 服務終止後,會再次的啟動此服務。舉例來說,如果你在 tty2 使用文字界面登入,操作完畢後登出,基本上,這個時候 tty2 就已經結束服務了。 但是你會看到螢幕又立刻產生一個新的 tty2 的登入畫面等待你的登入!那就是 Restart 的功能!除非使用 systemctl 強制將此服務關閉,否則這個服務會源源不絕的一直重複產生! |
RemainAfterExit | 當設定為 RemainAfterExit=1 時,則當這個 daemon 所屬的所有程序都終止之後,此服務會再嘗試啟動。這對於 Type=oneshot 的服務很有幫助! |
TimeoutSec | 若這個服務在啟動或者是關閉時,因為某些緣故導致無法順利『正常啟動或正常結束』的情況下,則我們要等多久才進入『強制結束』的狀態! |
KillMode | 可以是 process, control-group, none 的其中一種,如果是 process 則 daemon 終止時,只會終止主要的程序 (ExecStart 接的後面那串指令),如果是 control-group 時, 則由此 daemon 所產生的其他 control-group 的程序,也都會被關閉。如果是 none 的話,則沒有程序會被關閉喔! |
RestartSec | 與 Restart 有點相關性,如果這個服務被關閉,然後需要重新啟動時,大概要 sleep 多少時間再重新啟動的意思。預設是 100ms (毫秒)。 |
最後,再來看看那麼 Install 內還有哪些項目可用?
[Install] 部份 | |
設定參數 | 參數意義說明 |
WantedBy | 這個設定後面接的大部分是 *.target unit !意思是,這個 unit 本身是附掛在哪一個 target unit 底下的!一般來說,大多的服務性質的 unit 都是附掛在 multi-user.target 底下! |
Also | 當目前這個 unit 本身被 enable 時,Also 後面接的 unit 也請 enable 的意思!也就是具有相依性的服務可以寫在這裡呢! |
Alias | 進行一個連結的別名的意思!當 systemctl enable 相關的服務時,則此服務會進行連結檔的建立!以 multi-user.target 為例,這個傢伙是用來作為預設操作環境 default.target 的規劃, 因此當你設定用成 default.target 時,這個 /etc/systemd/system/default.target 就會連結到 /usr/lib/systemd/system/multi-user.target 囉! |
大致的項目就有這些,接下來讓我們根據上面這些資料來進行一些簡易的操作吧!
我們在上一章將 vsftpd 的 port 改成 555 號了。不過,因為某些原因,所以你可能需要使用到兩個埠口,分別是正常的 21 以及特殊的 555 ! 這兩個 port 都啟用的情況下,你可能就得要使用到兩個設定檔以及兩個啟動腳本設定了!現在假設是這樣:
我們可以這樣作:
# 1. 先建立好所需要的設定檔 [root@study ~]# cd /etc/vsftpd [root@study vsftpd]# cp vsftpd.conf vsftpd2.conf [root@study vsftpd]# vim vsftpd.conf #listen_port=555 [root@study vsftpd]# diff vsftpd.conf vsftpd2.conf 128c128 < #listen_port=555 --- > listen_port=555 # 注意這兩個設定檔的差別喔!只有這一行不同而已! # 2. 開始處理啟動腳本設定 [root@study vsftpd]# cd /etc/systemd/system [root@study system]# cp /usr/lib/systemd/system/vsftpd.service vsftpd2.service [root@study system]# vim vsftpd2.service [Unit] Description=Vsftpd second ftp daemon After=network.target [Service] Type=forking ExecStart=/usr/sbin/vsftpd /etc/vsftpd/vsftpd2.conf [Install] WantedBy=multi-user.target # 重點在改了 vsftpd2.conf 這個設定檔喔! # 3. 重新載入 systemd 的腳本設定檔內容 [root@study system]# systemctl daemon-reload [root@study system]# systemctl list-unit-files --all | grep vsftpd vsftpd.service enabled vsftpd2.service disabled vsftpd@.service disabled vsftpd.target disabled [root@study system]# systemctl status vsftpd2.service vsftpd2.service - Vsftpd second ftp daemon Loaded: loaded (/etc/systemd/system/vsftpd2.service; disabled) Active: inactive (dead) [root@study system]# systemctl restart vsftpd.service vsftpd2.service [root@study system]# systemctl enable vsftpd.service vsftpd2.service [root@study system]# systemctl status vsftpd.service vsftpd2.service vsftpd.service - Vsftpd ftp daemon Loaded: loaded (/usr/lib/systemd/system/vsftpd.service; enabled) Active: active (running) since Wed 2015-08-12 22:00:17 CST; 35s ago Main PID: 12670 (vsftpd) CGroup: /system.slice/vsftpd.service └─12670 /usr/sbin/vsftpd /etc/vsftpd/vsftpd.conf Aug 12 22:00:17 study.centos.vbird systemd[1]: Started Vsftpd ftp daemon. vsftpd2.service - Vsftpd second ftp daemon Loaded: loaded (/etc/systemd/system/vsftpd2.service; enabled) Active: active (running) since Wed 2015-08-12 22:00:17 CST; 35s ago Main PID: 12672 (vsftpd) CGroup: /system.slice/vsftpd2.service └─12672 /usr/sbin/vsftpd /etc/vsftpd/vsftpd2.conf [root@study system]# netstat -tlnp 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:22 0.0.0.0:* LISTEN 1340/sshd tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 2387/master tcp6 0 0 :::555 :::* LISTEN 12672/vsftpd tcp6 0 0 :::21 :::* LISTEN 12670/vsftpd tcp6 0 0 :::22 :::* LISTEN 1340/sshd tcp6 0 0 ::1:25 :::* LISTEN 2387/master
很簡單的將你的 systemd 所管理的 vsftpd 做了另一個服務!未來如果有相同的需求,同樣的方法作一遍即可!
我們的 CentOS 7 開機完成後,不是說有 6 個終端機可以使用嗎?就是那個 tty1~tty6 的啊!那個東西是由 agetty 這個指令達成的。 OK!那麼這個終端機的功能又是從哪個項目所提供的呢?其實,那個東東涉及很多層面,主要管理的是 getty.target 這個 target unit , 不過,實際產生 tty1~tty6 的則是由 getty@.service 所提供的!咦!那個 @ 是啥東西?
先來查閱一下 /usr/lib/systemd/system/getty@.service 的內容好了:
[root@study ~]# cat /usr/lib/systemd/system/getty@.service [Unit] Description=Getty on %I Documentation=man:agetty(8) man:systemd-getty-generator(8) Documentation=http://0pointer.de/blog/projects/serial-console.html After=systemd-user-sessions.service plymouth-quit-wait.service After=rc-local.service Before=getty.target ConditionPathExists=/dev/tty0 [Service] ExecStart=-/sbin/agetty --noclear %I $TERM Type=idle Restart=always RestartSec=0 UtmpIdentifier=%I TTYPath=/dev/%I TTYReset=yes TTYVHangup=yes TTYVTDisallocate=yes KillMode=process IgnoreSIGPIPE=no SendSIGHUP=yes [Install] WantedBy=getty.target
比較重要的當然就是 ExecStart 項目囉!那麼我們去 man agetty 時,發現到它的語法應該是『 agetty --noclear tty1 』之類的字樣, 因此,我們如果要啟動六個 tty 的時候,基本上應該要有六個啟動設定檔。亦即是可能會用到 getty1.service, getty2.service...getty6.service 才對! 哇!這樣控管很麻煩啊~所以,才會出現這個 @ 的項目啦!咦!這個 @ 到底怎麼回事呢?我們先來看看 getty@.service 的上游,亦即是 getty.target 這個東西的內容好了!
[root@study ~]# systemctl show getty.target # 那個 show 的指令可以將 getty.target 的預設設定值也取出來顯示! Names=getty.target Wants=getty@tty1.service WantedBy=multi-user.target Conflicts=shutdown.target Before=multi-user.target After=getty@tty1.service getty@tty2.service getty@tty3.service getty@tty4.service getty@tty6.service getty@tty5.service .....(後面省略).....
你會發現,咦!怎麼會多出六個怪異的 service 呢?我們拿 getty@tty1.service 來說明一下好了!當我們執行完 getty.target 之後, 他會持續要求 getty@tty1.service 等六個服務繼續啟動。那我們的 systemd 就會這麼作:
這也就是說,其實 getty@tty1.service 實際上是不存在的!他主要是透過 getty@.service 來執行~也就是說, getty@.service 的目的是為了要簡化多個執行的啟動設定, 他的命名方式是這樣的:
原始檔案:執行服務名稱@.service 執行檔案:執行服務名稱@範例名稱.service
因此當有範例名稱帶入時,則會有一個新的服務名稱產生出來!你再回頭看看 getty@.service 的啟動腳本:
ExecStart=-/sbin/agetty --noclear %I $TERM
上表中那個 %I 指的就是『範例名稱』!根據 getty.target 的資訊輸出來看,getty@tty1.service 的 %I 就是 tty1 囉!因此執行腳本就會變成『 /sbin/agetty --noclear tty1 』! 所以我們才有辦法以一個設定檔來啟動多個 tty1 給用戶登入囉!
現在你應該要感到困擾的是,那麼『 6 個 tty 是誰規定的』為什麼不是 5 個還是 7 個?這是因為 systemd 的登入設定檔 /etc/systemd/logind.conf 裡面規範的啦! 假如你想要讓 tty 數量降低到剩下 4 個的話,那麼可以這樣實驗看看:
# 1. 修改預設的 logind.conf 內容,將原本 6 個虛擬終端機改成 4 個 [root@study ~]# vim /etc/systemd/logind.conf [Login] NAutoVTs=4 ReserveVT=0 # 原本是 6 個而且還註解,請取消註解,然後改成 4 吧! # 2. 關閉不小心啟動的 tty5, tty6 並重新啟動 getty.target 囉! [root@study ~]# systemctl stop getty@tty5.service [root@study ~]# systemctl stop getty@tty6.service [root@study ~]# systemctl restart systemd-logind.service
現在你再到桌面環境下,按下 [ctrl]+[alt]+[F1]~[F6] 就會發現,只剩下四個可用的 tty 囉!後面的 tty5, tty6 已經被放棄了!不再被啟動喔! 好!那麼我暫時需要啟動 tty8 時,又該如何處理呢?需要重新建立一個腳本嗎?不需要啦!可以這樣作!
[root@study ~]# systemctl start getty@tty8.service
無須額外建立其他的啟動服務設定檔喔!
不知道你有沒有發現,其實在 /usr/lib/systemd/system 底下還有個特別的 vsftpd@.service 喔!來看看他的內容:
[root@study ~]# cat /usr/lib/systemd/system/vsftpd@.service [Unit] Description=Vsftpd ftp daemon After=network.target PartOf=vsftpd.target [Service] Type=forking ExecStart=/usr/sbin/vsftpd /etc/vsftpd/%i.conf [Install] WantedBy=vsftpd.target
根據前面 getty@.service 的說明,我們知道在啟動的腳本設定當中, %i 或 %I 就是代表 @ 後面接的範例檔名的意思! 那我能不能建立 vsftpd3.conf 檔案,然後透過該檔案來啟動新的服務呢?就來玩玩看!
# 1. 根據 vsftpd@.service 的建議,於 /etc/vsftpd/ 底下先建立新的設定檔 [root@study ~]# cd /etc/vsftpd [root@study vsftpd]# cp vsftpd.conf vsftpd3.conf [root@study vsftpd]# vim vsftpd3.conf listen_port=2121 # 2. 暫時啟動這個服務,不要永久啟動他! [root@study vsftpd]# systemctl start vsftpd@vsftpd3.service [root@study vsftpd]# systemctl status vsftpd@vsftpd3.service vsftpd@vsftpd3.service - Vsftpd ftp daemon Loaded: loaded (/usr/lib/systemd/system/vsftpd@.service; disabled) Active: active (running) since Thu 2015-08-13 01:34:05 CST; 5s ago [root@study vsftpd]# netstat -tlnp Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp6 0 0 :::2121 :::* LISTEN 16404/vsftpd tcp6 0 0 :::555 :::* LISTEN 12672/vsftpd tcp6 0 0 :::21 :::* LISTEN 12670/vsftpd
因為我們啟用了 vsftpd@vsftpd3.service ,代表要使用的設定檔在 /etc/vsftpd/vsftpd3.conf 的意思!所以可以直接透過 vsftpd@.service 而無須重新設定啟動腳本! 這樣是否比前幾個小節的方法還要簡便呢? ^_^。透過這個方式,你就可以使用到新的設定檔囉!只是你得要注意到 @ 這個東西就是了! ^_^
我們來模擬自己作一個服務吧!假設我要作一隻可以備份自己系統的服務,這隻腳本我放在 /backups 底下,內容有點像這樣:
[root@study ~]# vim /backups/backup.sh #!/bin/bash source="/etc /home /root /var/lib /var/spool/{cron,at,mail}" target="/backups/backup-system-$(date +%Y-%m-%d).tar.gz" [ ! -d /backups ] && mkdir /backups tar -zcvf ${target} ${source} &> /backups/backup.log [root@study ~]# chmod a+x /backups/backup.sh [root@study ~]# ll /backups/backup.sh -rwxr-xr-x. 1 root root 220 Aug 13 01:57 /backups/backup.sh # 記得要有可執行的權限才可以喔!
接下來,我們要如何設計一隻名為 backup.service 的啟動腳本設定呢?可以這樣做喔!
[root@study ~]# vim /etc/systemd/system/backup.service [Unit] Description=backup my server Requires=atd.service [Service] Type=simple ExecStart=/bin/bash -c " echo /backups/backup.sh | at now" [Install] WantedBy=multi-user.target # 因為 ExecStart 裡面有用到 at 這個指令,因此, atd.service 就是一定要的服務! [root@study ~]# systemctl daemon-reload [root@study ~]# systemctl start backup.service [root@study ~]# systemctl status backup.service backup.service - backup my server Loaded: loaded (/etc/systemd/system/backup.service; disabled) Active: inactive (dead) Aug 13 07:50:31 study.centos.vbird systemd[1]: Starting backup my server... Aug 13 07:50:31 study.centos.vbird bash[20490]: job 8 at Thu Aug 13 07:50:00 2015 Aug 13 07:50:31 study.centos.vbird systemd[1]: Started backup my server. # 為什麼 Active 是 inactive 呢?這是因為我們的服務僅是一個簡單的 script 啊! # 因此執行完畢就完畢了,不會繼續存在記憶體中喔!
完成上述的動作之後,以後你都可以直接使用 systemctl start backup.service 進行系統的備份了!而且會直接丟進 atd 的管理中, 你就無須自己手動用 at 去處理這項任務了~好像還不賴喔! ^_^
這樣自己做一個服務好像也不難啊! ^_^!自己動手玩玩看吧!
有時候,某些服務你想要定期執行,或者是開機後執行,或者是什麼服務啟動多久後執行等等的。在過去,我們大概都是使用 crond 這個服務來定期處理, 不過,既然現在有一直常駐在記憶體當中的 systemd 這個好用的東西,加上這 systemd 有個協力服務,名為 timers.target 的傢伙,這傢伙可以協助定期處理各種任務! 那麼,除了 crond 之外,如何使用 systemd 內建的 time 來處理各種任務呢?這就是本小節的重點囉!
在 archlinux 的官網 wiki 上面有提到,為啥要使用 systemd.timer 呢?
雖然還是有些弱點啦~例如 systemd 的 timer 並沒有 email 通知的功能 (除非自己寫一個),也沒有類似 anacron 的一段時間內的隨機取樣功能 (random_delay), 不過,總體來說,還是挺不錯的!此外,相對於 crond 最小的單位到分, systemd 是可以到秒甚至是毫秒的單位哩!相當有趣!
基本上,想要使用 systemd 的 timer 功能,你必須要有幾個要件:
滿足上面的需求就 OK 了!有沒有什麼案例可以來實作看看?這樣說好了,我們上個小節不是才自己做了個 backup.service 的服務嗎?那麼能不能將這個 backup.service 用在定期執行上面呢?好啊!那就來測試看看!
你可以到 /etc/systemd/system 底下去建立這個 *.timer 檔,那這個檔案的內容要項有哪些東西呢?基本設定主要有底下這些: (man systemd.timer & man systemd.time)
[Timer] 部份 | |
設定參數 | 參數意義說明 |
OnActiveSec | 當 timers.target 啟動多久之後才執行這隻 unit |
OnBootSec | 當開機完成後多久之後才執行 |
OnStartupSec | 當 systemd 第一次啟動之後過多久才執行 |
OnUnitActiveSec | 這個 timer 設定檔所管理的那個 unit 服務在最後一次啟動後,隔多久後再執行一次的意思 |
OnUnitInactiveSec | 這個 timer 設定檔所管理的那個 unit 服務在最後一次停止後,隔多久再執行一次的意思。 |
OnCalendar | 使用實際時間 (非循環時間) 的方式來啟動服務的意思!至於時間的格式後續再來談。 |
Unit | 一般來說不太需要設定,因此如同上面剛剛提到的,基本上我們設定都是 sname.server + sname.timer,那如果你的 sname 並不相同時,那在 .timer 的檔案中, 就得要指定是哪一個 service unit 囉! |
Persistent | 當使用 OnCalendar 的設定時,指定該功能要不要持續進行的意思。通常是設定為 yes ,比較能夠滿足類似 anacron 的功能喔! |
基本的項目僅有這些而已,在設定上其實並不困難啦!
如果你想要從 crontab 轉成這個 timer 功能的話,那麼對於時間設定的格式就得要了解了解~基本上的格式如下所示:
語法:英文周名 YYYY-MM-DD HH:MM:SS 範例:Thu 2015-08-13 13:40:00
上面談的是基本的語法,你也可以直接使用間隔時間來處理!常用的間隔時間單位有:
常見的使用範例有:
隔 3 小時: 3h 或 3hr 或 3hours
隔 300 分鐘過 10 秒: 10s 300m
隔 5 天又 100 分鐘: 100m 5day
# 通常英文的寫法,小單位寫前面,大單位寫後面~所以先秒、再分、再小時、再天數等~
此外,你也可以使用英文常用的口語化日期代表,例如 today, tomorrow 等!假設今天是 2015-08-13 13:50:00 的話,那麼:
英文口語 | 實際的時間格式代表 |
now | Thu 2015-08-13 13:50:00 |
today | Thu 2015-08-13 00:00:00 |
tomorrow | Thu 2015-08-14 00:00:00 |
hourly | *-*-* *:00:00 |
daily | *-*-* 00:00:00 |
weekly | Mon *-*-* 00:00:00 |
monthly | *-*-01 00:00:00 |
+3h10m | Thu 2015-08-13 17:00:00 |
2015-08-16 | Sun 2015-08-16 00:00:00 |
現在假設這樣:
好了,那麼應該如何處理這個腳本呢?可以這樣做喔!
[root@study ~]# vim /etc/systemd/system/backup.timer [Unit] Description=backup my server timer [Timer] OnBootSec=2hrs OnUnitActiveSec=2days [Install] WantedBy=multi-user.target # 只要這樣設定就夠了!儲存離開吧! [root@study ~]# systemctl daemon-reload [root@study ~]# systemctl enable backup.timer [root@study ~]# systemctl restart backup.timer [root@study ~]# systemctl list-unit-files | grep backup backup.service disabled # 這個不需要啟動!只要 enable backup.timer 即可! backup.timer enabled [root@study ~]# systemctl show timers.target ConditionTimestamp=Thu 2015-08-13 14:31:11 CST # timer 這個 unit 啟動的時間! [root@study ~]# systemctl show backup.service ExecMainExitTimestamp=Thu 2015-08-13 14:50:19 CST # backup.service 上次執行的時間 [root@study ~]# systemctl show backup.timer NextElapseUSecMonotonic=2d 19min 11.540653s # 下一次執行距離 timers.target 的時間
如上表所示,我上次執行 backup.service 的時間是在 2015-08-13 14:50 ,由於設定兩個小時執行一次,因此下次應該是 2015-08-15 14:50 執行才對! 由於 timer 是由 timers.target 這個 unit 所管理的,而這個 timers.target 的啟動時間是在 2015-08-13 14:31 , 要注意,最終 backup.timer 所紀錄的下次執行時間,其實是與 timers.target 所紀錄的時間差!因此是『 2015-08-15 14:50 - 2015-08-13 14:31 』才對! 所以時間差就是 2d 19min 囉!
上面的案例是固定週期運作一次,那如果我希望不管上面如何運作了,我都希望星期天凌晨 2 點運作這個備份程式一遍呢?請注意,因為已經存在 backup.timer 了! 所以,這裡我用 backup2.timer 來做區隔喔!
[root@study ~]# vim /etc/systemd/system/backup2.timer [Unit] Description=backup my server timer2 [Timer] OnCalendar=Sun *-*-* 02:00:00 Persistent=true Unit=backup.service [Install] WantedBy=multi-user.target [root@study ~]# systemctl daemon-reload [root@study ~]# systemctl enable backup2.timer [root@study ~]# systemctl start backup2.timer [root@study ~]# systemctl show backup2.timer NextElapseUSecRealtime=45y 7month 1w 6d 10h 30min
與循環時間運作差異比較大的地方,在於這個 OnCalendar 的方法對照的時間並不是 times.target 的啟動時間,而是 Unix 標準時間! 亦即是 1970-01-01 00:00:00 去比較的!因此,當你看到最後出現的 NextElapseUSecRealtime 時,哇!下一次執行還要 45 年 + 7 個月 + 1 周 + 6 天 + 10 小時過 30 分~剛看到的時候,鳥哥確實因此揉了揉眼睛~確定沒有看錯...這才了解原來比對的是『日曆時間』而不是某個 unit 的啟動時間啊!呵呵!
透過這樣的方式,你就可以使用 systemd 的 timer 來製作屬於你的時程規劃服務囉!
隨著 Linux 上面軟體支援性越來越多,加上自由軟體蓬勃的發展,我們可以在 Linux 上面用的 daemons 真的越來越多了。所以,想要寫完所有的 daemons 介紹幾乎是不可能的,因此,鳥哥這裡僅介紹幾個很常見的 daemons 而已, 更多的資訊呢,就得要麻煩你自己使用 systemctl list-unit-files --type=service 去查詢囉! 底下的建議主要是針對 Linux 單機伺服器的角色來說明的,不是桌上型的環境喔!
CentOS 7.x 預設啟動的服務內容 | |
服務名稱 | 功能簡介 |
abrtd | (系統)abrtd 服務可以提供使用者一些方式,讓使用者可以針對不同的應用軟體去設計錯誤登錄的機制, 當軟體產生問題時,使用者就可以根據 abrtd 的登錄檔來進行錯誤克服的行為。還有其他的 abrt-xxx.service 均是使用這個服務來加強應用程式 debug 任務的。 |
accounts-daemon (可關閉) |
(系統)使用 accountsservice 計畫所提供的一系列 D-Bus 界面來進行使用者帳號資訊的查詢。 基本上是與 useradd, usermod, userdel 等軟體有關。 |
alsa-X (可關閉) |
(系統)開頭為 alsa 的服務有不少,這些服務大部分都與音效有關!一般來說, 伺服器且不開圖形界面的話,這些服務可以關閉! |
atd | (系統)單一的例行性工作排程,詳細說明請參考第十五章。 抵擋機制的設定檔在 /etc/at.{allow,deny} 喔! |
auditd | (系統)還記得前一章的 SELinux 所需服務吧? 這就是其中一項,可以讓系統需 SELinux 稽核的訊息寫入 /var/log/audit/audit.log 中。 |
avahi-daemon (可關閉) |
(系統)也是一個用戶端的服務,可以透過 Zeroconf 自動的分析與管理網路。 Zeroconf 較常用在筆記型電腦與行動裝置上,所以我們可以先關閉他啦! |
brandbot rhel-* |
(系統)這些服務大多用於開機過程中所需要的各種偵測環境的腳本,同時也提供網路界面的啟動與關閉。 基本上,你不要關閉掉這些服務比較妥當! |
chronyd ntpd ntpdate |
(系統)都是網路校正時間的服務!一般來說,你可能需要的僅有 chronyd 而已! |
cpupower | (系統)提供 CPU 的運作規範~可以參考 /etc/sysconfig/cpupower 得到更多的資訊! 這傢伙與你的 CPU 使用情況有關喔! |
crond | (系統)系統設定檔為 /etc/crontab,詳細資料可參考第十五章的說明。 |
cups (可關閉) |
(系統/網路)用來管理印表機的服務,可以提供網路連線的功能,有點類似列印伺服器的功能哩! 你可以在 Linux 本機上面以瀏覽器的 http://localhost:631 來管理印表機喔!由於我們目前沒有印表機,所以可以暫時關閉他。 |
dbus | (系統)使用 D-Bus 的方式在不同的應用程式之間傳送訊息, 使用的方向例如應用程式間的訊息傳遞、每個使用者登入時提供的訊息資料等。 |
dm-event multipathd |
(系統)監控裝置對應表 (device mapper) 的主要服務,當然不能關掉啊! 否則就無法讓 Linux 使用我們的週邊裝置與儲存裝置了! |
dmraid-activation mdmonitor |
(系統)用來啟動 Software RAID 的重要服務!最好不要關閉啦!雖然你可能沒有 RAID。 |
dracut-shutdown | (系統)用來處理 initramfs 的相關行為,這與開機流程相關性較高~ |
ebtables | (系統/網路)透過類似 iptables 這種防火牆規則的設定方式,設計網路卡作為橋接時的封包分析政策。 其實就是防火牆。不過與底下談到的防火牆應用不太一樣。如果沒有使用虛擬化,或者啟用了 firewalld ,這個服務可以不啟動。 |
emergency rescue |
(系統)進入緊急模式或者是救援模式的服務 |
firewalld | (系統/網路)就是防火牆!以前有 iptables 與 ip6tables 等防火牆機制,新的 firewalld 搭配 firewall-cmd 指令,可以快速的建置好你的防火牆系統喔!因此,從 CentOS 7.1 以後,iptables 服務的啟動腳本已經被忽略了! 請使用 firewalld 來取代 iptables 服務喔! |
gdm | (系統)GNOME 的登入管理員,就是圖形界面上一個很重要的登入管理服務! |
getty@ | (系統)就是要在本機系統產生幾個文字界面 (tty) 登入的服務囉! |
hyper* ksm* libvirt* vmtoolsd |
(系統)跟建立虛擬機器有關的許多服務!如果你不玩虛擬機, 那麼這些服務可以先關閉。此外,如果你的 Linux 本來就在虛擬機的環境下,那這些服務對你就沒有用!因為這些服務是讓實體機器來建立虛擬機的! |
irqbalance | (系統)如果你的系統是多核心的硬體,那麼這個服務要啟動, 因為它可以自動的分配系統中斷 (IRQ) 之類的硬體資源。 |
iscsi* | (系統)可以掛載來自網路磁碟機的服務!這個服務可以在系統內模擬好貴的 SAN 網路磁碟。 如果你確定系統上面沒有掛載這種網路磁碟,也可以將他關閉的。 |
kdump (可關閉) |
(系統)在安裝 CentOS 的章節就談過這東西,主要是 Linux 核心如果出錯時,用來紀錄記憶體的東西。 鳥哥覺得不需要啟動他!除非你是核心駭客! |
lvm2-* | (系統)跟 LVM 相關性較高的許多服務,當然也不能關!不然系統上面的 LVM2 就沒人管了! |
microcode | (系統)Intel 的 CPU 會提供一個外掛的微指令集提供系統運作, 不過,如果你沒有下載 Intel 相關的指令集檔案,那麼這個服務不需要啟動的,也不會影響系統運作。 |
ModemManager network NetworkManager* |
(系統/網路)主要就是數據機、網路設定等服務!進入 CentOS 7 之後,系統似乎不太希望我們使用 network 服務了, 比較建議的是使用 NetworkManager 搭配 nmcli 指令來處理網路設定~所以,反而是 NetworkManager 要開,而 network 不用開哩! |
quotaon | (系統)啟動 Quota 要用到的服務喔! |
rc-local | (系統)相容於 /etc/rc.d/rc.local 的呼叫方式!只是,你必須要讓 /etc/rc.d/rc.local 具有 x 的權限後, 這個服務才能真的運作!否則,你寫入 /etc/rc.d/rc.local 的腳本還是不會運作的喔! |
rsyslog | (系統)這個服務可以記錄系統所產生的各項訊息, 包括 /var/log/messages 內的幾個重要的登錄檔啊。 |
smartd | (系統)這個服務可以自動的偵測硬碟狀態,如果硬碟發生問題的話, 還能夠自動的回報給系統管理員,是個非常有幫助的服務喔!不可關閉他啊! |
sysstat | (系統)事實上,我們的系統有隻名為 sar 的指令會記載某些時間點下,系統的資源使用情況,包括 CPU/流量/輸入輸出量等, 當 sysstat 服務啟動後,這些紀錄的資料才能夠寫入到紀錄檔 (log) 裡面去! |
systemd-* | (系統)大概都是屬於系統運作過程所需要的服務,沒必要都不要更動它的預設狀態! |
plymount* upower |
(系統)與圖形界面的使用相關性較高的一些服務!沒啟動圖形界面時,這些服務可以暫時不管他! |
上面的服務是 CentOS 7.x 預設有啟動的,這些預設啟動的服務很多是針對桌上型電腦所設計的,所以囉,如果你的 Linux 主機用途是在伺服器上面的話,那麼有很多服務是可以關閉的啦!如果你還有某些不明白的服務想要關閉的, 請務必要搞清楚該服務的功能為何喔!舉例來說,那個 rsyslog 就不能關閉,如果你關掉他的話,系統就不會記錄登錄檔, 那你的系統所產生的警告訊息就無法記錄起來,你將無法進行 debug 喔。
底下鳥哥繼續說明一些可能在你的系統當中的服務,只是預設並沒有啟動這個服務就是了。只是說明一下, 各服務的用途還是需要您自行查詢相關的文章囉。
其他服務的簡易說明 | |
服務名稱 | 功能簡介 |
dovecot | (網路)可以設定 POP3/IMAP 等收受信件的服務,如果你的 Linux 主機是 email server 才需要這個服務,否則不需要啟動他啦! |
httpd | (網路)這個服務可以讓你的 Linux 伺服器成為 www server 喔! |
named | (網路)這是領域名稱伺服器 (Domain Name System) 的服務, 這個服務非常重要,但是設定非常困難!目前應該不需要這個服務啦! |
nfs nfs-server |
(網路)這就是 Network Filesystem,是 Unix-Like 之間互相作為網路磁碟機的一個功能。 |
smb nmb |
(網路)這個服務可以讓 Linux 模擬成為 Windows 上面的網路上的芳鄰。 如果你的 Linux 主機想要做為 Windows 用戶端的網路磁碟機伺服器,這玩意兒得要好好玩一玩。 |
vsftpd | (網路)作為檔案傳輸伺服器 (FTP) 的服務。 |
sshd | (網路)這個是遠端連線伺服器的軟體功能, 這個通訊協定比 telnet 好的地方在於 sshd 在傳送資料時可以進行加密喔!這個服務不要關閉他啦! |
rpcbind | (網路)達成 RPC 協定的重要服務!包括 NFS, NIS 等等都需要這東西的協助! |
postfix | (網路)寄件的郵件主機~因為系統還是會產生很多 email 訊息!例如 crond / atd 就會傳送 email 給本機用戶! 所以這個服務千萬不能關!即使你不是 mail server 也是要啟用這服務才行! |
[root@study ~]# systemctl status sshd.service sshd.service - OpenSSH server daemon Loaded: loaded (/usr/lib/systemd/system/sshd.service; enabled) Active: active (running) since Thu 2015-08-13 14:31:12 CST; 20h ago [root@study ~]# cat /usr/lib/systemd/system/sshd.service [Unit] Description=OpenSSH server daemon After=network.target sshd-keygen.service Wants=sshd-keygen.service [Service] EnvironmentFile=/etc/sysconfig/sshd ExecStart=/usr/sbin/sshd -D $OPTIONS ExecReload=/bin/kill -HUP $MAINPID KillMode=process Restart=on-failure RestartSec=42s [Install] WantedBy=multi-user.target
[root@study ~]# cd /etc/ssh [root@study ssh]# cp sshd_config sshd2_config [root@study ssh]# vim sshd2_config Port 222 # 隨意找個地方加上這個設定值!你可以在檔案的最下方加入這行也 OK 喔!
[root@study ~]# cd /etc/systemd/system [root@study system]# cp /usr/lib/systemd/system/sshd.service sshd2.service [root@study system]# vim sshd2.service [Unit] Description=OpenSSH server daemon 2 After=network.target sshd-keygen.service Wants=sshd-keygen.service [Service] EnvironmentFile=/etc/sysconfig/sshd ExecStart=/usr/sbin/sshd -f /etc/ssh/sshd2_config -D $OPTIONS ExecReload=/bin/kill -HUP $MAINPID KillMode=process Restart=on-failure RestartSec=42s [Install] WantedBy=multi-user.target [root@study system]# systemctl daemon-reload [root@study system]# systemctl enable sshd2 [root@study system]# systemctl start sshd2 [root@study system]# tail -n 20 /var/log/messages # semanage port -a -t PORT_TYPE -p tcp 222 where PORT_TYPE is one of the following: ssh_port_t, vnc_port_t, xserver_port_t. # 認真的看!你會看到上面這兩句!也就是 SELinux 的埠口問題!請解決! [root@study system]# semanage port -a -t ssh_port_t -p tcp 222 [root@study system]# systemctl start sshd2 [root@study system]# netstat -tlnp | grep ssh tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1300/sshd tcp 0 0 0.0.0.0:222 0.0.0.0:* LISTEN 15275/sshd tcp6 0 0 :::22 :::* LISTEN 1300/sshd tcp6 0 0 :::222 :::* LISTEN 15275/sshd