天天看點

linux守護程序原理及建立詳解

在linux或者unix作業系統中在系統的引導的時候會開啟很多服務,這些服務就叫做守護程序。為了增加靈活性,root可以選擇系統開啟的模式,這些模式叫做運作級别,每一種運作級别以一定的方式配置系統。 守護程序是脫離于終端并且在背景運作的程序。守護程序脫離于終端是為了避免程序在執行過程中的資訊在任何終端上顯示并且程序也不會被任何終端所産生的終端資訊所打斷。

一. 守護程序簡介

  守護程序,也就是通常說的Daemon程序,是Linux中的背景服務程序。它是一個生存期較長的程序,通常獨立于控制終端并且周期性地執行某種任務或等待處理某些發生的事件。守護程序常常在系統引導裝入時啟動,在系統關閉時終止。Linux系統有很多守護程序,大多數服務都是通過守護程序實作的,同時,守護程序還能完成許多系統任務,例如,作業規劃程序crond、列印程序lqd等(這裡的結尾字母d就是Daemon的意思)。

  由于在Linux中,每一個系統與使用者進行交流的界面稱為終端,每一個從此終端開始運作的程序都會依附于這個終端,這個終端就稱為這些程序的控制終端,當控制終端被關閉時,相應的程序都會自動關閉。但是守護程序卻能夠突破這種限制,它從被執行開始運轉,直到整個系統關閉時才退出。如果想讓某個程序不因為使用者或終端或其他地變化而受到影響,那麼就必須把這個程序變成一個守護程序。

二.守護程序的分類

   根據守護程序的啟動和管理方式,可以分為獨立啟動守護程序和超級守護程序兩類

   獨立啟動(stand_alone):該類程序啟動後就常駐記憶體,是以會一直占用系統資源。其最大的優點就是它會一直啟動,當外界有要求時相應速度較快,像httpd等程序;

   超級守護程序:系統啟動時由一個統一的守護程序xinet來負責管理一些程序,當相應請求到來時需要通過xinet的轉接才可以喚醒被xinet管理的程序。這種程序的優點時最初隻有xinet這一守護程序占有系統資源,其他的内部服務并不一直占有系統資源,隻有資料包到來時才會被xinet管理者來喚醒。并且我們還可以通過xinet來對它所管理的程序設定一些通路權限,相當于多了一層管理機制。

如果用兩個比喻來形容兩類守護程序的話一般會用銀行的業務處理視窗來類比:

獨立啟動 :銀行裡有一種單服務的視窗,像取錢,存錢等視窗,這些視窗邊上 始終會 坐着一個人,如果有人來取錢或存錢,可以直接到相應的視窗去辦理,這個處理單一服務的始終存在的人就是獨立啟動的守護程序; 超級守護程序 :銀行裡還有一種視窗,提供綜合服務,像彙款,轉賬,提款等業務;這種視窗附近也始終坐着一個人(xinet),她可能不提供具體的服務,提供具體服務的人在裡面閑着聊天啊,喝茶啊,但是當有人來彙款時他會大聲喊一句,小王,有人彙款啦,然後裡面管彙款的小王會立馬跑過來幫忙辦完彙款業務。其他的人繼續聊天,喝茶。這些負責具體業務的人我們就稱之為超級守護程序。當然可能彙款人會有一些規則,可能不能往北京彙款,他就會提早告訴xinet,是以如果有人來彙款想彙往北京的話,管理者就直接告訴他這個我們這裡辦不到的,于是就根本不會去喊彙款員了,相當于提供了一層管理機制。針對這種視窗還存在多線程和單線程的差別: 多線程 :将所有使用者的要求都提上來,裡面的人都别閑着了,都一起幹活吧; 單線程

:大家都排好隊了,一個一個來,裡面的人同一時間隻有一個人在工作。

這裡需要注意的是超級守護程序的管理者xinet也是一個守護程序,隻不過它的任務就是傳話,其實這也是一個很具體很艱巨的任務哦。

當然每個守護程序都會監聽一個端口(銀行視窗),一些常用守護程序的監聽端口是固定的,像httpd監聽80端口, sshd監聽22端口等;我們可以将其了解為責任制,時候等待,有求必應。具體的端口資訊可以通過cat /etc/services來檢視。

三. 守護程序的命名規則和位

   服務程序後面通常會加一個d來表示,想負責http服務的httpd程序,cron服務的crond程序,這隻不過是一種約定,就想銀行裡的從業人員需要穿特定的制服是一樣的。

 每個守護程序都會有一個腳本,可以了解成工作内容說明書,還是需要分開來講解:

 獨立啟動守護程序:放在/etc/init.d/目錄下,當然也包括xinet的shell腳本;

 超級守護程序:按照xinet中腳本的訓示,它所管理的守護程序位于/et/xinetd.d/下,

 獨立啟動的守護程序啟動方式很簡單:

  # /etc/init.d/syslog start    stop       restart

 # service syslog start

    其中service指令也隻能啟動位于/etc/init.d/目錄先的程序,這由service指令的内容來決定的;裡面一定有case判斷,可以檢視/bin/service檢視其運作方式;

  超級守護程序:xinet要啟動起來,并且相應服務的人員都在,及在/etc/xinet.d/ftp裡開啟了此服務。超級守護程序的管理規則首先通過/etc/xinetd.conf來設定,裡面為一些預設設定,既通路此視窗的基本要求,像要有×××啊,啥的,然後每個具體的服務也會有自己的一些社會自,這些設定在/etc/xinet.d/中都有相應的設定檔案的。

詳述超級守護程序和它的配置檔案

     利用超級守護程序來管理(網絡)服務的最大好處是“安全性較高”。因為超級守護程序可以通過額外的資料分析,來管理誰可以,誰不可以使用某項服務。類似于多了一層防火牆的機制,確定了安全性。

     挂在xinetd例的服務設定項目寫在/etc/xinetd.conf與/etc/xinetd.d/*目錄的任何檔案中。

     1)/etc/xinetd.conf:設定xinetd服務的預設參數檔案

     # ......

     defaults

     {

     # Please note that you need a log_type line to be able to use log_on_success

     # and log_on_failure. The default is the following :

     # log_type = SYSLOG daemon info

     instances = 60                          # 同一服務的同時聯機最多60台

     log_type = SYSLOG authpriv     # 登入後會記錄到檔案中的資訊

     log_on_success = HOST PID     # 成功登入時,會記錄的資訊有哪些

     log_on_failure = HOST              # 若登入失敗,記錄的資訊是什麼

     cps = 25 30                               # 同一秒内最大聯機數量為25台,若超過25台,則該服務會暫停30秒

     }

     includedir /etc/xinetd.d              # 在此目錄中,挂靠的服務可以有自己的參數,如果沒有定義,則遵守上面的配置

     2)/etc/xinetd.d/*:這個目錄裡面的檔案都是挂上xinetd的所有服務,如telnet、pop3等。

     以telnet服務為例,它的配置檔案如下。

     # default: on

     # description: The telnet server serves telnet sessions; it uses \

     # unencrypted username/password pairs for authentication.

     service telnet

     {

        disable = no                                      # 開關,該服務可以進行開啟

        only_from = 192.168.1.0/24             # 僅允許來自網段192.168.1.0/24的連接配接

        no_access = 192.168.1.3

        flags = REUSE                                   #  額外的參數使用REUSE

        socket_type = stream                       # 聯機使用的資料包是TCP,如果為dgram,則使用UDP

        wait = no                                          # 多線程方式,多個請求同時啟動

        user = flagonxia                                # 啟動者預設為flagonxia

        server = /usr/sbin/in.telnetd             # 服務的啟動程式檔案的完整路徑名

        log_on_failure += USERID                 # 失敗後,syslog記錄的項目

}

四. 檢視系統打開的服務

有幾條常用的指令可以用來檢視

# service iptables status    #檢視相應服務的狀态,用service需要服務在/etc/init.d/目錄中存在

# netstat -tulp    #會列出相應的服務及其監聽的端口号等,若加n參數會列出端口号

#chkconfig --list |grep 服務名 #會列出現在目前服務的各種狀态,包括在不同運作級别下的啟情況,分為上線兩部分,上部分是獨立啟動的服務,你會看到xinetd也在,下面部分是有inet管理的超級守護程序,沒有運作級别可分的。

假設有一個服務想iptables服務想讓其在開機啟動時運作,可以通過指令chkconfig來實作,

 #chkconfig --level **  iptables on

若想建立自己的服務并讓其在啟動時運作也可以,但這種任務在其腳本的書寫方式上有一定寫法,像myvbird:#!/bin/bash

#chkconfig: 35 80 70

#第二行的文法為chkconfig: [run_level] [start number] [stop number]

然後在外部指令行中将其加入chkconfig的管理中為:

# chkconfig --add  myvbird

# chkconfig --list myvbird

myvbird   0:off 1: off 3: on 4:off 5: on 6:off

總之方式還是挺多的,可具體到網上搜尋。

五:建立守護程序

建立子程序,父程序退出

  這是編寫守護程序的第一步。由于守護程序是脫離控制終端的,是以,完成第一步後就會在Shell終端裡造成一程式已經運作完畢的假象。之後的所有工作都在子程序中完成,而使用者在Shell終端裡則可以執行其他指令,進而在形式上做到了與控制終端的脫離。

  在Linux中父程序先于子程序退出會造成子程序成為孤兒程序,而每當系統發現一個孤兒程序是,就會自動由1号程序(init)收養它,這樣,原先的子程序就會變成init程序的子程序。

在子程序中建立新會話

  這個步驟是建立守護程序中最重要的一步,雖然它的實作非常簡單,但它的意義卻非常重大。在這裡使用的是系統函數setsid,在具體介紹setsid之前,首先要了解兩個概念:程序組和會話期

  程序組:是一個或多個程序的集合。程序組有程序組ID來唯一辨別。除了程序号(PID)之外,程序組ID也是一個程序的必備屬性。每個程序組都有一個組長程序,其組長程序的程序号等于程序組ID。且該程序組ID不會因組長程序的退出而受到影響。

  會話周期:會話期是一個或多個程序組的集合。通常,一個會話開始與使用者登入,終止于使用者退出,在此期間該使用者運作的所有程序都屬于這個會話期。

  接下來就可以具體介紹setsid的相關内容:

  (1)setsid函數作用:

  setsid函數用于建立一個新的會話,并擔任該會話組的組長。調用setsid有下面的3個作用:

  讓程序擺脫原會話的控制

  讓程序擺脫原程序組的控制

  讓程序擺脫原控制終端的控制

  那麼,在建立守護程序時為什麼要調用setsid函數呢?由于建立守護程序的第一步調用了fork函數來建立子程序,再将父程序退出。由于在調用了fork函數時,子程序全盤拷貝了父程序的會話期、程序組、控制終端等,雖然父程序退出了,但會話期、程序組、控制終端等并沒有改變,是以,還還不是真正意義上的獨立開來,而setsid函數能夠使程序完全獨立出來,進而擺脫其他程序的控制。

改變目前目錄為根目錄

  這一步也是必要的步驟。使用fork建立的子程序繼承了父程序的目前工作目錄。由于在程序運作中,目前目錄所在的檔案系統(如“/mnt/usb”)是不能解除安裝的,這對以後的使用會造成諸多的麻煩(比如系統由于某種原因要進入單使用者模式)。是以,通常的做法是讓"/"作為守護程序的目前工作目錄,這樣就可以避免上述的問題,當然,如有特殊需要,也可以把目前工作目錄換成其他的路徑,如/tmp。改變工作目錄的常見函數式chdir。

重設檔案權限掩碼

  檔案權限掩碼是指屏蔽掉檔案權限中的對應位。比如,有個檔案權限掩碼是050,它就屏蔽了檔案組擁有者的可讀與可執行權限。由于使用fork函數建立的子程序繼承了父程序的檔案權限掩碼,這就給該子程序使用檔案帶來了諸多的麻煩。是以,把檔案權限掩碼設定為0,可以大大增強該守護程序的靈活性。設定檔案權限掩碼的函數是umask。在這裡,通常的使用方法為umask(0)。

關閉檔案描述符

繼續閱讀