3. 步骤 1:我们真正需要哪些服务?

在本节中,我们将了解在我们新安装的系统上运行哪些服务,确定我们真正需要的服务,并去除其余的服务。如果您不熟悉服务器和 TCP 连接的工作原理,您可能需要先阅读附录中关于服务器和端口的部分。如果您不熟悉 netstat 实用程序,您可能需要事先阅读其概述。附录中还有关于端口和相应服务的部分。您可能也想浏览一下。

我们的目标是尽可能关闭更多服务。如果我们能全部关闭,或者至少关闭与外部连接的服务,那就更好了。我们将使用以下一些经验法则来指导我们

3.1. 系统审计

那么,到底有哪些服务在我们的系统上运行呢?让我们不要想当然地认为哪些服务“应该”运行,或者我们“认为”哪些服务正在运行。

安装和启动哪些服务将因红帽的版本以及选择的安装选项而异。早期的版本非常容易启动许多服务,然后让用户弄清楚哪些是需要的,哪些是不需要的。最近的版本则谨慎得多。但这使得提供一份现成的可能服务列表变得不可能。不用担心,因为我们无论如何都不应该相信应该运行什么。我们需要做的是自己列出所有正在运行的服务。

现在打开一个 xterm,并 su 到 root 用户。您需要加宽窗口,以便行不会换行。使用此命令netstat -tap |grep LISTEN。这将为我们提供一个当前正在运行的所有服务器的列表,由关键字指示LISTEN,以及启动每个特定服务的“PID”“程序名称”

# netstat -tap |grep LISTEN
  *:exec               *:*        LISTEN    988/inetd          
  *:login              *:*        LISTEN    988/inetd          
  *:shell              *:*        LISTEN    988/inetd          
  *:printer            *:*        LISTEN    988/inetd          
  *:time               *:*        LISTEN    988/inetd          
  *:x11                *:*        LISTEN    1462/X              
  *:http               *:*        LISTEN    1078/httpd          
  bigcat:domain        *:*        LISTEN    956/named           
  bigcat:domain        *:*        LISTEN    956/named           
  *:ssh                *:*        LISTEN    972/sshd            
  *:auth               *:*        LISTEN    388/in.identd
  *:telnet             *:*        LISTEN    988/inetd          
  *:finger             *:*        LISTEN    988/inetd
  *:sunrpc             *:*        LISTEN    1290/portmap
  *:ftp                *:*        LISTEN    988/inetd
  *:smtp               *:*        LISTEN    1738/sendmail: accepting connections 
  *:1694               *:*        LISTEN    1319/rpc.mountd
  *:netbios-ssn        *:*        LISTEN    422/smbd

 

红帽 7.x 和 Mandrake 8.x 及更高版本的用户将有xinetd代替inetd。请注意,为了便于阅读,上面裁剪了前三列。如果您的列表像示例一样长,那么您还有一些工作要做!您不太可能真的需要运行如此多的服务器。

请注意,上面的示例只是众多可能的系统配置之一。您的系统可能看起来非常不同。

您不明白这一切都在告诉您什么?希望您已经阅读了附录中的 netstat 教程,并了解其工作原理。理解上面示例中每个服务器的具体含义及其作用超出了本文档的范围。如果该服务对您很重要,您将必须查看系统的文档(例如,安装指南、man 手册等)。例如,“exec”“login”“shell” 听起来重要吗?是的,但这些并不是它们听起来的样子。它们实际上是 rexecrloginrsh,即 “r”(表示远程)命令。这些是过时的、不必要的,实际上,如果暴露于互联网,它们非常危险。

让我们对什么是必要的和不必要的,以及因此 bigcat 上保留什么和去除什么做一些快速假设。由于我们正在 bigcat 上运行桌面,X11 当然需要保留。如果 bigcat 是某种专用服务器,那么 X11 将是不必要的。如果有打印机物理连接,则打印机 (lp) 守护程序应保留。否则,它将被去除。打印服务器可能听起来无害,但由于它们可以保持端口打开,因此也是潜在的目标。如果我们计划其他主机登录到 bigcat,则 sshd(安全 Shell 守护程序)将是必要的。如果我们的局域网中有 Microsoft 主机,我们可能需要 Samba,因此 smbd 应保留。否则,它是完全不必要的。此示例中的所有其他内容都是可选的,对于正常运行的系统来说不是必需的,并且可能应该去除。看到任何您不认识的东西吗?不确定?那就去除它!

总结一下:由于 bigcat 是一台连接了打印机的桌面电脑,我们将需要 “x11”“printer”。bigcat 位于具有 MS 主机的局域网上,并与它们共享文件和打印,因此需要 “netbios-ssn” (smbd)。我们还需要 “ssh”,以便我们可以从其他机器登录。对于这种情况,其他一切都是不必要的。

对此感到紧张吗?如果您愿意,您可以记录下您所做的任何更改,或者使用此命令保存您从 netstat 获取的服务器列表netstat -tap |grep LISTEN > ~/services.lst。这会将它保存在您的主目录中,文件名为 “services.lst”,以供将来参考。

这并不是说我们决定保留的服务本质上是安全的。只是我们可能需要这些服务。因此,我们将不得不通过防火墙或其他方式(如下所述)来处理这些服务。

值得注意的是,上面示例中的 telnetftp 守护程序是服务器,也称为 “监听器”。这些接受来自您的传入连接。您不需要,也不想要这些,仅仅为了使用 ftptelnet 客户端。例如,您只需使用 ftp 客户端即可从 FTP 站点下载文件。在您这边运行 ftp 服务器根本不是必需的,并且具有严重的安全隐患。

在个别情况下,可能需要对上述结论进行例外处理。请参阅下文

3.2. 危险区域 (或 r00t m3 pl34s3)

以下是不应通过互联网运行的服务列表。要么禁用这些服务(见下文),卸载,或者如果您真的需要在本地运行这些服务,请确保它们是当前、已修补的版本,并且它们有效地受到了防火墙的保护。如果您现在没有防火墙,请在防火墙启动并验证正常工作之前将其关闭。这些服务本质上可能是不安全的,因此是主要的黑客目标。

这不一定是最终的列表。只是一些常见的服务,有时会在默认的红帽安装中启动。反之,这并不意味着其他服务本质上是安全的。

3.3. 停止服务

下一步是找到我们杀戮列表上的每个服务器的启动位置。如果从 netstat 输出中不明显,请使用 psfindgreplocate 从最后一列中的 “程序名称”“PID” 信息中查找更多信息。附录的 netstat 教程中的进程所有者部分中有示例。如果服务名称或端口号对您来说不熟悉,您可能会在您的/etc/services文件中找到一个非常简短的解释。

chkconfig 是一个非常有用的命令,用于控制通过 init 脚本启动的服务(见下例)。此外,在使用 xinetd 的地方,它也可以控制这些服务。chkconfig 可以告诉我们系统配置为运行哪些服务,但不一定包括所有实际正在运行的服务。或者可能通过其他方式启动的服务,例如从rc.local启动的服务。它是一个配置工具,而不仅仅是一个实时系统审计工具。

怀疑我们会破坏您的系统,并且这些部件无法恢复原样?如果是这样,请采取以下方法:关闭上面 “危险区域” 中列出的所有服务,并运行您的系统一段时间。没问题?尝试停止我们发现是 “不必要” 的服务之一。然后,运行系统一段时间。不断重复此过程,直到达到最低限度。如果这可行,那么将更改设为永久性(见下文)。

最终目标不仅是现在停止服务,还要确保它永久停止!因此,无论您在此处采取什么步骤,请务必在下次重启后检查。

有各种各样的地方和方法来启动系统服务。让我们看看最常见的启动方式,这可能也是您的系统的工作方式。系统服务通常由 “init” 脚本启动,或者由大多数发行版上的 inetd(或其替代品 xinetd)启动。

3.3.1. 停止 Init 服务

Init 服务通常在启动过程中或运行级别更改期间自动启动。有一种命名方案,它使用符号链接来确定在任何给定的运行级别启动或停止哪些服务。脚本本身应该在/etc/init.d/(或可能是/etc/rc.d/init.d/对于旧版本的红帽)。

您可以获取这些脚本的列表

  # ls -l /etc/rc.d/init.d/ | less 

 

要立即停止正在运行的服务,以 root 用户身份

 # /etc/init.d/<$SERVICE_NAME> stop

 

其中 “$SERVICE_NAME” 是 init 脚本的名称,通常(但不总是)与服务名称本身相同。旧版本的红帽可能使用路径/etc/rc.d/init.d/代替。

这仅立即停止此特定服务。它将在下次重启或运行级别更改时再次重启,除非采取其他步骤。因此,对于 init 类型服务来说,这实际上是一个两步过程。

chkconfig 可用于查看在每个运行级别启动哪些服务,并关闭任何不需要的服务。要查看所有在其控制下的服务,请在 xterm 中键入此命令

 
 # chkconfig --list | less
 
 

要仅查看 “on” 的服务

 
 # chkconfig --list | grep "\bon\b" | less
 
 

第一列是服务名称,其余列是各种运行级别。我们通常只需要担心运行级别 3(启动到文本控制台登录)和 5(直接启动到 X11 登录)。xinetd 服务将没有列,因为这方面将由 xinetd 本身控制。

关闭服务的命令示例 “off”

 
 # chkconfig portmapper off
 # chkconfig nfs off
 # chkconfig telnet off
 # chkconfig rlogin off
 
 

请注意,最后两个是 xinetd 服务。一个非常简单和漂亮的工具!红帽还包括 ntsysvtksysv (GUI),用于运行级别和服务配置。有关其他命令行选项,请参阅 man 手册。

这里的另一个选项是卸载软件包,如果您知道您不需要它。这是一个非常可靠的永久性修复方法。这也减轻了保持所有已安装软件包更新和最新的潜在问题(步骤 2)。如果您改变主意,RPM 可以非常轻松地重新安装软件包。

使用 RPM 卸载软件包

 # rpm -ev telnet-server  rsh  rsh-server

 

上面的命令将卸载 “telnet 服务器” 软件包(但不包括 telnet 客户端!)、“rsh” 客户端和 “rsh 服务器” 软件包,在一个命令中完成。红帽还包括 gnorpm,一个 GUI RPM 管理实用程序,也可以执行此操作。

3.3.2. Inetd

Inetd 被称为 “超级守护进程”,因为它用于派生子守护进程。inetd 本身通常通过 init 脚本启动,并将根据其配置文件中启用的服务来 “监听” 各个端口,/etc/inetd.conf。此处列出的任何服务都将受 inetd 的控制。同样,在 netstat 输出中列出 “inetd” 作为 “程序名称” 下最后一列的任何监听服务器,都将由 inetd 启动。您将必须调整 inetd 配置以停止这些服务。xinetd 是增强型的 inetd 替代品,并且配置不同(见下节)。

下面是典型的inetd.conf的部分代码片段。以 “#” 开头的任何服务行都被 “注释掉”,因此 inetd 会忽略它们,因此会被禁用。

#
# inetd.conf  This file describes the services that will be available
#    through the INETD TCP/IP super server.  To re-configure
#    the running INETD process, edit this file, then send the
#    INETD process a SIGHUP signal.
#
# Version:  @(#)/etc/inetd.conf  3.10  05/27/93
#
# Authors:  Original taken from BSD UNIX 4.3/TAHOE.
#    Fred N. van Kempen, <waltje@uwalt.nl.mugnet.org>
#
# Modified for Debian Linux by Ian A. Murdock <imurdock@shell.portal.com>
#
# Echo, discard, daytime, and chargen are used primarily for testing.
#
# To re-read this file after changes, just do a 'killall -HUP inetd'
#
#echo  stream  tcp  nowait  root  internal
#echo  dgram  udp   wait    root  internal
#discard  stream  tcp  nowait  root  internal
#discard  dgram  udp   wait    root  internal
#daytime  stream tcp   nowait  root  internal
#daytime  dgram  udp   wait    root  internal
#chargen  stream tcp   nowait  root  internal
#chargen  dgram  udp   wait    root  internal
time  stream    tcp   nowait  root  internal
#
# These are standard services.
#
#ftp     stream  tcp   nowait  root  /usr/sbin/tcpd  in.ftpd -l -a
#telnet  stream  tcp   nowait  root  /usr/sbin/tcpd  in.telnetd
#
# Shell, login, exec, comsat and talk are BSD protocols.
#
#shell  stream  tcp  nowait  root  /usr/sbin/tcpd  in.rshd
#login  stream  tcp  nowait  root  /usr/sbin/tcpd  in.rlogind
#exec   stream  tcp  nowait  root  /usr/sbin/tcpd  in.rexecd
#comsat dgram   udp  wait    root  /usr/sbin/tcpd  in.comsat
#talk   dgram   udp  wait    root  /usr/sbin/tcpd  in.talkd
#ntalk  dgram   udp  wait    root  /usr/sbin/tcpd  in.ntalkd
#dtalk  stream  tcp  wait    nobody /usr/sbin/tcpd in.dtalkd
#
# Pop and imap mail services et al
#
#pop-2   stream  tcp     nowait  root    /usr/sbin/tcpd  ipop2d
pop-3    stream  tcp     nowait  root    /usr/sbin/tcpd  ipop3d
#imap    stream  tcp     nowait  root    /usr/sbin/tcpd  imapd
#
# The Internet UUCP service.
#
#uucp  stream tcp nowait uucp /usr/sbin/tcpd  /usr/lib/uucp/uucico -l
#

<snip>

 

上面的示例启用了两个服务:timepop3。要禁用这些服务,我们只需要使用文本编辑器打开文件,用 “#” 注释掉这两个服务,保存文件,然后重启 inetd(以 root 用户身份)

 
  # /etc/rc.d/init.d/inetd restart  

 

检查您的日志是否有错误,并再次运行 netstat 以验证一切顺利。

使用 grep 获取相同信息的更快方法

 $ grep  -v '^#' /etc/inetd.conf
 time     stream  tcp     nowait  root  internal
 pop-3    stream  tcp     nowait  root  /usr/sbin/tcpd  ipop3d

 

再说一遍,您在那里看到任何您不知道是什么的东西吗?那么很可能您没有使用它,应该禁用它。

与 init 服务配置不同,这是一个持久的更改,因此只需要一步即可。

让我们揭露一个被抛出的神话:您不应该通过注释掉或删除

中的条目来禁用服务。/etc/services。这在某些情况下可能会产生预期的效果,但这不是正确的方法,并且可能会干扰其他系统实用程序的正常运行。

3.3.3. Xinetd

xinetdinetd 的替代品,具有增强功能。红帽 7.0 及更高版本包含 xinetd。它本质上与 inetd 的用途相同,但配置不同。配置可以在文件/etc/xinetd.conf中,或目录/etc/xinetd.d/中的各个文件中。各个服务的配置将在/etc/xinetd.d/*下的各个文件中。关闭 xinetd 服务可以通过删除相应的配置部分或文件来完成。或者使用您的文本编辑器并简单地设置disable = yes对于适当的服务。或者使用 chkconfig。然后,需要重启 xinetd。请参阅man xinetdman xinetd.conf以获取语法和配置选项。一个 xinetd 配置示例

 # default: on
 # description: The wu-ftpd FTP server serves FTP connections. It uses \
 #       normal, unencrypted usernames and passwords for authentication.
 service ftp
 {
        disable                 = no
        socket_type             = stream
        wait                    = no
        user                    = root
        server                  = /usr/sbin/in.ftpd
        server_args             = -l -a
        log_on_success          += DURATION USERID
        log_on_failure          += USERID
        nice                    = 10
 }

 

您可以快速获取已启用服务的列表

 $ grep disable /etc/xinetd.d/* |grep no
 /etc/xinetd.d/finger:   disable = no
 /etc/xinetd.d/rexec:    disable = no
 /etc/xinetd.d/rlogin:   disable = no
 /etc/xinetd.d/rsh:      disable = no
 /etc/xinetd.d/telnet:   disable = no
 /etc/xinetd.d/wu-ftpd:  disable = no

 

此时,上面的输出应该引起一些警惕。在绝大多数系统中,以上所有服务都可以禁用,而不会产生任何不利影响。不确定?尝试在没有该服务的情况下运行。禁用不必要的服务后,然后重启 xinetd

 
  # /etc/rc.d/init.d/xinetd restart  

 

3.3.4. 当所有其他方法都失败时

好的,如果您找不到停止服务的 “正确” 方法,或者某个服务正在启动,但您找不到它的启动方式或位置,您可以 “kill” 该进程。要做到这一点,您需要知道 PID(进程 ID)。这可以通过 pstopfuser 或其他系统实用程序找到。对于 topps,这将是第一列中的数字。请参阅附录中的端口和进程所有者部分以获取示例。

示例(以 root 用户身份)

 # kill 1163

 

然后再次运行 topps 以验证该进程是否已消失。如果不是,则

 # kill -KILL 1163

 

请注意其中的第二个 “KILL”。这必须由进程的所有者用户或 root 用户完成。现在去查找这个进程是如何启动的 ;-)

/proc文件系统也可以用于查找有关每个进程的更多信息。有了 PID,我们可以找到一个神秘进程的路径

 $ /bin/ps ax|grep tcpgate
  921 ?   S    0:00        tcpgate

 

 # ls -l /proc/921/exe
 lrwxrwxrwx 1 root  root  0 July 21 12:11 /proc/921/exe -> /usr/local/bin/tcpgate

 

3.4. 例外情况

上面我们使用了关闭所有不必要服务的标准。有时这不是很明显。有时,对于一个人的配置可能需要的东西,对于另一个人来说可能不一样。让我们看看属于这一类的一些常见服务。

再次强调,我们的经验法则是,如果我们不需要它,我们就不会运行它。就这么简单。如果我们确实需要其中任何一项,那么它们是通过防火墙规则或其他机制(见下文)实施某种限制性策略的主要候选者。

3.5. 步骤 1 的总结和结论

在本节中,我们学习了如何识别系统上正在运行哪些服务,并获得了一些关于如何确定哪些服务可能是必要的提示。然后我们学习了如何找到服务在哪里启动,以及如何停止它们。如果这还没有理解,现在是重新阅读上述内容的好时机。

希望您已经采取了上述步骤。务必再次使用 netstat 测试您的结果,以验证是否已达到预期的目的,并且只有真正需要的服务正在运行。

在下次重启后、每次升级软件包时(以确保新的配置不会偷偷溜进来)以及每次系统升级或新安装后,也明智地这样做。