隨筆-49  評論-67  文章-27  trackbacks-0

          原文出處

          http://www.dbanotes.net/OpenSource/Using_xinetd.html

          [OpenSource] 使用xinetd

          作者:Jose Nazario
          譯者:Fenng
          日期:25-Oct-2004
          出處:http://www.dbanotes.net
          版本:@2001/11/27 Version 0.01 @2003/05/23 Version 1.00

          Jose描述了如何著手配置調(diào)整xinetd

          xinetd取代了inetd,并且提供了訪問控制、加強(qiáng)的日志和資源管理功能。xinetd已經(jīng)成為Red Hat 7 和 Mandrake 7.2的Internet標(biāo)準(zhǔn)超級守護(hù)進(jìn)程。這篇文章將引導(dǎo)你如何應(yīng)用一些它的特性,這些特性基于xinetd 2.1.8.8 pre3版本。

          導(dǎo)言

          xinetd的最初的作者(Panagoitis Tsirigotis panos@cs.colorado.edu)好像已經(jīng)停止了這個項目。 Rob Braun (bbraun@synack.net)繼續(xù)了該項目,現(xiàn)在負(fù)責(zé)維護(hù)這個軟件包。為了能使 select()在我的老的libc5系統(tǒng)上也可以使用,我不得不給當(dāng)前的包添加幾對頭文件,這是我注意到的問題。或許你需要它們,如下:

          xinetd/internals.c.orig
          Fri Jun 16 19:00:15 2000
          +++ xinetd/internals.c
          Fri Jun 16 19:00:53 2000
          @@ -12,6 +12,8 @@
           #include <time.h>
           #include <fcntl.h>
           #include <syslog.h>
           #include <unistd.h>
           #include <sys/time.h>
           #include "sio.h"
          

          關(guān)于 xinetd

          xinetd用括號括起的、擴(kuò)展了的語法取代了inetd中的通用的行。另外,還添加了日志和訪問控制功能。 雖然inetd可以使用Venema的 tcp_wrappers 軟件 (tcpd) 控制 TCP 的連接,但是你不能用它來控制 UDP 連接。此外,inetd對RPC(portmapper)類型的服務(wù)也處理不好。另外,雖然使用 inetd 你可以控制連接速度 ( 通過給wait或是no wait 變量附加一個數(shù)值,例如nowait.1表示每隔一秒鐘一個實例),你不能控制實例的最大數(shù)。這能導(dǎo)致進(jìn)程表攻擊(例如,一個有效的拒絕服務(wù)攻擊)。通過使用xinetd,我們可以防止Dos

          我通常使用下面的命令啟動xinetd,把它放在我的Internet服務(wù)啟動腳本中:

          /usr/sbin/xinetd -filelog /var/adm/xinetd.log -f /etc/xinetd.conf
          

          這告訴 xinetd 對所有的服務(wù)都進(jìn)行紀(jì)錄,日志保存到文件 /var/adm/xinetd.log中,并且使用配置文件/etc/xinetd.conf。這篇文章中的大量篇幅都將用在這個配置文件上。

          編譯時選項

          你應(yīng)該注意3個編譯時的選項:libwrap、loadavg (用于監(jiān)視負(fù)載均衡) 和 IPv6 support,它們提供了額外的訪問控制。對于大多數(shù)libwrap"明白"的守護(hù)進(jìn)程 (如portmapper 和sendmail),在配置腳本中的"with-libwrap"選項告訴xinetd支持tcp_wrappers文件/etc/hosts.allow和/etc/hosts.deny。這些選項對xinetd作用就如同它們之于 inetd那樣,并且支持所有的 xinetd控制的守護(hù)進(jìn)程。注意如果你從零開始做xinetd的話,就可以做訪問控制,不再需要tcpd。不管怎樣。對libwrap 的支持是有用的--如果你從inetd/tcpd遷移并且也不想改變你的訪問文件的話 。

          第二個有趣的設(shè)置選項是支持負(fù)載均衡監(jiān)控,通過在./configure腳本中使用with-loadavg選項可以達(dá)到。sendmail支持在高負(fù)載的時候停止連接--假定它已經(jīng)脫離了控制并且正在當(dāng)?shù)魴C(jī)器。用這個選項可以激活max_load 選項以限制任何連接或是基于負(fù)載均衡機(jī)器的所有服務(wù)。

          最后,添加 IPv6支持 可以通過在 ./configure 腳本中使用 with-inet6 capability選項來完成。 這使xinetd 支持IPv6地址和連接。注意要使其生效的話你的核心(和網(wǎng)絡(luò))必須支持 IPv6。當(dāng)然IPv4 仍然被支持。

          配置文件

          xinetd 配置文件,通常可以手工或是自動從inetd.conf文件生成。前者費時間且容易出錯;后者可以通過 itox軟件或者xconv.pl 腳本輕易完成。雖然itox軟件正在被取消而傾向于使用 xconv.pl 腳本,它仍是很有用的。但是,要注意重復(fù)的運行它會覆蓋原有的配置文件。itox和 xconv都以同樣的方式工作,我們用 itox來進(jìn)行演示:

          $ itox < /etc/inetd.conf > xinetd.conf
          

          新一些的工具(xconv)可以理解注釋,并且在對tcpd的使用上要比itox做得更好,使用itox,你不得不指定守護(hù)進(jìn)程的路徑 (如 /usr/sbin)。 你想要包含的第一段就是默認(rèn)的段,就像名字暗示的那樣,默認(rèn)的xinetd服務(wù)。

          defaults
          {
             instances       = 25
             log_type        = FILE /var/adm/servicelog
             log_on_success  = PID HOST EXIT
             flags           = NORETRY
             log_on_failure  = HOST RECORD ATTEMPT
             only_from       = 129.22.0.0
             no_access       = 129.22.210.61 
             disabled        = nntp uucp tftp bootps who
                               shell login exec 
             disabled       += finger
          }
          

          馬上,我們可以了解 xinetd 設(shè)置參數(shù)的語法:<指示(directive)> <操作符(operator)> <值(value)>。xinetd所能理解的指示列在表一中,在這里我們將忽略 flags、type、env 和passenv指示符。 我對將對 only_from 和 no_access以及額外的日志選項加以更多的討論

          表 1. xinetd的指示符
          指示符 描述
          socket_type 網(wǎng)絡(luò)套接字類型, 流或者數(shù)據(jù)包
          socket_type 網(wǎng)絡(luò)套接字類型, 流或者數(shù)據(jù)包
          protocol IP 協(xié)議, 通常是TCP或者 UDP
          wait yes/no, 等同于inetd的wait/nowait
          user 運行進(jìn)程的用戶 ID
          server 執(zhí)行的完整路徑
          server_args 傳遞給server的變量,或者是值
          instances 可以啟動的實例的最大的值
          start max_load 負(fù)載均衡
          log_on_success 成功啟動的登記選項
          log_on_failure 聯(lián)機(jī)失敗的時候的日志信息
          only_from 接受的網(wǎng)絡(luò)或是主機(jī)
          no_access 拒絕訪問的網(wǎng)絡(luò)或是主機(jī)
          disabled 用在默認(rèn)的 {} 中 禁止服務(wù)
          log_type 日志的類型和路徑 FILE /SYSLOG
          nice 運行服務(wù)的優(yōu)先級
          id 日志中使用的服務(wù)名

          操作符非常簡單,“=”或者“+=”。用 =,右邊給定的值傳給左邊的指示符。+=也是非常直接的,用于給一個已經(jīng)指定的指示符添加一個值。沒有它,原先的指示符就會被覆蓋,這樣可以用來展開訪問列表,或者跨越多行。

          用如下的格式描述服務(wù):

          服務(wù)名 
          {
          指示符 = 值
          指示符 += 值
          }

          服務(wù)名一定要在 /etc/services列出 ,并且要使用合適的socket和協(xié)議。

          關(guān)于訪問控制

          關(guān)于訪問控制的有幾句話。 首先,xinetd控制連接而不是控制數(shù)據(jù)分組,它只是個用戶方的守護(hù)進(jìn)程,如同inetd 一樣。同樣的,可以打斷一個被服務(wù)器禁止的主機(jī)的SYN或是connect()。但不能中止象FIN [端口掃描使用帶有FIN 標(biāo)志位的TCP包,通常是nmap這樣的工具運行產(chǎn)生的]這樣的"秘密" 掃描。不要把xinetd 當(dāng)作一個firewall 用以阻止端口掃描。一個有經(jīng)驗的入侵者能夠用這些信息收集你的不同服務(wù)的訪問控制列表。幸運的是, 這些可以被xinetd紀(jì)錄。當(dāng)你看到日志的時候你的疑慮會消除的。

          第二,xinetd(2.1.8.8pre3版本),當(dāng)一個系統(tǒng)試圖連接的時候進(jìn)行名字查找。以前,它在啟動的時候進(jìn)行查找, 但是現(xiàn)在已經(jīng)改變。

          使用訪問控制真的很簡單。第一個指示符是 only_from, 列出了我們可以接受從哪一個網(wǎng)絡(luò)或是主機(jī)的連接。這個規(guī)則可以被 no_access覆蓋。 你可以使用網(wǎng)絡(luò)號,如 10.0.0.0 或者 10或者是網(wǎng)絡(luò)名(包括 .my.com 或者 .my.com)。主機(jī)名或者主機(jī)的 IP地址也可以在這里使用指示符0.0.0.0 匹配所有的主機(jī)并監(jiān)聽所有的地址。通過使用 no_access一旦符合標(biāo)準(zhǔn)拒絕就會被解析。再說一遍,網(wǎng)絡(luò)和主機(jī)可以指定。

          服務(wù)配置

          讓我們看一些基本的應(yīng)用。我們先看第一個基本的服務(wù)echo,它是inetd 和xinetd固有的服務(wù)。

          service echo
          {
                  socket_type     = stream
                  protocol        = tcp
                  wait            = no
                  user            = root
                  type            = INTERNAL
                  id              = echo-stream
          }
          

          echo 以root權(quán)限運行, 是一個tcp 流并在內(nèi)部處理。echo-stream指示符將出現(xiàn)在日志中。如果沒有only_from或是 no_access在指示符中,對這個服務(wù)的訪問的配置將是不受限制的。

          現(xiàn)在,讓我們看一個正規(guī)的服務(wù),daytime:

          service daytime
          {
                  socket_type     = stream
                  protocol        = tcp
                  wait            = no
                  user            = nobody
                  server          = /usr/sbin/in.date
                  instances       = 1
                  nice            = 10
                  only_from       = 0.0.0.0
          }
          

          再說一次,任何人都可以連接, 不過我們指明它以nobody的身份運行來返回信息。和前一個例子相比,這個并沒有額外的什么。現(xiàn)在我們看另一個服務(wù) secure shell version 1。下面的設(shè)置可以防止sshd所帶來的資源耗盡問題。

          service ssh1
          {
                  socket_type     = stream
                  protocol        = tcp
                  instances       = 10
                  nice            = 10
                  wait            = no
                  user            = root
                  server          = /usr/local/sbin/sshd1
                  server_args     = -i
                  log_on_failure  += USERID
                  only_from       = 192.168.0.0
                  no_access       = 192.168.54.0 
                  no_access       += 192.168.33.0
          }
          

          在這里,我們建立了前面我們所作的。當(dāng)作為超級用戶inetd或者 xinetd重新調(diào)用sshd 需要用 -i 參數(shù), 所以我們把它放在了 server_args 指示符后。注意:把這個標(biāo)記添加到server標(biāo)識符出會導(dǎo)致失敗。在任何時候只有十個人可以同時使用,在這個服務(wù)器上這不是問題,這個例子我們從日志得到。另外作為默認(rèn)信息,如果不能連接的話,連接方的用戶 ID在RFC 1413中描述。最后,我們列出了兩個網(wǎng)絡(luò)不能訪問這個服務(wù)。

          日志和 xinetd

          日志中有幾個值可以用于得到你的服務(wù)器的信息

          表2 不同的日志指示值
          成功/失敗 描述
          PID success 當(dāng)一個連接成功時登記產(chǎn)生的進(jìn)程的pid
          HOST both 登記遠(yuǎn)程主機(jī)地址
          USERID both 登記遠(yuǎn)程用戶的RFC 1413 ID
          EXIT success 登記產(chǎn)生的進(jìn)程的完成
          DURATION success 登記任務(wù)持續(xù)的時間
          ATTEMPT failure 登記連接失敗的原因
          RECORD failure 關(guān)于連接失敗的額外的信息

          這樣,可以添加一些標(biāo)準(zhǔn)的行指明日志,就像下面的樣子。對一個成功連接的服務(wù),我們通常想登記服務(wù)產(chǎn)生的進(jìn)程id,連接的主機(jī)和退出的時間:

          log_on_success = PID HOST EXIT
          

          這樣可以給出我們用來排錯的有用的信息和正常的服務(wù)器操做信息。針對失敗,我們可以記錄我們想要的:

          log_on_failure = HOST RECORD ATTEMPT
          

          我們記錄了連接的主機(jī)、拒絕連接的原因和關(guān)于連接中的主機(jī)的額外的信息(有的時候是那些試圖連接的用戶ID)。推薦你這樣做,可以對你的服務(wù)器有一個好的把握。

          還看上面,在我們的默認(rèn)段中,我們的日志寫在/var/adm/servicelog中。我們指定所有信息,成功和失敗的都要被xinetd記錄。我們的大多數(shù)信息看起來像這樣:

          00/9/13@16:05:07: START: pop3 pid=25679 from=192.168.152.133
          00/9/13@16:05:09: EXIT: pop3 status=0 pid=25679
          00/10/3@19:28:18: USERID: telnet OTHER :www
          

          使用這個信息,可以輕易對 xinetd 排錯和進(jìn)行和正常操作。也可以容易發(fā)現(xiàn)安全問題(如你試圖阻止的連接企圖),在日志中簡單的用 grep 作 ''FAIL'' 過濾,這些項顯示如下:

          00/10/4@17:04:58: FAIL: telnet address from=216.237.57.154
          00/10/8@22:25:09: FAIL: pop2 address from=202.112.14.184
          

          真正的安全問題需要另外的文章,但是,這足以說明,既然地址可以偽造,不要把地址報告看作固定的信息。xinetd.log文件(包含了從 xinetd得到的信息)在連接出錯的時候作為排錯信息很有用。

          00/10/25@21:10:48 xinetd[50]: ERROR: service echo-stream,
          accept:
          Connection reset by peer
          

          重配置 xinetd

          在xinetd.conf運行的時候,你可以編輯 xinetd.conf 文件。要重新配置,發(fā)送一個信號SIGUSR1 給 xinetd 進(jìn)程:

          # ps -ax | grep xinetd
          50 ? S 5:47 /usr/sbin/xinetd -filelog /var/adm/xinetd.log -f /etc/xinetd.conf
          # kill -SIGUSR1 50
          

          察看日志文件的尾部(用tail命令)確保你的配置和改動已經(jīng)生效。如果你是個遠(yuǎn)程用戶的話要確保你退出后還可以重新登陸進(jìn)來。注意使用-HUP對xinetd重新配置,會實際導(dǎo)致 xinetd 停止操作。從設(shè)計的角度看,這可以阻止黑客重新配置你的xinetd并且在無需理解文檔的情況下就可以重新載入它。

          何時使用xinetd

          以我個人而言,對所有的服務(wù)我都使xinetd;唯一一個對性能有影響的服務(wù)是我的Apache web 守護(hù)進(jìn)程。太多的進(jìn)程不得不啟動,對它來說這太快了從而時間效率是個問題。DNS 服務(wù)也不應(yīng)該用 xinetd,性能消耗太大。

          對sendmail 服務(wù)我也使用了xinetd。這樣對于允許連接的客戶,我能夠進(jìn)行完美的控制。針對 sendmail我的設(shè)置如下:

          service smtp
          {
                  socket_type   = stream
                  protocol      = tcp
                  wait          = no
                  user          = root
                  server        = /usr/sbin/sendmail
                  server_args   = -bs
                  instances     = 20
                  nice          = 10
                  only_from     += 0.0.0.0
                  no_access     += 129.22.122.84 204.0.224.254
          }
          

          即使是在一個高流量的郵件服務(wù)器上,對性能的影響也是可以忽略不計的。我還把 sshd 載入到 xinetd 以便阻止對它的進(jìn)程表攻擊。

          結(jié)論

          希望這篇文章對你配置或是根據(jù)需要調(diào)整inetd能有幫助。正如你所看到的,它提供的特性要比inetd大得多,甚至包含了tcp_wrappers。Solar Designer (http://www.openwall.com/) 提供一個針對稍舊一點的xinetd的版本的(2.2.1版本)的補(bǔ)丁,允許基于IP的實例控制,這有助于阻止簡單的進(jìn)程表攻擊。注意,不管怎樣,簡單的偽造可以繞過它。我不知道是否這個包對以后的 xinetd是否也適用。

          附:xinetd 代表 Extended Internet Services Daemon 下面附上一個xinetd.conf手冊頁上的參考設(shè)置:

          	#
          	# Sample configuration file for xinetd
          	#
          
          	defaults
          	{
          	     log_type		 = FILE /var/log/servicelog
          	     log_on_success	 = PID
          	     log_on_failure	 = HOST RECORD
          	     only_from		 = 128.138.193.0 128.138.204.0
          	     only_from		 = 128.138.252.1
          	     instances		 = 10
          	     disabled		 = rstatd
              }
          
          	#
              # Note 1: the protocol attribute is not required
              # Note 2: the instances attribute overrides the default
              #
               
          	service login
              {
          	    socket_type	 = stream
          	    protocol		 = tcp
          	    wait		 = no
          	    user		 = root
          	    server		 = /usr/etc/in.rlogind
          	    instances		 = UNLIMITED
              }
          
              #
              # Note 1: the instances attribute overrides the default
              # Note 2: the log_on_success flags are augmented
              #
          
              service shell
              {
          	     socket_type	 = stream
          	     wait		 = no
          	     user		 = root
          	     instances		 = UNLIMITED
          	     server		 = /usr/etc/in.rshd
          	     log_on_success	 += HOST RECORD
              }
          
              service ftp
              {
          	     socket_type	 = stream
          	     wait		 = no
          	     nice		 = 10
          	     user		 = root
          	     server		 = /usr/etc/in.ftpd
          	     server_args	 = -l
          	     instances		 = 4
          	     log_on_success	 += DURATION HOST USERID
          	     access_times	 = 2:00-9:00 12:00-24:00
              }
          
              # Limit telnet sessions to 8 Mbytes of memory and a total
              # 20 CPU seconds for child processes.
          
              service telnet
              {
          	     socket_type	 = stream
          	     wait		 = no
          	     nice		 = 10
          	     user		 = root
          	     server		 = /usr/etc/in.telnetd
          	     rlimit_as		 = 8M
          	     rlimit_cpu		 = 20
              }
          
              #
              # This entry and the next one specify internal services. Since
              # this is the same service using a different socket type, the
              # id attribute is used to uniquely identify each entry
              #
              
          	service echo
              {
          	     id			 = echo-stream
          	     type		 = INTERNAL
          	     socket_type	 = stream
          	     user		 = root
          	     wait		 = no
              }
              
              service echo
              {
          	     id			 = echo-dgram
          	     type		 = INTERNAL
          	     socket_type	 = dgram
          	     user		 = root
          	     wait		 = no
              }
          
              service servers
          	{
          	     type		 = INTERNAL UNLISTED
          	     protocol		 = tcp
          	     port		 = 9099
          	     socket_type	 = stream
          	     wait		 = no
              }
          
              #
              # Sample RPC service
              #
              service rstatd
              {
          	     type		 = RPC
          	     socket_type	 = dgram
          	     protocol		 = udp
          	     server		 = /usr/etc/rpc.rstatd
          	     wait		 = yes
          	     user		 = root
          	     rpc_version	 = 2-4
          	     env		 = LD_LIBRARY_PATH=/etc/securelib
              }
          
              #
              # Sample unlisted service
              #
              
          	service unlisted
              {
          	     type		 = UNLISTED
          	     socket_type	 = stream
          	     protocol		 = tcp
          	     wait		 = no
          	     server		 = /home/user/some_server
          	     port		 = 20020
              }
          

          翻譯后記:一日在網(wǎng)上看到自己在2年前的這個翻譯文檔,細(xì)讀一下,發(fā)現(xiàn)謬誤不少,遂找到原文,更正了一些不當(dāng)之處。翻譯不當(dāng)之處肯定還是存在的,歡迎指出!


          參考信息(譯者提供)


          xinetd - http://www.xinetd.org/

          Frederic Raynal的文章 - http://www.linuxfocus.org/English/November2000/article175.shtml

          xinetd HOWTO - http://www.dbanotes/net/Books/xinted.pdf




          本文譯者

          Fenng,某美資公司DBA,業(yè)余時間混跡于各數(shù)據(jù)庫相關(guān)的技術(shù)論壇且樂此不疲。目前關(guān)注如何利用ORACLE數(shù)據(jù)庫有效地構(gòu)建企業(yè)應(yīng)用。對Oracle tuning、troubleshooting有一點研究。
          個人技術(shù)站點:http://www.dbanotes.net/ 。可以通過電子郵件 dbanotes@gmail.com 聯(lián)系到他。
          posted on 2007-03-04 01:45 思考 閱讀(710) 評論(0)  編輯  收藏 所屬分類: Linux技術(shù)
          主站蜘蛛池模板: 柳州市| 游戏| 德清县| 龙州县| 正安县| 平昌县| 西贡区| 万年县| 桂阳县| 游戏| 四会市| 龙川县| 城固县| 满洲里市| 安多县| 石棉县| 乐陵市| 高密市| 交口县| 阿坝| 永胜县| 齐齐哈尔市| 万宁市| 运城市| 天柱县| 常熟市| 荥经县| 白城市| 吉首市| 故城县| 衢州市| 贵定县| 余姚市| 察隅县| 石景山区| 东丰县| 杭州市| 上杭县| 连江县| 嵊泗县| 盱眙县|