安全攻略:网络站点主机安全档案
来源:硅谷动力 更新时间:2012-04-13

 
 
    本文档与站点服务器安全有关,由本人根据实际工作经验编写而成;这里只是一个初稿,以后有时间我会更新它。

  站点服务器通常指托管在IDC机房的服务器,如果你有服务器托管在IDC那里,就不得不对它们的安全予以关注。如果你是网络程序员或系统管理员,本文或许会对你有所帮助,如果你是专业安全管理员,那么看一下本文也无妨。

  站点安全应该包括几部分:物理安全、网络安全、系统安全以及安全管理,下面从这几方面予以阐述。

  一. 物理安全

  服务器运行的物理安全环境是很重要的,很多人忽略了这点。物理环境主要是指服务器托管机房的设施状况,包括通风系统、电源系统、防雷防火系统以及机房的温度、湿度条件等。这些因素会影响到服务器的寿命和所有数据的安全。我不想在这里讨论这些因素,因为在选择IDC时你自己会作出决策。

  在这里着重强调的是,有些机房提供专门的机柜存放服务器,而有些机房只提供机架。所谓机柜,就是类似于家里的橱柜那样的铁柜子,前后有门,里面有放服务器的拖架和电源、风扇等,服务器放进去后即把门锁上,只有机房的管理人员才有钥匙打开。而机架就是一个个铁架子,开放式的,服务器上架时只要把它插到拖架里去即可。这两种环境对服务器的物理安全来说有着很大差别,显而易见,放在机柜里的服务器要安全得多。

  如果你的服务器放在开放式机架上,那就意味着,任何人都可以接触到这些服务器。别人如果能轻松接触到你的硬件,还有什么安全性可言?以下是几个不安全的事例:

  很多Windows服务器采用终端服务进行管理,在一个机架式的机房里,你可以随便把显示器接在哪台服务器上。如果你碰巧遇到某台机器的管理员或使用者正通过终端使用这台机器,那么他的操作你可以一览无余。甚至,你可以把键盘接上去,把他kill off,然后完全控制这台机器。当然,这种事情比较少见,但不意味着不可发生。

  另外,很多Unix系统的管理员在离开机房时,没有把root或其他帐号的shell从键盘退出,这样你只要把键盘和显示器接上去,就完全可以获取这个shell的权限。这可比远程攻击获取系统权限容易得太多。我有次在机房时想要一个unix shell临时使用一下,于是我把显示器在旁边机架的几台服务器上接了一下,很快就发现一个没有退出的root shell,我把键盘接上去,做完我自己的事后,帮他退出了这个shell。如果我是一个不安好心的人,我完全可以在他的服务器里不带任何痕迹的安装一个木马(RootKit)。

  某天我看到一个公司的维护人员在机房调试专线时,怀疑是协议转换仪有问题,于是他毫不犹豫的把旁边一个机架上的协议转换仪拔下来,接到他自己的专线上用于调试。被破坏的服务器数据传输会中断几分钟,这对某些公司可能是致命的,而他们的服务器管理人员可能到死也查不出原因!

  还有,用一张Linux光盘引导Linux系统,你可以毫无障碍的重新获取主机的root权限;你可以无意中碰动别人的电源,等等,不在这里赘述。所有这些是要说明一点,放在开放机架上的服务器是不安全的。如果你的服务器硬件可以让其他人轻易接触,那么不出事是你的幸运,出事了你也找不到原因或找不到责任人。

  而放在密封式机柜里的服务器会安全很多,一般情况下,你的所有服务器放在一起(同一个机柜或者几个机柜)是明智之举,机柜里不要有其他公司的服务器。如果你的服务器只有有限的几台,那么放在机柜里也会安全很多。因为不是任何人都可以打开机柜接触到你的硬件,就算同一个机柜的其他公司的服务器的维护人员有这个机会,但风险也要小得多。而且,就算出事了,你也可以追查到责任人。

  有一次我们的服务器因为电源断掉,而中断几个小时,我们根据系统日志很快判断出服务器的down机情况,在追查责任时,我首先想到是IDC机房的维护人员的责任,因为在我们那个机柜里没有其他公司的服务器,别人不会接触到那里面的电源。后来经查实,果然是该IDC的电工在弄电时不小心把我们的服务器电源断掉,他们向我们出具了道歉声明。而如果在一个开放式机架的机房里,碰到这样的情况你无从查起。

  如果你的服务器只能放在开放式机架的机房,那么你可以这样做:1)将电源用胶带绑定在插槽上,这样避免别人无意中碰动你的电源;2)安装完系统后,重启服务器,在重启的过程中把键盘和鼠标拔掉,这样在系统启动后,普通的键盘和鼠标接上去以后不会起作用(USB鼠标键盘除外)3)跟机房值班人员搞好关系,不要得罪机房里其他公司的维护人员。这样做后,你的服务器至少会安全一些。

二. 网络安全

  网络安全是指你机房的服务器要有合理的安全拓扑结构。安全的网络环境会让你的系统管理任务轻松很多,否则你会时刻提心吊胆。例如,如果你的NFS服务器直接面对互联网,那么你的麻烦就来了。因此,在服务器的前面,至少要有网络屏蔽设施,或称为防火墙。

  从头部署新的防火墙策略是一件复杂的事情,你要综合考虑许多方面。一般来说,防火墙有两种工作模式,称为路由模式和透明模式,在路由模式下,防火墙就象一个路由器,能进行数据包的路由。不同的是,它能识别网络第四层协议(即传输层)的信息,因此它能基于TCP/UDP端口来进行过滤。在该模式下,防火墙本身要配备两个或多个网络地址,你的网络结构会被改变。在透明模式下,防火墙更象一个网桥,它不干涉网络结构,从拓扑中看来,它似乎是不存在的(因此称为透明)。但是,透明模式的防火墙同样具备数据包过滤的功能。透明模式的防火墙不具备IP地址。这两种模式的防火墙都提供网络访问控制功能,例如你可以在防火墙上设置,过滤掉来自因特网的对服务器的NFS端口的访问请求。

  在网络中使用哪种工作模式的防火墙取决于你的网络环境。一般来说,如果你的服务器使用真实IP地址(该地址一般是IDC分配给你的),会选择防火墙的透明模式。因为在该模式下,你的服务器看起来象直接面对互联网一样,所有对服务器的访问请求都直接到达服务器。当然,在数据包到达服务器之前会经过防火墙的检测,不符合规则的数据包会被丢弃掉(从服务器编程的角度看,它不会觉察到数据包实际已被处理过)。

  实际上为了安全起见,很多服务器都采用私有IP地址(例如172.16.0.0/16和192.168.0.0/24都属于私有IP地址),如果这些服务器不必对外提供服务,那么就最安全不过了,如果要对外提供服务,就有必要通过防火墙的NAT(网络地址转换)来满足来自因特网的访问要求。NAT是防火墙的一项功能,它实际上工作在路由模式下。大多数防火墙都会区分所谓的正向NAT和反向NAT,所谓正向NAT就是指从内网出去的数据包,在经过防火墙后,包头会被改写,源IP被改写成防火墙上绑定的IP地址(或地址池,肯定是公网真实IP),源端口也会有所改变,回来的数据包经过同样处理,这样就保证内网具有私有IP的主机能够与因特网进行通信。在反向NAT的实现中,会将服务器的公网IP绑定在出口处的防火墙上,服务器只会使用一个私有IP,防火墙会在它的公网IP和这个私有IP之间建立一个映射,当外网对这台服务器的请求到达防火墙时,防火墙会把它转发给该服务器。当然,在转发之前,会先匹配防火墙规则集,不符合规则的数据包将被丢弃。

  使用反向NAT,会大大提高服务器的安全性。因为任何用户的访问都不是直接面对服务器,而是先要经过防火墙才被转交。而且,服务器使用私有IP地址,这总比使用真实地址要安全。在抗拒绝服务攻击上,这种方式的成效更显然。但是,相对于透明模式的防火墙,采用反向NAT方式的防火墙会影响网络速度。如果你的站点访问流量超大,那么就不要使用该种方式。值得一提的是,CISCO的PIX在NAT的处理上性能异常卓越。

  另外一种情况是,服务器使用真实IP地址,防火墙配置成路由模式,不使用它的NAT功能。这种情况虽然可以实现,但会使你的网络结构变得很复杂,似乎也不会带来效益的提高。

  大多数IDC的机房不提供防火墙服务,你需要自己购买和配置使用防火墙。你完全可以按透明模式或NAT模式来配置,具体怎么配取决于你的实际情况。有些IDC公司会提供防火墙服务,作为他们吸引客户的一个手段。一般来说,他们的防火墙服务会收费。

  如果你的服务器在IDC提供的公共防火墙后面,那么就有必要仔细考虑你的内网结构了。如果IDC提供给你的防火墙使用透明模式,也即是你的服务器全部使用真实IP地址,在这种情况下,除非你的服务器数量足够多(象我们在北京有500多台),那么在你的逻辑网段里肯定还有其他公司的主机存在。这样,虽然有防火墙,你的系统管理任务也不会轻松多少,因为你要受到同一网段里其他公司主机的威胁。例如,你的服务器的IP地址段是211.139.130.0/24,你使用了其中的几个地址,那么在这个网段里还会有200多台其他公司的主机,它们与你的主机同处于一个防火墙之后,虽然防火墙可以屏蔽来自因特网的某些访问,然而,内部这些主机之间的相互访问却没有任何屏蔽措施。于是,其他公司不怀好意的人可以通过他们的主机来攻击你。或者,网络中一台主机被黑客入侵,则所有服务器都会面临严重威胁。在这样的网络中,你不要运行NFS、Sendmail、BIND这样的危险服务。

  这种问题的解决方法是自己购买防火墙,并配置使用透明模式,不要使用公用防火墙的透明模式。

  有的IDC公司会给你提供NAT方式的防火墙,你需要在服务器上设置私有IP地址,然后由防火墙来给服务器做地址转换。这种情况与上述情况存在同样的问题,那就是,在你的服务器所在的逻辑网段里还有其他公司的主机。例如在172.16.16.0/24这个网段可容纳254台主机,你的服务器使用了其中的几个IP,那么可能还有200多台其他公司的主机与你的服务器在同一个网段里。这样,虽然对外有防火墙保护,但无法防范来自内网的攻击。

  要解决这个问题,你不必自己购买防火墙。既然私有IP是可以任意分配的,那么你可以向IDC单独要一个网段,例如172.16.19.0/24网段,把你的服务器都放在这个网段里,其中不要有其他公司的主机。这样一来,你的内网也无懈可击了。

  实际上,如果你有一个大的UNIX主机的网络,那么没必要让每台主机都在防火墙上打开登陆端口。你可以特别设置一台或两台主机做为登陆入口,对其他主机的访问都必须使用入口主机作为跳板。这样做牺牲了使用的方便性,但带来更强的安全性。当然,前提是你必须管理好入口主机。有一种电子令牌卡适合这种应用,它是一张随身携带的卡,每隔一段时间(这个时间通常很小,几分钟或者几十秒)动态产生一个口令,你只有使用这个口令才能登陆主机,并且该口令很快就会失效。

  不仅是UNIX主机,对Windows主机的终端管理也可以采用这种跳板的方式。但Windows的终端比UNIX的shell要麻烦得多,如果你不愿牺牲太多的方便性,那么就不要这样做。

三. 系统安全

  系统安全是站点安全的主要部分。如果你的系统存在明显漏洞,那么再好的物理环境和网络环境也保不了你。一个很明显的问题是,如果你的WEB服务器存在安全漏洞,你在没有将其修补的情况下对外提供服务,那么不管你的防火墙有多坚固,也会很快被入侵。因此,系统管理员在保证系统功能稳定的同时,不得不花时间来研究系统的安全问题。

  我所接触的服务器主要有Windows2000 Server、Freebsd、Linux和Solaris。第一种是微软的产品,方便好用,但是,你必须要不断的patch它。Freebsd是一种优雅的操作系统,它简洁的内核和优异的性能让人感动。Linux和Freebsd一样,是免费的操作系统,它们都广泛使用GNU(一个伟大的组织)的实用工具集,Linux容易上手,但不如Freebsd简洁。Solaris是SUN的商用操作系统,关于SUN OS的文章在网上被贴得到处都是,但遗憾的是,它看起来并不快,而且,你也要经常对它打补丁。

  关于这几种操作系统的安全,每种都可以写一本书。我不会在这里对它们进行详细描述,只讲一些系统初始化安全配置。

  1. Windows2000 Server的初始安全配置

  Windows的服务器在运行时,都会打开一些端口,如135、139、445等。这些端口用于Windows本身的功能需要,冒失的关闭它们会影响到Windows的功能。然而,正是因为这些端口的存在,给Windows服务器带来诸多的安全风险。远程攻击者可以利用这些开放端口来广泛的收集目标主机信息,包括操作系统版本、域SID、域用户名、主机SID、主机用户名、帐号信息、网络共享信息、网络时间信息、Netbios名字、网络接口信息等,并可用来枚举帐号和口令。今年8月份和9月份,微软先后发布了两个基于135端口的RPC DCOM漏洞的安全公告,分别是MS03-026和MS03-039,该漏洞风险级别高,攻击者可以利用它来获取系统权限。而类似于这样的漏洞在微软的操作系统中经常存在。

  解决这类问题的通用方法是打补丁,微软有保持用户补丁更新的良好习惯,并且它的Windows2000 SP4安装后可通过Windows Update来自动升级系统补丁。另外,在防火墙上明确屏蔽来自因特网的对135-139和445、593端口的访问也是明智之举。

  Microsoft的SQL Server数据库服务也容易被攻击,今年3月份盛行的SQL蠕虫即使得多家公司损失惨重,因此,如果安装了微软的SQL Server,有必要做这些事:1)更新数据库补丁;2)更改数据库的默认服务端口(1433);3)在防火墙上屏蔽数据库服务端口;4)保证sa口令非空。

  另外,在Windows服务器上安装杀毒软件是绝对必须的,并且要经常更新病毒库,定期运行杀毒软件查杀病毒。

  不要运行不必要的服务,尤其是IIS,如果不需要它,就根本不要安装。IIS历来存在众多问题,有几点在配置时值得注意:1)操作系统补丁版本不得低于SP3;2)不要在默认路径运行WEB(默认是c:\inetpub\wwwroot);3)以下ISAPI应用程序扩展可被删掉:.ida .idq .idc .shtm .shtml .printer。

  2. Freebsd的初始安全配置

  Freebsd在设计之初就考虑了安全问题,在初次安装完成后,它基本只打开了22(SSH)和25(Sendmail)端口,然而,即使是Sendmail也应该把它关闭(因为历史上Sendmail存在诸多安全问题)。方式是编辑/etc/rc.conf文件,改动和增加如下四句:

  sendmail_enable="NO"

  sendmail_submit_enable="NO"

  sendmail_outbound_enable="NO"

  sendmail_msp_queue_enable="NO"

  这样就禁止了Sendmail的功能,除非你的服务器处于一个安全的内网(例如在防火墙之后并且网段中无其他公司主机),否则不要打开Sendmail。

  禁止网络日志:在/etc/rc.conf中保证有如下行:

  syslogd_flags="-ss"

  这样做禁止了来自远程主机的日志记录并关闭514端口,但仍允许记录本机日志。

  禁止NFS服务:在/etc/rc.conf中有如下几行:

  nfs_server_enable="NO"

  nfs_client_enable="NO"

  portmap_enable="NO"

  有些情况下很需要NFS服务,例如用户上传图片的目录通常需要共享出来供几台WEB服务器使用,就要用到NFS。同理,要打开NFS,必须保证你的服务器处于安全的内网,如果NFS服务器可以被其他人访问到,那么系统存在较大风险。

  保证/etc/inetd.conf文件中所有服务都被注销,跟其他系统不同,不要由inetd运行任何服务。将如下语句加进/etc/rc.conf:

  inetd_enable="NO"

  所有对/etc/rc.conf文件的修改执行完后都应重启系统。

  如果要运行Apache,请编辑httpd.conf文件,修改如下选项以增进安全或性能:

  1) Timeout 300--->Timeout 120

  2) MaxKeepAliveRequests 256

  3) ServerSignature on--->ServerSignature off

  4) Options Indexes FollowSymLinks 行把indexes删掉(目录的Options不要带index选项)

  5) 将Apache运行的用户和组改为nobody

  6) MaxClients 150——>MaxClients 1500

  (如果要使用Apache,内核一定要重新编译,否则通不过Apache的压力测试,关于如何配置和管理WEB服务器请见我的另一篇文章)

  如果要运行FTP服务,请安装proftpd,它比较安全。在任何服务器上,都不要打开匿名FTP。

 3. Linux的初始安全配置

  Linux安装完成后,默认会打开一些不必要端口,运行netstat –an  grep LISTEN命令看一下,会看到本机打开的所有端口。除了必须的网络端口如SSH、FTP和WEB,其他端口都关闭。如果你不熟悉这些端口对应什么程序,那么请参看/etc/services文件,里面有端口和服务的对应列表。

  在Redhat 9.0默认安装完成后,请进入/etc/rc2.d和/etc/rc3.d,将系统启动时打开的不必要服务都在这里注销掉。这些服务通常包括sendmail、NFS、rpc等,注销的方法是将S打头的相关服务文件重命名(注意不要命名为S或K 打头的其他文件)。

  例如将/etc/rc2.d/S80sendmail 改名为 X80sendmail

  将/etc/rc3.d/S13portmap S14nfslock S28autofs S80sendmail 改名为 X13portmap X14nfslock X28autofs X80sendmail

  RPC的安全问题历来很多,请注意一定不要打开111端口。

  改完后需要重启Linux服务器。

  如果你的Linux直接面对因特网,那么可以配置它的防火墙来实现访问控制。Linux2.4内核支持iptables,2.4以下支持ipchains,它们的语法差不多,都是很好的防火墙工具。例如,如果你只允许从因特网访问SSH和WWW服务,那么可将如下语句加进/etc/rc.d/rc.local文件:

  /sbin/iptables -F

  /sbin/iptables -A INPUT -p tcp -d 211.96.13.* --dport 80 -i eth0 -j ACCEPT

  /sbin/iptables -A INPUT -p tcp -d 211.96.13.* --dport 22 -i eth0 -j ACCEPT

  /sbin/iptables -A INPUT -i eth0 -j DROP

  说明:iptables –F刷新iptables规则表,接下来两条语句允许任何人访问211.96.13.*这个地址的WWW和SSH服务,最后一条DROP语句将不符合规则的其他访问过滤掉。

  这样系统在启动后即可自动运行防火墙规则。

  通常在Freebsd或Linux上会运行Mysql数据库服务,不要将数据库服务端口(3306)暴露在防火墙之外。如果运行Apache,同样要做如Freebsd的修改。

  4. Solaris的初始安全配置

  关于Solaris的安全配置网上有一篇非常好的文章,叫做《The Solaris Security FAQ》,照着做就可以了。

  1) 禁止root从网络直接登陆:修改/etc/default/login文件,确保CONSOLE=/dev/console被设置,该行只允许root从控制台登陆。将root用户加入/etc/ftpusers,保证root不可以远程使用ftp。

  2) 禁止rlogin和rsh访问:删除/etc/hosts.equiv和/.rhosts文件,从/etc/inetd.conf文件里注释掉所有以r打头的服务。

  3) 帐号控制:删除、锁定或注释掉不必要的系统帐号,包括sys/uucp/nuucp/listen等

  4) 改变/etc目录的访问权限:该目录下文件不应该对同组用户可写,执行:chmod –R g-w /etc (不推荐)

  5) 在solaris2.5 以上版本的系统中,创建/etc/notrouter文件来关闭solaris默认的路由转发。

  6) 禁止automounter:删除/etc/auto_*配置文件,删除/etc/init.d/autofs

  7) 禁止NFS服务:删除/etc/dfs/dfstab,重命名/etc/rc3.d/S15nfs.server,重命名/etc/rc2.d/S73nfs.client (不要再以S打头)

  8) 禁止rpc服务:重命名/etc/rc2.d/S71RPC

  9) 修改/etc/inetd.conf文件,注释掉大部分不必要服务,只保留telnet和ftp服务,然后重启inetd进程。

  10) 给系统打补丁:包括各版本Solaris通用补丁和单个补丁集合。

  11) 将如下三行加进/etc/init.d/inetinit文件:

  ndd -set /dev/ip ip_forward_directed_broadcasts 0

  ndd -set /dev/ip ip_forward_src_routed 0

  ndd -set /dev/ip ip_forwarding 0

  这样在系统启动后就关闭了IP转发和IP源路由。

  四. 服务器安全管理

  4.1 安全管理应做的事

  安全管理是站点安全中最重要的一环,离开了管理,安全将变得不切实际。以下也许是Windows系统安全管理员每天应做的事:

  1. 检查系统有无新增帐户,并了解其来源及用途;查看管理员组里有无新增帐户,该组的帐户除系统最初设置外,以后不应该增加帐户;

  2. 在命令行状态下,运行netstat –an命令查看当前连接及打开的端口,查找可疑连接及可疑的端口;

  3. 查看“任务管理器”,查找有无可疑的应用程序或后台进程在运行,并观察CPU及内存的使用状态;

  4. 运行注册表编辑器,查找有无可疑的程序被加到windows的启动项里,并查看有无新增的可疑服务;

  5. 使用 Windows事件查看器查看“系统日志”“安全日志”和“应用程序日志”,以发现有无可疑的事件或影响系统性能的事件;

  6. 检查共享目录,不应有对所有用户可写的目录存在;

  7. 如果运行Microsoft IIS,查看C:\WINNT\system32\LogFiles\下的WEB 服务器日志,以发现是否有试图攻击WEB的行为;

  8. 不定期运行杀毒软件查杀病毒;

  9. 经常浏览微软的网站,保持服务器的补丁同步更新,留意微软发布的安全公告。

  以下是Unix系统安全管理员应经常做的事:

  1. 以root运行last,查看用户在过去一段时间内所发生的事件;

  2. 查看/etc/passwd和/etc/shadow文件,以发现是否有新增用户,并追查用户来源及用途;保证这两个文件中的系统用户(如Daemon bin sys adm lp uucp nuucp listen noaccess、mysql、sshd、nobody等)没有自己的shell;检查有无帐户被提升到root权限(UID 0);

  3. 运行netstat –an  grep LISTEN查看有无可疑的打开的端口;

  4. 使用ps命令查看系统进程,保证只有必要的进程在运行;

  5. 检查被cron运行的程序,Solaris一般在/var/spool/cron目录里,Freebsd一般在/var/cron里,初始化的crontable除root外,其他用户不应拥有;仔细查看root的crontable;

  6. 使用vmstat和top查看系统资源占用状况,对高资源占用的系统进程要做谨慎处理;

  7. 查看系统日志,包括Solaris下的/var/adm/messages和Freebsd下的/var/log/messages,以发现有无可疑的事件发生;

  8. 查看系统安全日志,包括用户登陆尝试、验证失败、可疑的IP地址登陆等,在solaris下是/var/log/authlog,freebsd下是/var/log/auth.log;

  9. 运行chkrootkit,以检查系统是否被植入木马程序;

  10. 安装了Apache的主机,不定期查看Apache的访问日志和错误日志, 以发现是否有试图攻击WEB的行为。

  4.2 系统及服务的稳定性

  一些重要的服务器是片刻也不能停的,一旦发生服务器down机事故,而你又没有及时发现和恢复,那么你面对的将是铺天盖地的指责。系统安全管理的任务也许不是很重,但责任却并不轻。因此,你有必要时刻了解服务器的存活状况,一旦发生down机事件,你应在第一时间知道。

  有些好的IDC机房有服务器监控系统,一旦某台机器down掉,它会发出警报。然后机房的值班人员会电话通知你,这样你就能从容的处理事故。然而,并非所有的机房都有这样的措施,很多时候还得依靠自己的小心。

  在机房网络中,应该有一它网管机器,这台机器最好是Unix系统,因为你可以在上面编写脚本来监控网络,并通过sendmail发送邮件给自己。这台机器可以是一台服务器,象前面讲过的登陆入口服务器,就完全可以充当网管机;也可以是一台配置很低的普通PC,能运行Linux或Freebsd就可以了。有必要在上面运行sendmail,因为它要对外发送邮件。当然,sendmail有一些安全问题,因此在运行它之前,你必须确认服务器处于安全的网络:在防火墙之后,且同一网段中没有其他公司的服务器。否则,就不要运行它。当然,你也可以配置sendmail绑定在127.0.0.1端口,不接受网络请求(在Linux默认安装的sendmail不接受网络请求,Freebsd中可以在rc.conf文件中设置使sendmail绑定在127.0.0.1端口),这样的sendmail会安全很多。

  然后你可以写一个简单的脚本来监控网络主机生存状况。在Unix主机上,使用shell或perl都很容易编写脚本,但是,shell脚本用于系统管理更简单明了,除非你要进行复杂的数学计算或文本处理。如下这个shell脚本很简单,却很实用。