xinetd 服務管理

xinetd

xinetd 本身是由 System V 腳本所管理,它會監控由它管理的服務所需監聽的 port,當有連線由監聽 ports 連入時,xinetd 會啟動相對應的服務,當連線中斷時,xinetd 就會中止該服務的執行。和System V 所管理 standalone 的服務比較起來,xinetd 所管理的服務在閒置時不會佔用系統資源,直到有連線要求時才會啟動服務;而 standalone 的服務會常駐在記憶體中,當有連線需求時能夠直接回應要求,反應更為迅速。

交由 xinetd 管理的服務,可將設定檔寫在 /etc/xinetd.conf 中,或是將之放置在 /etc/xinetd.d/ 底下,以服務名稱作區隔,前者只要設定一個檔案即可,但是檔案內容會太長;而後者是檔案數量比較多,可是每個服務有自己的設定檔,不會相互影響,也可以直接修改特定的服務。現在比較常見的作法是,全域設定就放在 /etc/xinetd.conf 之中,而個別服務的設定就在 /etc/xinetd.d/SERVICE_NAME 之中,當兩個設定內容相衝突時,以個別服務的設定為主。

在設定檔中,只會寫出服務的名稱,而要監聽那個 ports,xinetd 就會到 /etc/services 檔案中查詢相對應的埠。在 Red Hat 的 xinetd 套件,在編譯時已連結了 libwrap.so 函式庫,所以 xinetd 也支援由 /etc/hosts.allow 和 /etc/hosts.deny 兩個檔案來作連線限制的動作。

xinetd 對連入連線的管控流程:
連線--> xinetd --> 比對 xinetd 本身的 ACL --> 呼叫 libwrap.so 比對 hosts.allow 和 hosts.deny --> 啟動服務

==============================

xinetd.conf

xinetd 將全域設定放在 /etc/xinetd.conf 之中,如果各服務的個別設定沒有設,則以全域設定為主。它的內容如下:

#/etc/xinetd.conf
defaults
{
enabled            = yes          (是否開啟此項服務)
instances          = 50          (服務的最大連線數)
per_source       = 10          (同一來源的最大連線數)
v6only              = no
log_type           = SYSLOG  daemon  info          (記錄交由 syslogd 來處理,並把記錄的類型定為 daemon,記錄等級為 info)
log_on_failure  = HOST          (建立連線失敗時,要記錄那些內容)
log_on_success = PID  HOST  DURATION  EXIT          (連線建立成功時,要記錄那些內容)
cps                    = 50  10          (同一個服務在同一秒內收到 50 個請求時,就將該服務暫止 10 秒鐘,數字自己調)
banner              = /PATH/FILE_NAME
}
includedir    /etc/xinetd.d

xinetd 的個別服務設定放在 /etc/xinetd.d/SERVICE_NAME 中:

# ls  /etc/xinetd.d/
chargen-dgram   discard-dgram    ekrb5-telnet       ktalk          time-stream
chargen-stream   discard-stream    gssftp                rsync
cvs                       echo-dgram        klogin                tcpmux-server
daytime-dgram    echo-stream       krb5-telnet         telnet
daytime-stream   eklogin               kshell                  time-dgram

來看一下其中一個服務 tftp :

# cat  /etc/xinetd.d/tftp
# default: off
service tftp
(服務名稱,xinetd 會去比對 /etc/services 裡定義的服務埠,並監聽該埠)
{
socket_type             = dgram
(服務連線是 TCP 或 UDP,TCP 設為 stream、UDP 設為 dgram)
protocol                = udp
wait                    = yes
(同一時間內是否允許一個以上使用者同時存取,允許則其他連線就不用等,所以設為 no,如果只允許一個連線,其他連線就要等待,所以設為 yes)
user                    = root
(本服務以什麼帳號執行)
server                  = /usr/sbin/in.tftpd
(服務 daemon 的檔名,路徑+執行檔)
server_args             = -s /tftpboot
(服務執行時的參數)
disable                 = yes
(是否啟用本服務,yes 關閉、no 開啟)
per_source              = 11
(限定同一個 client 同時可以有幾個連線)
cps                     = 100 2
flags                   = IPv4
}

再看一下 telnet 的設定檔:

# cat /etc/xinetd.d/telnet
# default: off
service telnet
{
disable         = yes
flags           = REUSE
socket_type     = stream
wait            = no
user            = root

nice                 = 10 (本服務的 nice 值,19 ~ -20)
redirect           = 192.168.0.250  23 (將連線請求轉向另一臺主機)
only_from       = 192.168.0.0/24 (只允許 192.168.0.0/24 網段的電腦連線)
no_access        = 192.168.1.0/24 (不允許 192.168.1.0/24 網段的電腦連線)
access_times    = 12:00-16:00 (本服務只開放 12:00 ~ 16:00)
server          = /usr/sbin/in.telnetd
log_on_failure  += USERID
(使用 xinded.conf 的記錄,另加上 USERID 記錄)
log_on_success -= DURATION (使用 xinetd.conf 的記錄,但不要 DURATION 記錄)
}

記錄檔事項代號:
PID                 (success)                   連線成功時服務的 PID
HOST             (success, failure)       記錄用戶端的 IP
USERID          (success, failure)       記錄用戶端符合 RFC 1413 規定的 ID
EXIT               (success)                   記錄服務結束時的訊息
DURATION    (success)                    記錄連線時間長度
ATTEMPT      (failure)                     記錄連線失敗原因
RECORD         (failure)                    記錄連線失敗的其他訊息

==============================

tcp_wrappers

每個服務都會有個自的連線安全設定方式,但是通常也會使用 tcp_wrappers 作為另一種連線安全設定的方式,雖然它是透過 libwrap.so 函式庫作 host-based 的連線限制,只能對 IP、網段、及主機作限制,但是優點是所有服務只要在同一個地方設定就可以了。有連線到 libwrap.so 的服務有:sendmail, slapd, sshd, stunnel, xinetd, gdm, gnome-session, vsftpd, portmap。

想要知道該服務有沒有連結到 libwrap.so,可以用 ldd 這支程式 ,ldd 可以追蹤執行檔連結的函式庫:

# ldd  /usr/sbin/sshd
linux-gate.so.1 =>  (0x00335000)
libwrap.so.0 => /usr/lib/libwrap.so.0 (0x002a8000)
libpam.so.0 => /lib/libpam.so.0 (0x003e3000)
libdl.so.2 => /lib/libdl.so.2 (0x00ff0000)
libselinux.so.1 => /lib/libselinux.so.1 (0x008cf000)
libaudit.so.0 => /lib/libaudit.so.0 (0x0072b000)
libresolv.so.2 => /lib/libresolv.so.2 (0x00110000)
libcrypto.so.6 => /lib/libcrypto.so.6 (0x00134000)
libutil.so.1 => /lib/libutil.so.1 (0x00123000)
libz.so.1 => /usr/lib/libz.so.1 (0x0098a000)
libnsl.so.1 => /lib/libnsl.so.1 (0x00cb1000)
libcrypt.so.1 => /lib/libcrypt.so.1 (0x00865000)
libgssapi_krb5.so.2 => /usr/lib/libgssapi_krb5.so.2 (0x00266000)
libkrb5.so.3 => /usr/lib/libkrb5.so.3 (0x00336000)
libk5crypto.so.3 => /usr/lib/libk5crypto.so.3 (0x00eb7000)
libcom_err.so.2 => /lib/libcom_err.so.2 (0x007a7000)
libc.so.6 => /lib/libc.so.6 (0x003ee000)
/lib/ld-linux.so.2 (0x009ce000)
libsepol.so.1 => /lib/libsepol.so.1 (0x002b0000)
libkrb5support.so.0 => /usr/lib/libkrb5support.so.0 (0x00ce3000)

tcp_wrappers 的連線設定檔放在 /etc/hosts.allow 和 /etc/hosts.deny 中,整個連線程序如下:

連入連線 --> 是否在 hosts.allow 中 --是--> ALLOW <--否
.                                           |                                                                    |
.                                            ------否--> 是否在 hosts.deny 中 --是--> DENY

hosts.allow 和 hosts.deny 是採 first match 方式比對,先比對到的規則先生效,檔案修改完後,下一個連線馬上生效。兩個檔案使用的語法一樣:

服務執行檔: 目標網段或IP  [:擴充功能1  :擴充功能2 ……] (服務執行檔用 rpm  -ql  SERVER_RPM_NAME 來找)

in.telnetd:  192.168.0.1          (telnet 服務,對 192.168.0.1 這個 IP)
sshd, gdm:  192.168.0.2, 192.168.0.3          (sshd, gdm 這些服務,對 192.168.0.2 和 192.168.0.3 這兩個 IP,用逗點區隔)
vsftpd@192.168.0.50:      192.168.0.          (vsftpd 服務於 192.168.0.50 這個 IP 連入的連線,對 192.168.0 整個網段)
vsftpd@168.95.88.99:      168.95.1.1         (vsftpd 服務於 168.95.88.99 這個 IP 連入的連線,對 168.95.1.1 這個 IP)

hosts.allow 和 hosts.deny 中的通用字元 (wildcards):
ALL:全部服務或全部主機
LOCAL:不包含點的主機名稱,也就是定義在 /etc/hosts 中的所有 IP
UNKNOWN:無法解析的主機名稱
KNOWN:可以反向解析的 IP
PARANOID:DNS 正向解析名稱不一致的主機名稱或 IP
EXCEPT:除外,後面接服務執行檔、主機名稱或 IP

例:
/etc/hosts.allow
sshd:  ALL  EXCEPT  .cracker.org  EXCEPT  trusted.cracker.org
/etc/hosts.deny
sshd:  ALL
上面的例子顯示,連線進來時先比對 hosts.allow,可允許通過的是所有主機和 trusted.cracker.org 這台主機,但是其他的 *.cracker.org 的主機不在此列。所以當 xyz.cracker.org 這台主機連進來時,在 hosts.allow 被擋了下來(還沒拒絕連線),再去和 hosts.deny 作比對,如果 hosts.deny 是空的, xyz.cracker.org 就可以連線成功,所以在 hosts.deny 中要加上 sshd: ALL 這一行,這樣 xyz.cracker.org 到此才會真正的被拒絕連線。

在 Red Hat 中的 tcp_wrappers 可允許在設定檔中加入其他的擴充功能,可用 man 來詳細了解:
#man hosts_options
在擴充功能中,最常被用到的功能是 spawn,它可以在當 client 符合到其中一條規則時,啟動某個程式,例如:
in.telnetd:  ALL  :  spawn  echo  “login  attemp  from  %c  to  %s”  |  mail  -s  warning  root
(當有人 telnet 連線時,會寄一封信給 root,主旨是 warning,內容是 login attemp from %c to %s)
其他常用變數有:
%c    用戶端的資訊 (user@host)
%s    伺服端的資訊 (server@host)
%h    用戶端的主機名稱或 IP
%p    服務的 PID

*服務執行檔:
服務的執行檔有的時候並不是我們直覺的那樣,像 telnet 服務的執行檔是 in.telnetd、ssh 服務執行檔是 sshd,如果不知道或不確定,可以以下方法:
# rpm -qa | grep ssh (先確定 ssh server 的套件名稱)
openssh-clients-4.3p2-16.el5
openssh-server-4.3p2-16.el5
(就是它了)
openssh-askpass-4.3p2-16.el5
openssh-4.3p2-16.el5

# rpm -ql openssh-server (列出所有檔案名稱,服務執行檔通常會在 /sbin 或 /usr/sbin)
/etc/pam.d/sshd
/etc/rc.d/init.d/sshd
/etc/ssh
/etc/ssh/sshd_config
/usr/libexec/openssh/sftp-server
/usr/sbin/sshd (就是它了)
/usr/share/man/man5/sshd_config.5.gz
/usr/share/man/man8/sftp-server.8.gz
/usr/share/man/man8/sshd.8.gz
/var/empty/sshd
/var/empty/sshd/etc

找一下 telnet 的服務執行檔:

# rpm -qa | grep telnet
telnet-0.17-38.el5
telnet-server-0.17-38.el5

# rpm -ql telnet-server
/etc/xinetd.d/telnet
/usr/sbin/in.telnetd
/usr/share/man/man5/issue.net.5.gz
/usr/share/man/man8/in.telnetd.8.gz
/usr/share/man/man8/telnetd.8.gz

在《xinetd 服務管理》中有 1 則留言

  1. 自動引用通知: ISHM Blog » 網路檔案系統服務 (NFS)

留言功能已關閉。