当前位置:Linux教程 - Linux - 深入分析Linux防火墙

深入分析Linux防火墙



           关于网络安全的研究分析中,防火墙(Firewall)是被经常强调的重点,它基本功能是过滤并可能阻挡本地网络或者网络的某个部分与Internet之间的数据传送(数据包)。数据包其实就是一段段的数据,其中同时包括了用来把它们发送到各自的目的地所必须的信息。你可以把数据包想象成一个邮包:数据包本身就是邮包中的数据,而信封上则是所有用来把这些信息发送到正确的机器和正确的程序中去的书信抬头,它同时还包含着回信地址等方面的信息。在其具体的过滤工作过程中,防火墙将接管在此之前从网络内部存取Internet和从Internet存取该内部网络的路由设置。

      我们的感觉是以前的防火墙专门用来过滤一些非法的数据包,要么为什么其中的一种类型称为包过滤型防火墙呢?发展到现在,它的功能是日益增多,不仅能够过滤数据包,还能够作网络地址转换,作代理等等。Linux内核2.4中防火墙实现NetFilter就是这样的。

      先来看看防火墙所处的位置,我的理解是要么它装在一台机器上作个人防火墙,要么装在一台机器上为一个局域网提供网关的功能,而后种情况则如下图所示:(http://www.yesky.com/20011119/cl011119001.gif
      这副图概括了装在网关上的NetFilter的框架结构图,从图中可以看到一个数据包可能经过的路径,其中用[]扩起来的东东,称为检查点,当数据包到达这个点时,就要停下来进行一些检查。这里检查点的名称使用的是iptables中名称,具体到NetFilter中可能就要改为那些所谓的钩子(Hook)函数了。

    NetFilter概括起来说,它有下面的三个基本功能:

      1、数据过滤(filter表)
      2、网络地址转换(nat表)
      3、数据包处理(mangle表)

      根据这三个功能,将上面的五个检查点按功能进行了分类。由于每个功能在NetFilter中对应一个表,而每个检查点又有若干个匹配规则,这些规则组成一个链,所以就有下面的说法:“NetFilter是表的容器,表是链的容器,链是规则的容器”

      一个链(chain)其实就是众多规则(rules)中的一个检查清单(checklist)。每一条链中可以有一条或数条规则,每一条规则都是这样定义的“如果数据包头符合这样的条件,就这样处理这个数据包”。当一个数据包到达一个链时,系统就会从第一条规则开始检查,看是否符合该规则所定义的条件: 如果满足,系统将根据该条规则所定义的方法处理该数据包;如果不满足则继续检查下一条规则。最后,如果该数据包不符合该链中任一条规则的话,系统就会根据该链预先定义的策略(policy)来处理该数据包。

      而一个iptables命令基本上包含如下五部分:希望工作在哪个表上、希望使用该表的哪个链、进行的操作(插入,添加,删除,修改)、对特定规则的目标动作和匹配数据包条件。

      基本的语法为:iptables -t table -Operation chain -j target match(es)(系统缺省的表为"filter")

      基本操作如下:

      -A 在链尾添加一条规则
      -I 插入规则
      -D 删除规则
      -R 替代一条规则
      -L 列出规则

      基本目标动作,适用于所有的链:

      ACCEPT 接收该数据包
      DROP 丢弃该数据包
      QUEUE 排队该数据包到用户空间
      RETURN 返回到前面调用的链
      foobar 用户自定义链
    基本匹配条件,适用于所有的链:

      -p 指定协议(tcp/icmp/udp/...)
      -s 源地址(ip address/masklen)
      -d 目的地址(ip address/masklen)
      -i 数据包输入接口
      -o 数据包输出接口

      匹配条件扩展:

      TCP-----匹配源端口,目的端口,及tcp标记的任意组合,tcp选项等。
      UPD-----匹配源端口和目的端口
      ICMP----匹配ICMP类型
      MAC-----匹配接收到的数据的mac地址
      MARK----匹配nfmark
      OWNE----(仅仅应用于本地产生的数据包)来匹配用户ID,组ID,进程ID及会话ID
      LIMIT---匹配特定时间段内的数据包限制。这个扩展匹配对于限制dos攻击数据流非常有用。
      STATE---匹配特定状态下的数据包(由连接跟踪子系统来决定状态),可能的状态包括:
        INVALID (不匹配于任何连接)
        ESTABLISHED (属于某个已经建立的链接的数据包)
        NEW (建立连接的数据包)
        RELATED (和某个已经建立的连接有一定相关的数据包,例如一个ICMP错误消息或ftp数据连接)
      TOS——匹配IP头的TOS字段的值。

      目标动作扩展:

      LOG 将匹配的数据包传递给syslog()进行记录
      ULOG 将匹配的数据适用用户空间的log进程进行记录
      REJECT 不仅仅丢弃数据包,同时返回给发送者一个可配置的错误信息
      MIRROR 互换源和目的地址以后重新传输该数据包

      Ipchains是一种Linux下使用比较广泛的工具软件,可以实现数据包过滤的防火墙功能(Linux的内核为2.1及以上的内核版本都能够支持这个软件包)。这个软件包管理着对Linux操作系统内核本身极为重要的那些IP帐户和防火墙功能。用户使用的内核必须已经在编译时激活ipchains功能;如果想掌握ipchains运行在哪一个层次,就必须在数据包级别上精通TCP/IP网络的数据传输情况。ipchains是一个数据包过滤器,即是一个用来检查数据包的信封内容的程序;同时,根据用户设定的一系列规则,还可以决定是否允许某些数据包通过和把它们发送到什么地方。
      安装ipchains:首先下载或在光盘上找到它的rpm包,然后以root身份登录进入系统,敲入“rpm -ivh ipchains*”的命令来安装ipchains软件包。

      配置ipchains的数据包过滤功能:首先依然以root用户身份登录进入系统,接着输入“ipchains-L”命令,查看当前已经存在的链。如果你还没有对这些选项进行过配置的话,应该会看到下面这样的几行:

    >chaininput(policyACCEPT);
    >chainforward(policyACCEPT);
    >chainoutput(policyACCEPT);
    >

      选择打算配置的链:一个链就是一系列加在一组数据包类型上的规则。inputchain(输入链)指的是进入到防火墙机器中的数据包。forwardchain(转发链)指的是进入到防火墙机器中而现在又需要发送到网络中的另外一台机器上的数据包。outputchain(输出链)指的是要向外发送的数据包。

      然后输入“ipchains -L chain”命令,列出打算编辑的链中当前已经存在的规则。在缺省的情况下,所有的链中的规则都是空白的。再输入“ipchain-Achain”,告诉ipchains程序需要针对哪个链建立一个新的数据包过滤规则。举例来说,用户可能想对输入链建立些新规则,那么就输入“ipchains -A input”。现在还不能按回车键,还有事情要做。现在需要键入规则本身的内容。我们假定用户想做的设置是:除了从某一台特定的远程工作站点之外,人们没有办法远程登录连接到防火墙后面的任何机器。在你正在建立的那个规则的格式中使用-s(source)标志设置地址(或地址范围),如下:

      (1)单个完整的IP地址,比如:192.168.152.24。
      (2)整个一类的IP地址范围,比如:192.168.152.0/255.255.255.0—它表示从192.168.152.0到192.168.152.255范围内的地址。
      (3)主机名,比如:blue。
      (4)完整的域名,比如:blue.cdors.org。
      (5)某个IP地址范围,要使用IP地址和网络屏蔽码(netmask)认真地构造之。

      我们这个示例的目标是只允许从三台特定的机器上接入远程登录服务,它们的IP地址是192.156.12.1到192.156.12.3。表示这个地址范围的IP地址和网络屏蔽码组合是192.156.12.1/255.255.255.252。现在用户的规则语句看起来应该是这个样子的:ipchains-Ainput-s192.156.12.1/255.255.255.252还是不能按回车键,你还有事情要做。
      除了来自这三台机器以外,还可以继续细化,告诉ipchains程序允许通过防火墙进入的接收程序必须要使用哪一种协议。用户可以使用-p(protocol,协议)标志。远程登录进程使用的是TCP协议。现在这条规则看起来像是:ipchains-Ainput-s192.156.12.1/255.255.255.252-pTCP还是不要按回车键。

      围绕某个特定的协议建立一条规则的选择太多了,但是用户可以为你选定的进程指定其端口(port)来细化那条规则。用户可以把端口的名称加到规则的末尾,也可以用一个冒号引导该端口的端口号。从/etc/services文件中可以查到任何网络服务所使用的端口号。现在这条规则看起来是下列这两行文字中的某个样子:

    ipchains-Ainput-s192.156.12.1/255.255.255.252-pTCP:23ALLOW
    ipchains-Ainput-s192.156.12.1/255.255.255.252-pTCPTelnetALLOW

      现在可以按下回车键了。用户在确实屏蔽了其他接入类型之前,这条规则实际上还是没有什么用处的。最好的解决方法(因为我们的目的是为用户所有希望允许的东西建立规则)是使用-P(policy)标志(注意是大写字母)屏蔽所有的输入,然后ipchains就会去检查特定的规则看看到底什么才能被允许进入。这样的一个策略语句如下所示:ipchains-PinputDENY

      在重启动/关机之前保存数据包过滤规则:没有哪个配置文件是用来自动保存数据包过滤规则供你下次启动机器的时候使用的。因此,选择某种方法自己来完成这项工作就十分重要,否则下一次你就还得从头一点一滴地重新写出所有的规则。下面介绍一个保存数据包过滤规则的方法:先以root身份登录进入系统,再使用ipchains-save脚本程序把用户已经编写好的规则设置保存到一个文件中去,比如/root/ipchains-settings文件。输入“ipchains-save>/root/ipchains-settings”。

      开机引导后恢复数据包过滤规则:用户在计算机重启动之后,必须恢复数据包过滤规则。请按照下面的方法完成这项任务:先以root身份登录进入系统,再使用ipchains-restore脚本程序在某个文件中检索用户已经编写好的规则,比如从文件/root/ipchains-settings中恢复数据包过滤规则。如下所示,输入“ipchains-restore

      如果要想实现代理防火墙功能,需要安装能够控制用户从某个网络的外部可以使用和不可以使用什么样的网络服务功能的软件。代理防火墙不允许有任何连接接入到它后面的机器上(当然也不是绝对的),不存在任何数据包过滤的效果,从接入连接的角度考虑,它就是一堵密不透风的砖墙。可以如下设置:

      首先在/etc/inetd.conf文件中禁用任何你不打算使用的服务功能,方法是把它们改为注释语句(即在那些语句开头加上一个#符号)。任何一种服务都会为试图进入系统的那些人多打开一条通路,因此应该只使用你确实需要的服务。
    接着编辑/etc/issue.net文件,删除其中关于在你的机器上运行的特定硬件和Linux发行版本的介绍信息。这些信息会在诸如Telnet之类的远程登录任务操作过程中显示在登录端的屏幕上。如果他们对屏幕上显示的安装方式熟悉的话,任何暴露了你机器上这些特殊信息的东西都会使那些试图闯入的人们了解应该去攻击哪些薄弱环节(如Sendmail8.7-8.8.2 for Linux这个漏洞)。

      再接着把某些特殊的用户们分配到console用户组中,这样就是这帮人实际坐在服务器计算机前面时确实可以执行命令,但同时要禁止任何其他人调用这些命令。举例来说,如果需要强调安全性,那就应该只允许console用户组的成员可以挂装磁盘。

      然后查看/etc/securetty文件,确定其中列出的设备都是真实存在的物理ttys(比如tty1到tty8)端口。这个文件限制了人们能够以根用户身份登录进入系统的位置。允许任何远端用户以根用户身份登录进入系统是极其危险的,因为这样做就为潜在的侵入者缩短了侵入超级用户帐户的过程。

      最后是最好不设匿名帐户或来宾帐户(anonymouse & guest)如果一定要设,请在/etc/passwd中将其shell设为/bin/failure,使其不能访问任何shell。(注意:Linux中是设为/bin/false)。打开chroot(如chroot -s),使其访问的文件限定在一定目录下。一定要保证在FTP服务器上唯一允许匿名用户进行写入操作的部分是/incoming目录。列出成功登录的记录清单如果想查看都有哪些人最近成功地登录进入了系统,可以使用last命令。如果想列出比缺省数目更多的记录,可以使用格式“last -nnumber”告诉last命令需要显示多少登录记录。如果这个命令执行失败,说明登录操作还没有被记录下来。为了确保它们能够被记录下来,请以根用户身份执行“touch/sar/log/wtmp”命令来建立日志记录文件。列出不成功登录的记录清单如果想查看都有哪些人最近没有成功地登录进入系统,可以使用lastb命令。和last命令相类似,如果你想列出比缺省数目更多的不成功尝试记录的话,可以使用“lastb -nnumber”格式。如果这个命令执行失败,说明不成功登录操作还没有被记录下来。为了确保它们能够被记录下来,请以根用户身份执行“touch/var/log/btmp”命令来建立日志记录文件。

      如果安全出现了漏洞,或者你认为已经出现了漏洞的话,就可以抓住这个机会从系统登录记录或者其他地方查找蛛丝马迹。系统会记录下每一次成功的登录操作和不成功的登录尝试操作。特别是那个“列出不成功的尝试登录记录清单”,它能够让你很快地查找出是否有人在千方百计地获取根用户权限或者猜试某个用户的口令字。
    如果你使用的是shadow隐藏口令字软件,请检查/etc/passwd文件,看看其中是否禁用了shadow隐藏口令字功能——如果是这样,口令字将会被保存在/etc/passwd文件里。Linux系统中的/etc/passwd文件是整个系统中最重要的文件,它包含了每个用户的信息(加密后的口令也可能存与/etc/shadow文件中)。它每一行分为7个部分,依次为用户登录名,加密过的口令,用户号,用户组号,用户全名,用户主目录和用户所用的Shell程序,其中用户号(UID)和用户组号(GID)用于Unix系统唯一地标识用户和同组用户及用户的访问权限。这个文件是用DES不可逆算法加密的,只能用John之类的软件穷举,因此,此文件成为入侵者的首要目标。通常黑客用FTP匿名登录后将passwd Get回去,就用John开始跑了。所以一定要把此文件设为不可读不可写。另注意,opasswd或passwd.old是passwd的备份,它们可能存在,如果存在,一定也要设为不可读不可写修改。进行以上设置必须root用户的权限,所以如果情况真的如上面所说的这样,你就应该知道在这台机器上黑客已经获得了root的操作权限。

      检查是否有不熟悉的用户帐户拥有特殊的优先权:一个拥有高级工具和丰富经验的黑客能够替换某些重要的系统功能。用一台独立的计算机或者一台你相信没有遭到攻击的机器把诸如ls之类的命令备份到一张软盘上去,当然最好是将安装光盘再刻录一张,然后检查程序ls、find、ps和所有网络守护进程的系统版本中的日期与它们生成时的日期数据是否一致。

      最后你应该经常到下面的地方去查看是否有提高安全性方面的建议和那些修补最新发现的系统漏洞的网站:如Root Shell (http://www.rootshell.com)、Computer Emergency Response Team(计算机紧急情况快速反应组——http://www.cert.com)和你机器上安装的Linux版本的软件服务商网页,并最好订阅一些最新系统漏洞的电子杂志。
    · 周侃·yesky·
    发布人:pnut 来自:天极