服务器架设篇 - CentOS 5.x

第九章、防火墙与 NAT 服务器

利用简单的 iptables 规则来说明防火墙,另外也会提到 NAT 服务器这个 IP 分享的咚咚!

最近更新时间: 2011/02/08

本文数据主要针对 CentOS 5.x 的系统进行说明,而 CentOS 5.x 已经在 2017 年 3 月份正式不再进行维护,事实上,在 2012 年底几乎就不再维护了。 因此,建议您前往本站查找最新版本的 Linux distribution 文章来阅读,比较不会浪费时间。那为何还需要编辑 CentOS 5 的数据呢? 鸟哥只想要做个自己曾经撰写过的文档内容保存而已啰! ^_^!最新文章请前往鸟站首页查阅啰!
从第七章的图 7.1-1 我们可以发现防火墙是整个封包要进入主机前的第一道关卡,但,什么是防火墙?Linux 的防火墙有哪些机制? 防火墙可以达到与无法达到的功能有哪些?防火墙能不能作为区域防火墙而不是仅针对单一主机而已呢?其实,Linux 的防火墙主要是通过 Netfilter 与 TCP Wrappers 两个机制来管理的。其中,通过 Netfilter 防火墙机制,我们可以达到让私有 IP 的主机上网 (IP 分享器功能) ,并且也能够让 Internet 连到我内部的私有 IP 所架设的 Linux 服务器 (DNAT 功能)!真的很不赖喔! 这一章对您来说,也真的有够重要的啦!

9.1 认识防火墙

网络安全除了随时注意相关软件的漏洞以及网络上的安全通报之外,你最好能够依据自己的环境来订定防火墙机制! 这样对于你的网络环境,会比较有保障一点喔!那么什么是防火墙呢?其实防火墙就是通过订定一些有顺序的规则,并管制进入到我们网域内的主机 (或者可以说是网域) 数据封包的一种机制!更广义的来说,只要能够分析与过滤进出我们管理之网域的封包数据, 就可以称为防火墙

防火墙又可以分为硬件防火墙与本机的软件防火墙。硬件防火墙是由厂商设计好的主机硬件, 这部硬件防火墙内的操作系统主要以提供封包数据的过滤机制为主,并将其他不必要的功能拿掉。因为单纯作为防火墙功能而已, 因此封包过滤的效率较佳。至于软件防火墙呢?那就是我们这个章节要来谈论的啊! 软件防火墙本身就是在保护系统网络安全的一套软件(或称为机制),例如 Netfilter 与 TCP Wrappers 都可以称为软件防火墙。

无论怎么分,反正防火墙就是用来保护我们网络安全的咚咚就对啦!我们这个章节主要在介绍 Linux 系统本身提供的软件防火墙的功能,那就是 Netfilter 。至于 TCP Wrappers 虽然在基础篇的第十八章认识系统服务里面谈过了,我们这里还会稍微简单的介绍啦!


9.1.1 开始之前来个提醒事项

由于本章主要的目的在介绍 Netfilter 这种封包过滤式的防火墙机制,因此网络基础里面的许多封包与讯框的概念要非常清楚, 包括网域的概念, IP 网域的撰写方式等,均需有一定的基础才行。请到第二章加强一下 MAC, IP, ICMP, TCP, UDP 等封包表头数据的认识,以及 Network/Netmask 的整体网域 (CIDR) 写法等。

另外,虽然 Netfilter 机制可以通过 iptables 指令的方式来进行规则的排序与修改,不过鸟哥建议你利用 shell script 来撰写属于你自己的防火墙机制比较好,因为对于规则的排序与汇整有比较好的观察性, 可以让你的防火墙规则比较清晰一点。所以在你开始了解底下的数据之前,希望你可以先阅读过相关的数据了:

  • 已经认识 Shell 以及 Shell script
  • 已经阅读过第二章网络基础的内容;
  • 已经阅读过第七章认识网络安全的内容;
  • 已经阅读过第八章路由器的内容,了解重要的路由概念;
  • 最好拥有两部主机以上的小型局域网路环境,以方便测试防火墙;
  • 做为区域防火墙的 Linux 主机最好有两张实体网卡,可以进行多种测试,并架设 NAT 服务器;

9.1.2 为何需要防火墙

仔细分析第七章的图 7.1-1 可以发现, 封包进入本机时,会通过防火墙、服务器软件进程、SELinux与文件系统等。所以基本上,如果你的系统 (1)已经关闭不需要而且危险的服务; (2)已经将整个系统的所有软件都保持在最新的状态; (3)权限设置妥当且定时进行备份工作; (4)已经教育用户具有良好的网络、系统操作习惯。 那么你的系统实际上已经颇为安全了!要不要架设防火墙?那就见仁见智啰!

不过,毕竟网络世界是很复杂的,而 Linux 主机也不是一个简单的东西,说不定哪一天你在进行某个软件的测试时, 主机突然间就启动了一个网络服务,如果你没有管制该服务的使用范围,那么该服务就等于对所有 Internet 开放, 那就麻烦了!因为该服务可能可以允许任何人登录你的系统,那不是挺危险?

所以啰,防火墙能作什么呢?防火墙最大的功能就是帮助你『限制某些服务的访问来源』! 举例来说: (1)你可以限制文件传输服务 (FTP) 只在子网域内的主机才能够使用,而不对整个 Internet 开放; (2)你可以限制整部 Linux 主机仅可以接受客户端的 WWW 要求,其他的服务都关闭; (3)你还可以限制整部主机仅能主动对外连接。反过来说,若有用户端对我们主机发送主动连接的封包状态 (TCP 封包的 SYN flag) 就予以抵挡等等。这些就是最主要的防火墙功能了!

所以鸟哥认为,防火墙最重要的任务就是在规划出:

  • 切割被信任(如子网域)与不被信任(如 Internet)的网段;
  • 划分出可提供 Internet 的服务与必须受保护的服务;
  • 分析出可接受与不可接受的封包状态;

当然啦,咱们 Linux 的 iptables 防火墙软件还可以进行更细部深入的 NAT (Network Address Translation) 的设置,并进行更弹性的 IP 封包伪装功能,不过,对於单一主机的防火墙来说, 最简单的任务还是上面那三项就是了!所以,你需不需要防火墙呢?理论上,当然需要! 而且你必须要知道『你的系统哪些数据与服务需要保护』,针对需要受保护的服务来设置防火墙的规则吧! 底下我们先来谈一谈,那在 Linux 上头常见的防火墙类型有哪些?

9.1.3 Linux 系统上防火墙的主要类别

基本上,依据防火墙管理的范围,我们可以将防火墙区分为网域型与单一主机型的控管。在单一主机型的控管方面, 主要的防火墙有封包过滤型的 Netfilter 与依据服务软件程序作为分析的 TCP Wrappers 两种。若以区域型的防火墙而言, 由于此类防火墙都是当作路由器角色,因此防火墙类型主要则有封包过滤的 Netfilter 与利用代理服务器 (proxy server) 进行访问代理的方式了。


  • Netfilter (封包过滤机制)

    所谓的封包过滤,亦即是分析进入主机的网络封包,将封包的表头数据捉出来进行分析,以决定该连接为放行或抵挡的机制。 由于这种方式可以直接分析封包表头数据,所以包括硬件地址(MAC), 软件地址 (IP), TCP, UDP, ICMP 等封包的信息都可以进行过滤分析的功能,因此用途非常的广泛。(其实主要分析的是 OSI 七层协定的 2, 3, 4 层啦)

    在 Linux 上面我们使用内核内置的 Netfilter 这个机制,而 Netfilter 提供了 iptables 这个软件来作为防火墙封包过滤的指令。由于 Netfilter 是内核内置的功能,因此他的效率非常的高! 非常适合于一般小型环境的设置呢!Netfilter 利用一些封包过滤的规则设置,来定义出什么数据可以接收, 什么数据需要剔除,以达到保护主机的目的喔!


  • TCP Wrappers (程序控管)

    另一种抵挡封包进入的方法,为通过服务器程序的插件 (tcpd) 来处置的!与封包过滤不同的是, 这种机制主要是分析谁对某程序进行访问,然后通过规则去分析该服务器程序谁能够连接、谁不能连接。 由于主要是通过分析服务器程序来控管,因此与启动的端口口无关,只与程序的名称有关。 举例来说,我们知道 FTP 可以启动在非正规的 port 21 进行监听,当你通过 Linux 内置的 TCP wrappers 限制 FTP 时, 那么你只要知道 FTP 的软件名称 (vsftpd) ,然后对他作限制,则不管 FTP 启动在哪个端口口,都会被该规则管理的。


  • Proxy (代理服务器)

    其实代理服务器是一种网络服务,它可以『代理』用户的需求,而代为前往服务器取得相关的数据。就有点像底下这个图标吧:

    Proxy Server 的运作原理简介
    图 9.1-1、Proxy Server 的运作原理简介

    以上图为例,当 Client 端想要前往 Internet 取得 Google 的数据时,他取得数据的流程是这样的:

    1. client 会向 proxy server 要求数据,请 proxy 帮忙处理;
    2. proxy 可以分析用户的 IP 来源是否合法?用户想要去的 Google 服务器是否合法? 如果这个 client 的要求都合法的话,那么 proxy 就会主动的帮忙 client 前往 Google 取得数据;
    3. Google 所回传的数据是传给 proxy server 的喔,所以 Google 服务器上面看到的是 proxy server 的 IP 啰;
    4. 最后 proxy 将 Google 回传的数据送给 client。

    这样了解了吗?没错, client 并没有直接连上 Internet ,所以在实线部分(步骤 1, 4)只要 Proxy 与 Client 可以连接就可以了!此时 client 甚至不需要拥有 public IP 哩!而当有人想要攻击 client 端的主机时, 除非他能够攻破 Proxy server ,否则是无法与 client 连接的啦!

    另外,一般 proxy 主机通常仅开放 port 80, 21, 20 等 WWW 与 FTP 的端口口而已,而且通常 Proxy 就架设在路由器上面,因此可以完整的掌控局域网路内的对外连接!让你的 LAN 变的更安全啊! 由于一般小型网络环境很少会用到代理服务器,因此本书并没有谈到 proxy server 的设置,有兴趣的话可以参考一下 squid (注1) 这个软件的官网或 google 一下吧!

9.1.4 防火墙的一般网络布线示意

由前面的说明当中,你应该可以了解到一件事,那就是防火墙除了可以『保护防火墙机制本身所在的那部主机』之外,还可以『保护防火墙后面的主机』。也就是说,防火墙除了可以防备本机被入侵之外, 他还可以架设在路由器上面借以控管进出本地端网域的网络封包。 这种规划对于内部私有网域的安全也有一定程度的保护作用呢!底下我们稍微谈一谈目前常见的防火墙与网络布线的配置吧:


  • 单一网域,仅有一个路由器:

    防火墙除了可以作为 Linux 本机的基本防护之外,他还可以架设在路由器上面以管控整个局域网路的封包进出。 因此,在这类的防火墙上头通常至少需要有两个接口,将可信任的内部与不可信任的 Internet 分开, 所以可以分别设置两块网络接口的防火墙规则啦!简单的环境如同下列图 9.1-2 所示。

    在图 9.1-2 中,由于防火墙是设置在所有网络封包都会经过的路由器上头, 因此这个防火墙可以很轻易的就掌控到局域网路内的所有封包, 而且你只要管理这部防火墙主机,就可以很轻易的将来自 Internet 的不良网络封包抵挡掉呐。 只要管理一部主机就能够造福整的 LAN 里面的 PC,很划算的啦。

    如果你想要将局域网路控管的更严格的话,那你甚至可以在这部 Linux 防火墙上面架设更严格的代理服务器, 让用户端仅能连上你所开放的 WWW 服务器而已,而且还可以通过代理服务器的注册表分析功能, 明确的查出来那个用户在某个时间点曾经连上哪些 WWW 服务器,你瞧瞧!厉害吧! 如果在这个防火墙上面再加装类似 MRTG 的流量监控软件,还能针对整个网域的流量进行监测。这样配置的优点是:

    • 因为内外网域已经分开,所以安全维护在内部可以开放的权限较大!
    • 安全机制的设置可以针对 Linux 防火墙主机来维护即可!
    • 对外只看的到 Linux 防火墙主机,所以对于内部可以达到有效的安全防护!

    单一网域,仅有一个路由器
    图 9.1-2、单一网域,仅有一个路由器的环境示意图


  • 内部网络包含安全性更高的子网络,需内部防火墙切开子网络:

    一般来说,我们的防火墙对于 LAN 的防备都不会设置的很严格,因为是我们自己的 LAN 嘛!所以是信任网域之一啰!不过,最常听到的入侵方法也是使用这样的一个信任漏洞! 因为你不能保证所有使用企业内部电脑的用户都是公司的员工,也无法保证你的员工不会『搞破坏!』 更多时候是由于某些外来访客利用移动式设备 (笔记本电脑) 连接到公司内部的无线网络来加以窃取企业内部的重要信息。

    呵呵!所以,如果你有特别重要的部门需要更安全的保护网络环境,那么将 LAN 里面再加设一个防火墙,将安全等级分类,那么将会让你的重要数据获得更佳的保护喔!整个架构有点像下图所示。

    内部网络包含需要更安全的子网络防火墙
    图 9.1-3、内部网络包含需要更安全的子网络防火墙


  • 在防火墙的后面架设网络服务器主机

    还有一种更有趣的设置,那就是将提供网络服务的服务器放在防火墙后面,这有什么好处呢? 如下图所示,Web, Mail 与 FTP 都是通过防火墙连到 Internet 上面去,所以, 底下这四部主机在 Internet 上面的 Public IP 都是一样的!(这个观念我们会在本章底下的 NAT 服务器的时候再次的强调)。 只是通过防火墙的封包分析后,将 WWW 的要求封包转送到 Web 主机,将 Mail 送给 Mail Server 去处理而已(通过 port 的不同来转递)。

    好了,因为四部主机在 Internet 上面看到的 IP 都相同,但是事实上却是四部不同的主机, 而当有攻击者想要入侵你的 FTP 主机好了,他使用各种分析方法去进攻的主机,其实是『防火墙』那一部, 攻击者想要攻击你内部的主机,除非他能够成功的搞定你的防火墙,否则就很难入侵你的内部主机呢!

    而且,由于主机放置在两部防火墙中间,内部网络如果发生状况时 (例如某些用户不良操作导致中毒啊、 被社交工程攻陷导致内部主机被绑架啊等等的) ,是不会影响到网络服务器的正常运作的。 这种方式适用在比较大型的企业当中,因为对这些企业来说,网络主机能否提供正常稳定的服务是很重要的!

    不过,这种架构下所进行的设置就得包含 port 的转递,而且要有很强的网络逻辑概念, 可以厘清封包双向沟通时的流动方式。对于新手来说,设置上有一定的难度, 鸟哥个人不太建议新手这么做,还是等以后有经验之后再来玩这种架构吧!

    架设在防火墙后端的网络服务器环境示意图
    图 9.1-4、架设在防火墙后端的网络服务器环境示意图

    通常像上图的环境中,将网络服务器独立放置在两个防火墙中间的网络,我们称之为非军事区域 (DMZ)。 DMZ 的目的就如同前面提到的,重点在保护服务器本身,所以将 Internet 与 LAN 都隔离开来,如此一来不论是服务器本身,或者是 LAN 被攻陷时,另一个区块还是完好无缺的!

9.1.5 防火墙的使用限制

从前面的分析中,我们已经知道过封包滤式防火墙主要在分析 OSI 七层协定当中的 2, 3, 4 层,既然如此的话, Linux 的 Netfilter 机制到底可以做些什么事情呢?其实可以进行的分析工作主要有:

  • 拒绝让 Internet 的封包进入主机的某些端口口
    这个应该不难了解吧!例如你的 port 21 这个 FTP 相关的端口口,若只想要开放给内部网络的话,那么当 Internet 来的封包想要进入你的 port 21 时,就可以将该数据封包丢掉!因为我们可以分析的到该封包表头的端口口号码呀!

  • 拒绝让某些来源 IP 的封包进入
    例如你已经发现某个 IP 主要都是来自攻击行为的主机,那么只要来自该 IP 的数据封包,就将他丢弃!这样也可以达到基础的安全呦!

  • 拒绝让带有某些特殊旗标 (flag) 的封包进入
    最常拒绝的就是带有 SYN 的主动连接的旗标了!只要一经发现,嘿嘿!你就可以将该封包丢弃呀!

  • 分析硬件地址 (MAC) 来决定连接与否
    如果你的局域网路里面有比较捣蛋的但是又具有比较高强的网络功力的高手时,如果你使用 IP 来抵挡他使用网络的权限,而他却懂得反正换一个 IP 就好了,都在同一个网域内嘛! 同样还是在搞破坏~怎么办?没关系,我们可以锁死他的网络卡硬件地址啊!因为 MAC 是銲在网络卡上面的,所以你只要分析到该用户所使用的 MAC 之后,可以利用防火墙将该 MAC 锁住,呵呵!除非他能够一换再换他的网络卡来取得新的 MAC,否则换 IP 是没有用的啦!

虽然 Netfilter 防火墙已经可以做到这么多的事情,不过,还是有很多事情没有办法通过 Netfilter 来完成喔! 什么?设置防火墙之后还不安全啊!那当然啦!谁说设置了防火墙之后你的系统就一定安全? 防火墙虽然可以防止不受欢迎的封包进入我们的网络当中,不过,某些情况下,他并不能保证我们的网络一定就很安全。 举几个例子来谈一谈:

  • 防火墙并不能很有效的抵挡病毒或木马程序
    假设你已经开放了 WWW 的服务,那么你的 WWW 主机上面,防火墙一定得要将 WWW 服务的 port 开放给 Client 端登录才行吧!否则你的 WWW 主机设置了等于没有用对吧!也就是说,只要进入你的主机的封包是要求 WWW 数据的,就可以通过你的防火墙。那好了,『万一你的 WWW 服务器软件有漏洞,或者本身向你要求 WWW 服务的该封包就是病毒在侦测你的系统』时,你的防火墙可是一点办法也没有啊! 因为本来设置的规则就是会让他通过啊。

  • 防火墙对于来自内部 LAN 的攻击较无承受力
    一般来说,我们对于 LAN 里面的主机都没有什么防火墙的设置,因为是我们自己的 LAN 啊,所以当然就设置为信任网域了!不过, LAN 里面总是可能有些网络小白啊,虽然他们不是故意要搞破坏, 但是他们就是不懂嘛!所以就乱用网络了。这个时候就很糟糕,因为防火墙对于内部的规则设置通常比较少, 所以就容易造成内部员工对于网络误用或滥用的情况。

所以啦,还是回到第七章的图 7.1-1 的说明去看看,分析一下该图标,你就会知道,在你的 Linux 主机实地上网之前,还是得先:

  • 关闭几个不安全的服务;
  • 升级几个可能有问题的套件;
  • 架设好最起码的安全防护--防火墙--

其他相关的消息还是请到第七章认识网络安全里面去看一看怎么增加自身的安全吧!

9.2 TCP Wrappers

在进入主题之前,我们先来玩一个简单的防火墙机制,那就是 TCP Wrappers 这玩意儿。如同前面说的, TCP wrappers 是通过用户端想要链接的程序文件名,然后分析用户端的 IP ,看看是否需要放行。那么哪些程序支持 TCP wrappers 的功能?这个 TCP wrappers 又该如何设置?我们这里先简单的谈谈吧!(这个小节仅是简单的介绍过 TCP wrappers ,更多相关功能请参考基础学习篇的第十八章内容喔!)


9.2.1 哪些服务有支持

说穿了, TCP wrappers 就是通过 /etc/hosts.allow, /etc/hosts.deny 这两个宝贝蛋来管理的一个类似防火墙的机制, 但并非所有的软件都可以通过这两个文件来控管,只有底下的软件才能够通过这两个文件来管理防火墙规则,分别是:

  • 由 super daemon (xinetd) 所管理的服务;
  • 有支持 libwrap.so 模块的服务。

经由 xinetd 管理的服务还好理解,就是设置档在 /etc/xinetd.d/ 里面的服务就是 xinetd 所管理的啊! 那么什么是有支持 libwrap.so 模块呢?就让我们来进行底下的例题,你就比较容易明白啰:

例题:
请查出你的系统有没有安装 xinetd ,若没有请安装。安装完毕后,请查找 xinetd 管理的服务有哪些?
答:
[root@www ~]# yum install xinetd
Setting up Install Process
Package 2:xinetd-2.3.14-10.el5.i386 already installed and latest version
Nothing to do
# 画面中显示,已经是最新的 xinetd !所以,已经有安装啰!
# 接下来找出 xinetd 所管理的服务群!

[root@www ~]# chkconfig --list
....(前面省略)....
xinetd based services:
        chargen-dgram:  off
        chargen-stream: off
....(中间省略)....
        kshell:         off     <==下一小节的范例就用这玩意儿来解释
        rsync:          off
        tcpmux-server:  off
        time-dgram:     off
        time-stream:    off
上述结果最终输出的部分就是 xinetd 所管理的服务群啰!上述的服务之防火墙简易设置,都可以通过 TCP wrappers 来管理的噜!

例题:
请问, syslogd, sshd, xinetd, httpd (若该服务不存在,请自行安装软件),这四个程序有没有支持 tcp wrappers 的抵挡功能?
答:
由于支持 tcp wrappers 的服务必定包含 libwrap 这一个动态函数库,因此可以使用 ldd 来观察该服务即可。 简单的使用方式为:
[root@www ~]# ldd $(which syslogd sshd xinetd httpd)
# 这个方式可以将所有的动态函数库取出来查阅,不过需要眼睛搜索。
# 可以通过底下的方式来处理更快!

[root@www ~]# for name in syslogd sshd xinetd httpd; do echo $name; \
> ldd $(which $name) | grep libwrap; done
syslogd
sshd
        libwrap.so.0 => /lib/libwrap.so.0 (0x00aa3000)
xinetd
        libwrap.so.0 => /lib/libwrap.so.0 (0x0052e000)
httpd
上述的结果中,在该文件名档下有出现 libwrap 的,代表有找到该函数库,才有支持 tcp wrappers。 所以, sshd, xinetd 有支持,但是 syslogd, httpd 这两支程序则不支持。也就是说, httpd 与 syslogd 不能够使用 /etc/hosts.{allow|deny} 来进行防火墙机制的控管。

9.2.2 /etc/hosts.{allow|deny} 的设置方式

那如何通过这两个文件来抵挡有问题的 IP 来源呢?这两个文件的语法都一样,很简单的:

<service(program_name)> : <IP, domain, hostname> 
<服务   (亦即程序名称)> : <IP 或领域 或主机名称>
# 上头的 > < 是不存在于设置档中的喔!

我们知道防火墙的规则都是有顺序的,那这两个文件与规则的顺序优先是怎样呢?基本上是这样的:

  • 先以 /etc/hosts.allow 为优先比对,该规则符合就予以放行;
  • 再以 /etc/hosts.deny 比对,规则符合就予以抵挡;
  • 若不在这两个文件内,亦即规则都不符合,最终则予以放行。

我们拿 kshell 这个 xinetd 管理的服务来进行说明好了,请参考底下的例题吧:

例题:
先开放本机的 127.0.0.1 可以进行任何本机的服务,然后,让区网 (192.168.1.0/24) 可以使用 kshell , 同时 10.0.0.100 也能够使用 kshell ,但其他来源则不允许使用 kshell 喔。
答:
我们得要先知道 kshell 的服务启动的文件名为何,因为 tcp wrappers 是通过启动服务的文件名来管理的。 当我们观察 kshell 的设置档时,可以发现:
[root@www ~]# cat /etc/xinetd.d/kshell
service kshell
{
        flags           = REUSE
        socket_type     = stream
        wait            = no
        user            = root
        server          = /usr/kerberos/sbin/kshd   <==文件名叫做 kshd
        server_args     = -e -5
        disable         = yes
}
因此程序字段的项目要写的不是 kshell 喔!而应该是 kshd 才对!因此,我们应该要这样设置的:
[root@www ~]# vim /etc/hosts.allow
ALL: 127.0.0.1    <==这就是本机全部的服务都接受!
kshd: 192.168.1.0/255.255.255.0 10.0.0.100

[root@www ~]# vim /etc/hosts.deny
kshd: ALL

上面的例题有几个重点,首先, tcp wrappers 理论上不支持 192.168.1.0/24 这种通过 bit 数值来定义的网域, 只支持 netmask 的地址显示方式。另外,如果有多个网域或者是单一来源,可以通过空格来累加。 如果想要写成多行呢?也可以啊!多写几行『 kshd: IP 』的方式也可以,不必要将所有数据集中在一行啦!因为 tcp wrappers 也是一条一条规则比对嘛!

基本上,你只要理解这些数据即可!因为绝大部分的时刻,我们都会建议使用底下介绍的 Netfilter 的机制来抵挡封包。 那让我们准备开始来玩玩 iptables 封包过滤防火墙吧!

9.3 Linux 的封包过滤软件:iptables

上面谈了这么多,主要还是希望你能了解到防火墙是什么这个议题!而且也希望你知道防火墙并非万能的。 好了,那么底下我们终于可以来瞧一瞧,那目前我们的 2.6 版这个 Linux 内核到底使用什么内核功能来进行防火墙设置?


9.3.1 不同 Linux 内核版本的防火墙软件

Linux 的防火墙为什么功能这么好?这是因为他本身就是由 Linux 内核所提供,由于直接经过内核来处理,因此性能非常好! 不过,不同内核版本所使用的防火墙软件是不一样的!因为内核支持的防火墙是逐渐演进而来的嘛!

  • Version 2.0:使用 ipfwadm 这个防火墙机制;
  • Version 2.2:使用的是 ipchains 这个防火墙机制;
  • Version 2.4 与 2.6 :主要是使用 iptables 这个防火墙机制,不过在某些早期的 Version 2.4 版本的 distributions 当中,亦同时支持 ipchains (编译成为模块),好让用户仍然可以使用来自 2.2 版的 ipchains 的防火墙规划。不过,不建议在 2.4 以上的内核版本使用 ipchains 喔!

因为不同的内核使用的防火墙机制不同,且支持的软件指令与语法也不相同,所以在 Linux 上头设置属于你自己的防火墙规则时,要注意啊,先用 uname -r 追踪一下你的内核版本再说!如果你是安装 2004 年以后推出的 distributions ,那就不需要担心了,因为这些 distributions 几乎都使用 kernel 2.6 版的内核啊! ^_^

9.3.2 封包进入流程:规则顺序的重要性!

前面的几个小节里面我们一直谈到:『防火墙规则』,咦!啥是规则啊?因为 iptables 是利用封包过滤的机制, 所以他会分析封包的表头数据。根据表头数据与定义的『规则』来决定该封包是否可以进入主机或者是被丢弃。 意思就是说:『根据封包的分析数据 "比对" 你预先定义的规则内容, 若封包数据与规则内容相同则进行动作,否则就继续下一条规则的比对!』 重点在那个『比对与分析顺序』上。

举个简单的例子,假设我预先定义 10 条防火墙规则好了,那么当 Internet 来了一个封包想要进入我的主机, 那么防火墙是如何分析这个封包的呢?我们以底下的图标来说明好了:

封包过滤的规则动作及分析流程
图 9.3-1、封包过滤的规则动作及分析流程

当一个网络封包要进入到主机之前,会先经由 NetFilter 进行检查,那就是 iptables 的规则了。 检查通过则接受 (ACCEPT) 进入本机取得资源,如果检查不通过,则可能予以丢弃 (DROP) ! 上图中主要的目的在告知你:『规则是有顺序的』!例如当网络封包进入 Rule 1 的比对时, 如果比对结果符合 Rule 1 ,此时这个网络封包就会进行 Action 1 的动作,而不会理会后续的 Rule 2, Rule 3.... 等规则的分析了

而如果这个封包并不符合 Rule 1 的比对,那就会进入 Rule 2 的比对了!如此一个一个规则去进行比对就是了。 那如果所有的规则都不符合怎办?此时就会通过缺省动作 (封包政策, Policy) 来决定这个封包的去向。 所以啦,当你的规则顺序排列错误时,就会产生很严重的错误了。 怎么说呢?让我们看看底下这个例子:

假设你的 Linux 主机提供了 WWW 的服务,那么自然就要针对 port 80 来激活通过的封包规则,但是你发现 IP 来源为 192.168.100.100 老是恶意的尝试入侵你的系统,所以你想要将该 IP 拒绝往来,最后,所有的非 WWW 的封包都给他丢弃,就这三个规则来说,你要如何设置防火墙检验顺序呢?

  1. Rule 1 先抵挡 192.168.100.100 ;
  2. Rule 2 再让要求 WWW 服务的封包通过;
  3. Rule 3 将所有的封包丢弃。

这样的排列顺序就能符合你的需求,不过,万一你的顺序排错了,变成:

  1. Rule 1 先让要求 WWW 服务的封包通过;
  2. Rule 2 再抵挡 192.168.100.100 ;
  3. Rule 3 将所有的封包丢弃。

此时,那个 192.168.100.100 『可以使用你的 WWW 服务』喔!只要他对你的主机送出 WWW 要求封包,就可以使用你的 WWW 功能了,因为你的规则顺序定义第一条就会让他通过,而不去考虑第二条规则!这样可以理解规则顺序的意义了吗! 现在再来想一想,如果 Rule 1 变成了『将所有的封包丢弃』,Rule 2 才设置『WWW 服务封包通过』,请问,我的 client 可以使用我的 WWW 服务吗?呵呵!答案是『否~』想通了吗? ^_^

9.3.3 iptables 的表格 (table) 与链 (chain)

事实上,那个图 9.3-1 所列出的规则仅是 iptables 众多表格当中的一个链 (chain) 而已。 什么是链呢?这得由 iptables 的名称说起。为什么称为 ip"tables" 呢? 因为这个防火墙软件里面有多个表格 (table) ,每个表格都定义出自己的缺省政策与规则, 且每个表格的用途都不相同。我们可以使用底下这张图来稍微了解一下:

iptables 的表格与相关链示意图
图 9.3-2、iptables 的表格与相关链示意图

刚刚图 9.3-1 的规则内容仅只是图 9.3-2 内的某个 chain 而已! 而缺省的情况下,咱们 Linux 的 iptables 至少就有三个表格,包括管理本机进出的 filter 、管理后端主机 (防火墙内部的其他电脑) 的 nat 、管理特殊旗标使用的 mangle (较少使用) 。更有甚者,我们还可以自订额外的链呢! 真是很神奇吧!每个表格与其中链的用途分别是这样的:

  • filter (过滤器):主要跟进入 Linux 本机的封包有关,这个是缺省的 table 喔!
    • INPUT:主要与想要进入我们 Linux 本机的封包有关;
    • OUTPUT:主要与我们 Linux 本机所要送出的封包有关;
    • FORWARD:这个咚咚与 Linux 本机比较没有关系, 他可以『转递封包』到后端的电脑中,与下列 nat table 相关性较高。

  • nat (地址转换):是 Network Address Translation 的缩写, 这个表格主要在进行来源与目的之 IP 或 port 的转换,与 Linux 本机较无关,主要与 Linux 主机后的局域网路内电脑较有相关。
    • PREROUTING:在进行路由判断之前所要进行的规则(DNAT/REDIRECT)
    • POSTROUTING:在进行路由判断之后所要进行的规则(SNAT/MASQUERADE)
    • OUTPUT:与发送出去的封包有关

  • mangle (破坏者):这个表格主要是与特殊的封包的路由旗标有关, 早期仅有 PREROUTING 及 OUTPUT 链,不过从 kernel 2.4.18 之后加入了 INPUT 及 FORWARD 链。 由于这个表格与特殊旗标相关性较高,所以像咱们这种单纯的环境当中,较少使用 mangle 这个表格。

所以说,如果你的 Linux 是作为 www 服务,那么要开放用户端对你的 www 要求有回应,就得要处理 filter 的 INPUT 链; 而如果你的 Linux 是作为局域网路的路由器,那么就得要分析 nat 的各个链以及 filter 的 FORWARD 链才行。也就是说, 其实各个表格的链结之间是有关系的!简单的关系可以由下图这么看:

iptables 内置各表格与链的相关性
图 9.3-3、iptables 内置各表格与链的相关性

上面的图标很复杂喔!不过基本上你依旧可以看出来,我们的 iptables 可以控制三种封包的流向:

  • 封包进入 Linux 主机使用资源 (路径 A): 在路由判断后确定是向 Linux 主机要求数据的封包,主要就会通过 filter 的 INPUT 链来进行控管;

  • 封包经由 Linux 主机的转递,没有使用主机资源,而是向后端主机流动 (路径 B): 在路由判断之前进行封包表头的修订作业后,发现到封包主要是要通过防火墙而去后端,此时封包就会通过路径 B 来跑动。 也就是说,该封包的目标并非我们的 Linux 本机。主要经过的链是 filter 的 FORWARD 以及 nat 的 POSTROUTING, PREROUTING。 这路径 B 的封包流向使用情况,我们会在本章的 9.5 小节来跟大家作个简单的介绍。

  • 封包由 Linux 本机发送出去 (路径 C): 例如回应用户端的要求,或者是 Linux 本机主动送出的封包,都是通过路径 C 来跑的。先是通过路由判断, 决定了输出的路径后,再通过 filter 的 OUTPUT 链来发送的!当然,最终还是会经过 nat 的 POSTROUTING 链。
Tips 鸟哥 有没有发现有两个『路由判断』呢?因为网络是双向的,所以进与出要分开来看!因此,进入的封包需要路由判断, 送出的封包当然也要进行路由判断才能够发送出去啊!了解乎?

由于 mangle 这个表格很少被使用,如果将图 9.3-3 的 mangle 拿掉的话,那就容易看的多了:

iptables 内置各表格与链的相关性(简图)
图 9.3-4、iptables 内置各表格与链的相关性(简图)

通过图 9.3-4 你就可以更轻松的了解到,事实上与本机最有关的其实是 filter 这个表格内的 INPUT 与 OUTPUT 这两条链,如果你的 iptables 只是用来保护 Linux 主机本身的话,那 nat 的规则根本就不需要理他,直接设置为开放即可。

不过,如果你的防火墙事实上是用来管制 LAN 内的其他主机的话,那么你就必须要再针对 filter 的 FORWARD 这条链,还有 nat 的 PREROUTING, POSTROUTING 以及 OUTPUT 进行额外的规则订定才行。 nat 表格的使用需要很清晰的路由概念才能够设置的好,建议新手先不要碰!最多就是先玩一玩最阳春的 nat 功能『IP 分享器的功能』就好了! ^_^!这部份我们在本章的最后一小节会介绍的啦!

9.3.4 本机的 iptables 语法

理论上,当你安装好 Linux 之后,系统应该会主动的帮你启动一个阳春的防火墙规则才是, 不过这个阳春防火墙可能不是我们想要的模式,因此我们需要额外进行一些修订的行为。不过,在开始进行底下的练习之前, 鸟哥这里有个很重要的事情要告知一下。因为 iptables 的指令会将网络封包进行过滤及抵挡的动作,所以, 请不要在远程主机上进行防火墙的练习,因为你很有可能一不小心将自己关在家门外! 尽量在本机前面登录 tty1-tty6 终端机进行练习,否则常常会发生悲剧啊!鸟哥以前刚刚在玩 iptables 时,就常常因为不小心规则设置错误,导致常常要请远程的朋友帮忙重新开机...

刚刚提到咱们的 iptables 至少有三个缺省的 table (filter, nat, mangle),较常用的是本机的 filter 表格, 这也是缺省表格啦。另一个则是后端主机的 nat 表格,至于 mangle 较少使用,所以这个章节我们并不会讨论 mangle。 由于不同的 table 他们的链不一样,导致使用的指令语法或多或少都有点差异。 在这个小节当中,我们主要将针对 filter 这个缺省表格的三条链来做介绍。底下就来玩一玩吧!

Tips 鸟哥 防火墙的设置主要使用的就是 iptables 这个指令而已。而防火墙是系统管理员的主要任务之一, 且对于系统的影响相当的大,因此『只能让 root 使用 iptables 』,不论是设置还是观察防火墙规则喔!

9.3.4-1 规则的观察与清除

如果你在安装的时候选择没有防火墙的话,那么 iptables 在一开始的时候应该是没有规则的,不过, 可能因为你在安装的时候就有选择系统自动帮你创建防火墙机制,那系统就会有缺省的防火墙规则了! 无论如何,我们先来看看目前本机的防火墙规则是如何吧!

[root@www ~]# iptables [-t tables] [-L] [-nv]
选项与参数:
-t :后面接 table ,例如 nat 或 filter ,若省略此项目,则使用缺省的 filter
-L :列出目前的 table 的规则
-n :不进行 IP 与 HOSTNAME 的反查,显示消息的速度会快很多!
-v :列出更多的信息,包括通过该规则的封包总比特数、相关的网络接口等

范例:列出 filter table 三条链的规则
[root@www ~]# iptables -L -n
Chain INPUT (policy ACCEPT)    <==针对 INPUT 链,且缺省政策为可接受
target               prot opt source     destination  <==说明栏
RH-Firewall-1-INPUT  all  --  0.0.0.0/0  0.0.0.0/0    <==规则跳到 RH 链去检查

Chain FORWARD (policy ACCEPT) <==针对 FORWARD 链,且缺省政策为可接受
target               prot opt source     destination
RH-Firewall-1-INPUT  all  --  0.0.0.0/0  0.0.0.0/0

Chain OUTPUT (policy ACCEPT) <==针对 OUTPUT 链,且缺省政策为可接受
target     prot opt source               destination

Chain RH-Firewall-1-INPUT (2 references)  <==自订链的规则顺序
target     prot opt source     destination
ACCEPT     all  --  0.0.0.0/0  0.0.0.0/0                  <==第 1 条规则
ACCEPT     icmp --  0.0.0.0/0  0.0.0.0/0    icmp type 255 <==第 2 条规则
ACCEPT     esp  --  0.0.0.0/0  0.0.0.0/0                  <==第 3 条规则
ACCEPT     ah   --  0.0.0.0/0  0.0.0.0/0                  <==底下类推共 9 条规则
ACCEPT     udp  --  0.0.0.0/0  224.0.0.251  udp dpt:5353
ACCEPT     udp  --  0.0.0.0/0  0.0.0.0/0    udp dpt:631
ACCEPT     tcp  --  0.0.0.0/0  0.0.0.0/0    tcp dpt:631
ACCEPT     all  --  0.0.0.0/0  0.0.0.0/0    state RELATED,ESTABLISHED
REJECT     all  --  0.0.0.0/0  0.0.0.0/0    reject-with icmp-host-prohibited

范例:列出 nat table 三条链的规则
[root@www ~]# iptables -t nat -L -n
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

在上表中,每一个 Chain 就是前面提到的每个链啰~ Chain 那一行里面括号的 policy 就是缺省的政策, 那底下的 target, prot 代表什么呢?

  • target:代表进行的动作, ACCEPT 是放行,而 REJECT 则是拒绝,此外,尚有 DROP (丢弃) 的项目!
  • prot:代表使用的封包协定,主要有 tcp, udp 及 icmp 三种封包格式;
  • opt:额外的选项说明
  • source :代表此规则是针对哪个『来源 IP』进行限制?
  • destination :代表此规则是针对哪个『目标 IP』进行限制?

在输出结果中,第一个范例因为没有加上 -t 的选项,所以缺省就是 filter 这个表格内的 INPUT, OUTPUT, FORWARD 三条链的规则啰。由于缺省规则中,INPUT 与 FORWARD 的规则一致,因此 CentOS 将两条链的规则写在一块,变成一个自订链 RH-Firewall-1-INPUT 的链!你得要注意的是,最后一条规则的政策是 REJECT (拒绝) 喔! 所以,虽然 INPUT 与 FORWARD 的政策是放行 (ACCEPT),不过其实不合前面 8 条规则的封包全部都会被第 9 条规则拒绝。

不过这个指令的观察只是作个格式化的查阅,要详细解释每个规则会比较不容易解析。举例来说, 我们将上述的九条规则依据输出结果来说明一下,结果会变成:

  1. 无论任何来源 (0.0.0.0/0) 且要去任何目标的封包,不论任何封包格式 (prot 为 all),通通都接受
  2. 只要是 icmp 类型为 255 号的,就予以放行
  3. 只要是封包格式为 esp 的,就予以放行 (特殊功能)
  4. 只要是封包格式为 ah 的,就予以放行 (特殊功能)
  5. 只要是要发送给目标为 224.0.0.251 且为 udp 端口口 5353 的,就予以接受
  6. 只要是传给 port 631 的 udp 封包就接受
  7. 只要是传给 port 631 的 tcp 封包就接受
  8. 只要是封包状态为 RELATED,ESTABLISHED 就予以接受
  9. 全部的封包信息通通拒绝

最有趣的应该是第一条规则了,怎么会所有的封包信息都予以接受?如果都接受的话,那么后续的规则根本就不会有用嘛! 其实那条规则是仅针对每部主机都有的内部循环测试网络 (lo) 接口啦!如果没有列出接口,那么我们就很容易搞错啰~ 所以,近来鸟哥都建议使用 iptables-save 这个指令来观察防火墙规则啦!因为 iptables-save 会列出完整的防火墙规则,只是并没有规格化输出而已。

[root@www ~]# iptables-save [-t table]
选项与参数:
-t :可以仅针对某些表格来输出,例如仅针对 nat 或 filter 等等

[root@www ~]# iptables-save
# Generated by iptables-save v1.3.5 on Wed Jan 26 18:25:15 2011
*filter                       <==星号开头的指的是表格,这里为 filter
:INPUT ACCEPT [0:0]           <==冒号开头的指的是链,三条内置一条自订
:FORWARD ACCEPT [0:0]         <==三条内置链的政策都是 ACCEPT 啰!
:OUTPUT ACCEPT [4:496]
:RH-Firewall-1-INPUT - [0:0]
-A INPUT -j RH-Firewall-1-INPUT    <==针对 INPUT 的规则
-A FORWARD -j RH-Firewall-1-INPUT  <==针对 FORWARD 的规则
-A RH-Firewall-1-INPUT -i lo -j ACCEPT <==针对自订链 RH 的规则
-A RH-Firewall-1-INPUT -p icmp -m icmp --icmp-type any -j ACCEPT
-A RH-Firewall-1-INPUT -p esp -j ACCEPT
-A RH-Firewall-1-INPUT -p ah -j ACCEPT
-A RH-Firewall-1-INPUT -d 224.0.0.251 -p udp -m udp --dport 5353 -j ACCEPT
-A RH-Firewall-1-INPUT -p udp -m udp --dport 631 -j ACCEPT
-A RH-Firewall-1-INPUT -p tcp -m tcp --dport 631 -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A RH-Firewall-1-INPUT -j REJECT --reject-with icmp-host-prohibited
COMMIT
# Completed on Wed Jan 26 18:25:15 2011

由上面的输出来看,有底线的那条规则当中, -i lo 指的就是由 lo 适配器进来的封包! 这样看就清楚多了!因为有写到接口的关系啊!不像之前的 iptables -L -n 嘛!这样了解乎! 不过,既然这个规则不是我们想要的,那该如何修改规则呢?鸟哥建议,先删除规则再慢慢创建各个需要的规则! 那如何清除规则?这样做就对了:

[root@www ~]# iptables [-t tables] [-FXZ]
选项与参数:
-F :清除所有的已订定的规则;
-X :杀掉所有用户 "自订" 的 chain (应该说的是 tables )啰;
-Z :将所有的 chain 的计数与流量统计都归零

范例:清除本机防火墙 (filter) 的所有规则
[root@www ~]# iptables -F
[root@www ~]# iptables -X
[root@www ~]# iptables -Z

由于这三个指令会将本机防火墙的所有规则都清除,但却不会改变缺省政策 (policy) , 所以如果你不是在本机下达这三行指令时,很可能你会被自己挡在家门外 (若 INPUT 设置为 DROP 时)!要小心啊!

一般来说,我们在重新定义防火墙的时候,都会先将规则给他清除掉。还记得我们前面谈到的, 防火墙的『规则顺序』是有特殊意义的,所以啰, 当然先清除掉规则,然后一条一条来设置会比较容易一点啦。底下就来谈谈定义缺省政策吧!

9.3.4-2 定义缺省政策 (policy)

清除规则之后,再接下来就是要设置规则的政策啦!还记得政策指的是什么吗?『 当你的封包不在你设置的规则之内时,则该封包的通过与否,是以 Policy 的设置为准』,在本机方面的缺省政策中,假设你对于内部的用户有信心的话, 那么 filter 内的 INPUT 链方面可以定义的比较严格一点,而 FORWARD 与 OUTPUT 则可以订定的松一些!通常鸟哥都是将 INPUT 的 policy 定义为 DROP 啦,其他两个则定义为 ACCEPT。 至于 nat table 则暂时先不理会他。

[root@www ~]# iptables [-t nat] -P [INPUT,OUTPUT,FORWARD] [ACCEPT,DROP]
选项与参数:
-P :定义政策( Policy )。注意,这个 P 为大写啊!
ACCEPT :该封包可接受
DROP   :该封包直接丢弃,不会让 client 端知道为何被丢弃。

范例:将本机的 INPUT 设置为 DROP ,其他设置为 ACCEPT
[root@www ~]# iptables -P INPUT   DROP
[root@www ~]# iptables -P OUTPUT  ACCEPT
[root@www ~]# iptables -P FORWARD ACCEPT
[root@www ~]# iptables-save
# Generated by iptables-save v1.3.5 on Wed Jan 26 23:41:43 2011
*filter
:INPUT DROP [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [24:2120]
COMMIT
# Completed on Wed Jan 26 23:41:43 2011
# 由于 INPUT 设置为 DROP 而又尚未有任何规则,所以上面的输出结果显示:
# 所有的封包都无法进入你的主机!是不通的防火墙设置!(网络连接是双向的)

看到输出的结果了吧?INPUT 被修改了设置喔!其他的 nat table 三条链的缺省政策设置也是一样的方式,例如:『 iptables -t nat -P PREROUTING ACCEPT 』就设置了 nat table 的 PREROUTING 链为可接受的意思!缺省政策设置完毕后,来谈一谈关于各规则的封包基础比对设置吧。

9.3.4-3 封包的基础比对:IP, 网域及接口设备

开始来进行防火墙规则的封包比对设置吧!既然是互联网,那么我们就由最基础的 IP, 网域及端口口,亦即是 OSI 的第三层谈起,再来谈谈设备 (网络卡) 的限制等等。这一小节与下一小节的语法你一定要记住,因为这是最基础的比对语法喔!

[root@www ~]# iptables [-AI 链名] [-io 网络接口] [-p 协定] \
> [-s 来源IP/网域] [-d 目标IP/网域] -j [ACCEPT|DROP|REJECT|LOG]
选项与参数:
-AI 链名:针对某的链进行规则的 "插入" 或 "累加"
    -A :添加加一条规则,该规则增加在原本规则的最后面。例如原本已经有四条规则,
         使用 -A 就可以加上第五条规则!
    -I :插入一条规则。如果没有指定此规则的顺序,缺省是插入变成第一条规则。
         例如原本有四条规则,使用 -I 则该规则变成第一条,而原本四条变成 2~5 号
    链 :有 INPUT, OUTPUT, FORWARD 等,此链名称又与 -io 有关,请看底下。

-io 网络接口:设置封包进出的接口规范
    -i :封包所进入的那个网络接口,例如 eth0, lo 等接口。需与 INPUT 链配合;
    -o :封包所传出的那个网络接口,需与 OUTPUT 链配合;

-p 协定:设置此规则适用于哪种封包格式
   主要的封包格式有: tcp, udp, icmp 及 all 。

-s 来源 IP/网域:设置此规则之封包的来源项目,可指定单纯的 IP 或包括网域,例如:
   IP  :192.168.0.100
   网域:192.168.0.0/24, 192.168.0.0/255.255.255.0 均可。
   若规范为『不许』时,则加上 ! 即可,例如:
   -s ! 192.168.100.0/24 表示不许 192.168.100.0/24 之封包来源;

-d 目标 IP/网域:同 -s ,只不过这里指的是目标的 IP 或网域。

-j :后面接动作,主要的动作有接受(ACCEPT)、丢弃(DROP)、拒绝(REJECT)及记录(LOG)

iptables 的基本参数就如同上面所示的,仅只谈到 IP 、网域与设备等等的信息, 至于 TCP, UDP 封包特有的端口口 (port number) 与状态 (如 SYN 旗标) 则在下小节才会谈到。 好,先让我们来看看最基础的几个规则,例如开放 lo 这个本机的接口以及某个 IP 来源吧!

范例:设置 lo 成为受信任的设备,亦即进出 lo 的封包都予以接受
[root@www ~]# iptables -A INPUT -i lo -j ACCEPT

仔细看上面并没有列出 -s, -d 等等的规则,这表示:不论封包来自何处或去到哪里,只要是来自 lo 这个接口,就予以接受!这个观念挺重要的,就是『没有指定的项目,则表示该项目完全接受』的意思! 例如这个案例当中,关于 -s, -d...等等的参数没有规定时,就代表不论什么值都会被接受啰。

这就是所谓的信任设备啦!假如你的主机有两张以太网路卡,其中一张是对内部的网域,假设该网卡的代号为 eth1 好了, 如果内部网域是可信任的,那么该网卡的进出封包就通通会被接受,那你就能够用:『iptables -A INPUT -i eth1 -j ACCEPT』 来将该设备设置为信任设备。不过,下达这个指令前要特别注意,因为这样等于该网卡没有任何防备了喔!

范例:只要是来自内网的 (192.168.1.0/24) 的封包通通接受
[root@www ~]# iptables -A INPUT -i eth0 -s 192.168.1.0/24 -j ACCEPT
# 由于是内网就接受,因此也可以称之为『信任网域』啰。

范例:只要是来自 192.168.0.1 就接受,但 192.168.1.20 这个恶意来源就丢弃
[root@www ~]# iptables -A INPUT -i eth0 -s 192.168.0.1 -j ACCEPT
[root@www ~]# iptables -A INPUT -i eth0 -s 192.168.1.20 -j DROP
# 针对单一 IP 来源,可视为信任主机或者是不信任的恶意来源喔!

[root@www ~]# iptables-save
# Generated by iptables-save v1.3.5 on Fri Jan 28 14:25:09 2011
*filter
:INPUT DROP [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [17:1576]
-A INPUT -i lo -j ACCEPT
-A INPUT -s 192.168.1.0/255.255.255.0 -i eth0 -j ACCEPT
-A INPUT -s 192.168.0.1 -i eth0 -j ACCEPT
-A INPUT -s 192.168.1.20 -i eth0 -j DROP
COMMIT
# Completed on Fri Jan 28 14:25:09 2011

这就是最单纯简单的防火墙规则的设置与观察方式。不过,在上面的案例中,其实你也发现到有两条规则可能有问题~ 那就是上面的特殊字体圈起来的规则顺序。明明已经放行了 192.168.1.0/24 了,所以那个 192.168.1.20 的规则就不可能会被用到! 这就是有问题的防火墙设置啊!了解乎?那该怎办?就重打啊!@_@!那如果你想要记录某个规则的纪录怎么办?可以这样做:

[root@www ~]# iptables -A INPUT -s 192.168.2.200 -j LOG
[root@www ~]# iptables -L -n
target prot opt source         destination
LOG    all  --  192.168.2.200  0.0.0.0/0   LOG flags 0 level 4

看到输出结果的最左边,会出现的是 LOG 喔!只要有封包来自 192.168.2.200 这个 IP 时, 那么该封包的相关信息就会被写入到内核消息,亦即是 /var/log/messages 这个文件当中。 然后该封包会继续进行后续的规则比对。所以说, LOG 这个动作仅在进行记录而已,并不会影响到这个封包的其他规则比对的。 好了,接下来我们分别来看看 TCP,UDP 以及 ICMP 封包的其他规则比对吧!

9.3.4-4 TCP, UDP 的规则比对:针对端口口设置

我们在第二章网络基础谈过各种不同的封包格式, 在谈到 TCP 与 UDP 时,比较特殊的就是那个端口口 (port),在 TCP 方面则另外有所谓的连接封包状态, 包括最常见的 SYN 主动连接的封包格式。那么如何针对这两种封包格式进行防火墙规则的设置呢?你可以这样看:

[root@www ~]# iptables [-AI 链] [-io 网络接口] [-p tcp,udp] \
> [-s 来源IP/网域] [--sport 端口口范围] \
> [-d 目标IP/网域] [--dport 端口口范围] -j [ACCEPT|DROP|REJECT]
选项与参数:
--sport 端口口范围:限制来源的端口口号码,端口口号码可以是连续的,例如 1024:65535
--dport 端口口范围:限制目标的端口口号码。

事实上就是多了那个 --sport 及 --dport 这两个玩意儿,重点在那个 port 上面啦! 不过你得要特别注意,因为仅有 tcp 与 udp 封包具有端口口,因此你想要使用 --dport, --sport 时,得要加上 -p tcp 或 -p udp 的参数才会成功喔!底下让我们来进行几个小测试:

范例:想要连接进入本机 port 21 的封包都抵挡掉:
[root@www ~]# iptables -A INPUT -i eth0 -p tcp --dport 21 -j DROP

范例:想连到我这部主机的网芳 (upd port 137,138 tcp port 139,445) 就放行
[root@www ~]# iptables -A INPUT -i eth0 -p udp --dport 137:138 -j ACCEPT
[root@www ~]# iptables -A INPUT -i eth0 -p tcp --dport 139 -j ACCEPT
[root@www ~]# iptables -A INPUT -i eth0 -p tcp --dport 445 -j ACCEPT

瞧!你可以利用 UDP 与 TCP 协定所拥有的端口口号码来进行某些服务的开放或关闭喔!你还可以综合处理呢!例如:只要来自 192.168.1.0/24 的 1024:65535 端口口的封包,且想要连接到本机的 ssh port 就予以抵挡,可以这样做:

[root@www ~]# iptables -A INPUT -i eth0 -p tcp -s 192.168.1.0/24 \
> --sport 1024:65534 --dport ssh -j DROP

如果忘记加上 -p tcp 就使用了 --dport 时,会发生啥问题呢?

[root@www ~]# iptables -A INPUT -i eth0 --dport 21 -j DROP
iptables v1.3.5: Unknown arg `--dport'
Try `iptables -h' or 'iptables --help' for more information.

你应该会觉得很奇怪,怎么『 --dport 』会是未知的参数 (arg) 呢?这是因为你没有加上 -p tcp 或 -p udp 的缘故啊!很重要喔!

除了端口口之外,在 TCP 还有特殊的旗标啊!最常见的就是那个主动连接的 SYN 旗标了。 我们在 iptables 里面还支持『 --syn 』的处理方式,我们以底下的例子来说明好了:

范例:将来自任何地方来源 port 1:1023 的主动连接到本机端的 1:1023 连接丢弃
[root@www ~]# iptables -A INPUT -i eth0 -p tcp --sport 1:1023 \
> --dport 1:1023 --syn -j DROP

一般来说,client 端激活的 port 都是大于 1024 以上的端口口,而 server 端则是激活小于 1023 以下的端口口在监听的。所以我们可以让来自远程的小于 1023 以下的端口口数据的主动连接都给他丢弃! 但不适用在 FTP 的主动连接中!这部份我们未来在 FTP 章节当中再来谈吧!

9.3.4-5 iptables 插件模块:mac 与 state

在 kernel 2.2 以前使用 ipchains 管理防火墙时,通常会让系统管理员相当头痛!因为 ipchains 没有所谓的封包状态模块,因此我们必须要针对封包的进、出方向进行管控。举例来说,如果你想要连接到远程主机的 port 22 时,你必须要针对两条规则来设置:

  • 本机端的 1024:65535 到远程的 port 22 必须要放行 (OUTPUT 链);
  • 远程主机 port 22 到本机的 1024:65535 必须放行 (INPUT 链);

这会很麻烦!因为如果你要连接到 10 部主机的 port 22 时,假设 OUTPUT 为缺省打开 (ACCEPT), 你依旧需要填写十行规则,让那十部远程主机的 port 22 可以连接到你的本地端主机上。 那如果打开全部的 port 22 呢?又担心某些恶意主机会主动以 port 22 连接到你的机器上! 同样的道理,如果你要让本地端主机可以连到外部的 port 80 (WWW 服务),那就更不得了~ 这就是网络连接是双向的一个很重要的概念!

好在我们的 iptables 免除了这个困扰!他可以通过一个状态模块来分析 『这个想要进入的封包是否为刚刚我发出去的回应?』 如果是刚刚我发出去的回应,那么就可以予以接受放行!哇!真棒!这样就不用管远程主机是否连接进来的问题了! 那如何达到呢?看看底下的语法:

[root@www ~]# iptables -A INPUT [-m state] [--state 状态]
选项与参数:
-m :一些 iptables 的插件模块,主要常见的有:
     state :状态模块
     mac   :网络卡硬件地址 (hardware address)
--state :一些封包的状态,主要有:
     INVALID    :无效的封包,例如数据破损的封包状态
     ESTABLISHED:已经连接成功的连接状态;
     NEW        :想要新创建连接的封包状态;
     RELATED    :这个最常用!表示这个封包是与我们主机发送出去的封包有关

范例:只要已创建或相关封包就予以通过,只要是不合法封包就丢弃
[root@www ~]# iptables -A INPUT -m state \
> --state RELATED,ESTABLISHED -j ACCEPT
[root@www ~]# iptables -A INPUT -m state --state INVALID -j DROP

如此一来,我们的 iptables 就会主动分析出该封包是否为回应状态,若是的话,就直接予以接受。呵呵! 这样一来你就不需要针对回应的封包来撰写个别的防火墙规则了!这真是太棒了!底下我们继续谈一下 iptables 的另一个插件, 那就是针对网卡来进行放行与防御:

范例:针对局域网路内的 aa:bb:cc:dd:ee:ff 主机开放其连接
[root@www ~]# iptables -A INPUT -m mac --mac-source aa:bb:cc:dd:ee:ff \
> -j ACCEPT
选项与参数:
--mac-source :就是来源主机的 MAC 啦!

如果你的区网当中有某些网络高手,老是可以通过修改 IP 去尝试通过路由器往外跑,那你该怎么办? 难道将整个区网拒绝?并不需要的,你可以通过之前谈到的 ARP 相关概念,去捉到那部主机的 MAC ,然后通过上头的这个机制, 将该主机整个 DROP 掉即可。不管他改了什么 IP ,除非他知道你是用网卡的 MAC 来管理,否则他就是出不去啦!了解乎?

Tips 鸟哥 其实 MAC 也是可以伪装的,可以通过某些软件来修改网卡的 MAC。不过,这里我们是假设 MAC 是无法修改的情况来说明的。 此外,MAC 是不能跨路由的,因此上述的案例中才特别说明是在区网内,而不是指 Internet 外部的来源唷!

9.3.4-6 ICMP 封包规则的比对:针对是否回应 ping 来设计

第二章 ICMP 协定当中我们知道 ICMP 的类型相当的多,而且很多 ICMP 封包的类型都是为了要用来进行网络检测用的!所以最好不要将所有的 ICMP 封包都丢弃!如果不是做为路由器的主机时,通常我们会把 ICMP type 8 (echo request) 拿掉而已,让远程主机不知道我们是否存在,也不会接受 ping 的回应就是了。ICMP 封包格式的处理是这样的:

[root@www ~]# iptables -A INPUT [-p icmp] [--icmp-type 类型] -j ACCEPT
选项与参数:
--icmp-type :后面必须要接 ICMP 的封包类型,也可以使用代号,
              例如 8  代表 echo request 的意思。

范例:让 0,3,4,11,12,14,16,18 的 ICMP type 可以进入本机:
[root@www ~]# vi somefile
#!/bin/bash
icmp_type="0 3 4 11 12 14 16 18"
for typeicmp in $icmp_type
do
   iptables -A INPUT -i eth0 -p icmp --icmp-type $typeicmp -j ACCEPT
done

[root@www ~]# sh  somefile

这样就能够开放部分的 ICMP 封包格式进入本机进行网络检测的工作了!不过,如果你的主机是作为区网的路由器, 那么建议 icmp 封包还是要通通放行才好!这是因为用户端检测网络时,常常会使用 ping 来测试到路由器的线路是否畅通之故呦! 所以不要将路由器的 icmp 关掉,会有状况啦!

9.3.4-7 超阳春用户端防火墙设计与防火墙规则保存

经过上述的本机 iptables 语法分析后,接下来我们来想想,如果站在用户端且不提供网络服务的 Linux 本机角色时, 你应该要如何设计你的防火墙呢?老实说,你只要分析过 CentOS 缺省的防火墙规则就会知道了,理论上, 应该要有的规则如下:

  1. 规则归零:清除所有已经存在的规则 (iptables -F...)
  2. 缺省政策:除了 INPUT 这个自订链设为 DROP 外,其他为缺省 ACCEPT;
  3. 信任本机:由于 lo 对本机来说是相当重要的,因此 lo 必须设置为信任设备;
  4. 回应封包:让本机主动向外要求而回应的封包可以进入本机 (ESTABLISHED,RELATED)
  5. 信任用户:这是非必要的,如果你想要让区网的来源可用你的主机资源时

这就是最最阳春的防火墙,你可以通过第二步骤抵挡所有远程的来源封包,而通过第四步骤让你要求的远程主机回应封包可以进入, 加上让本机的 lo 这个内部循环设备可以放行,嘿嘿!一部 client 专用的防火墙规则就 OK 了!你可以在某个 script 上面这样做即可:

[root@www ~]# vim firewall.sh
#!/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin; export PATH

# 1. 清除规则
iptables -F
iptables -X
iptables -Z

# 2. 设置政策
iptables -P   INPUT DROP
iptables -P  OUTPUT ACCEPT
iptables -P FORWARD ACCEPT

# 3~5. 制订各项规则
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -i eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT
#iptables -A INPUT -i eth0 -s 192.168.1.0/24 -j ACCEPT

# 6. 写入防火墙规则设置档
/etc/init.d/iptables save

[root@www ~]# sh firewall.sh
正在保存防火墙规则到 /etc/sysconfig/iptables:              [  确定  ]

其实防火墙也是一个服务,你可以通过『chkconfig --list iptables』去察看就知道了。 因此,你这次修改的各种设置想要在下次开机还保存,那就得要进行『 /etc/init.d/iptables save 』这个指令加参数。 因此,鸟哥现在都是将保存的动作写入这个 firewall.sh 脚本中,比较单纯些啰!现在,你的 Linux 主机已经有相当的保护了, 只是如果想要作为服务器,或者是作为路由器,那就得要自行加上某些自订的规则啰。

Tips 鸟哥 老实说,如果你对 Linux 够熟悉的话,直接去修改 /etc/sysconfig/iptables 然后将 iptables 这个服务 restart, 那你的防火墙规则就是会在开机后持续存在啰!不过,鸟哥个人还是喜欢写 scripts 就是了。

制订好规则后当然就是要测试啰!那么如何测试呢?

  1. 先由主机向外面主动连接试看看;
  2. 再由私有网域内的 PC 向外面主动连接试看看;
  3. 最后,由 Internet 上面的主机,主动连接到你的 Linux 主机试看看;

一步一步作下来,看看问题出在哪里,然后多多的去改进、改良!基本上,网络上目前很多的数据可以提供你不错的参考了! 这一篇的设置写的是很简单,大部分都还在介绍阶段而已!希望对大家有帮助! 鸟哥在参考数据(注2)当中列出几个有用的防火墙网页,希望大家有空真的要多多的去看看!会很有帮助的!

9.3.5 IPv4 的内核管理功能: /proc/sys/net/ipv4/*

除了 iptables 这个防火墙软件之外,其实咱们 Linux kernel 2.6 提供很多内核缺省的攻击抵挡机制喔! 由于是内核的网络功能,所以相关的设置数据都是放置在 /proc/sys/net/ipv4/ 这个目录当中。 至于该目录下各个文件的详细数据,可以参考内核的说明文档:

  • /usr/src/linux-{version}/networking/ip-sysctl.txt

上面的这个说明数据可以由 http://www.kernel.org 这个网站下载任何一个内核原代码后,解压缩就能够看到。 鸟哥这里也放一份备份:

有兴趣的话应该要自行去查一查比较好的喔!我们底下就拿几个简单的文件来作说明吧!


  • /proc/sys/net/ipv4/tcp_syncookies

    我们在前一章谈到所谓的阻断式服务 (DoS) 攻击法当中的一种方式,就是利用 TCP 封包的 SYN 三向交握原理所达成的, 这种方式称为 SYN Flooding 。那如何预防这种方式的攻击呢?我们可以激活内核的 SYN Cookie 模块啊! 这个 SYN Cookie 模块可以在系统用来启动随机连接的端口口 (1024:65535) 即将用完时自动启动。

    当启动 SYN Cookie 时,主机在发送 SYN/ACK 确认封包前,会要求 Client 端在短时间内回复一个序号,这个序号包含许多原本 SYN 封包内的信息,包括 IP、port 等。若 Client 端可以回复正确的序号,那么主机就确定该封包为可信的,因此会发送 SYN/ACK 封包,否则就不理会此一封包

    通过此一机制可以大大的降低无效的 SYN 等待端口口,而避免 SYN Flooding 的 DoS 攻击说! 那么如何启动这个模块呢?很简单,这样做即可:
    [root@www ~]# echo "1" > /proc/sys/net/ipv4/tcp_syncookies
    
    但是这个设置值由于违反 TCP 的三向交握 (因为主机在发送 SYN/ACK 之前需要先等待 client 的序号回应), 所以可能会造成某些服务的延迟现象,例如 SMTP (mail server)。 不过总的来说,这个设置值还是不错用的! 只是不适合用在负载已经很高的服务器内喔! 因为负载太高的主机有时会让内核误判遭受 SYN Flooding 的攻击呢。

    如果是为了系统的 TCP 封包连接优化,则可以参考 tcp_max_syn_backlog, tcp_synack_retries, tcp_abort_on_overflow 这几个设置值的意义。


  • /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts

    阻断式服务常见的是 SYN Flooding ,不过,我们知道系统其实可以接受使用 ping 的回应, 而 ping 的封包数据量是可以给很大的!想像一个状况, 如果有个搞破坏的人使用 1000 台主机发送 ping 给你的主机,而且每个 ping 都高达数百 K bytes时, 你的网络带宽会怎样?要嘛就是带宽被吃光,要嘛可能系统会当机! 这种方式分别被称为 ping flooding (不断发 ping) 及 ping of death (发送大的 ping 封包)。

    那如何避免呢?取消 ICMP 类型 8 的 ICMP 封包回应就是了。我们可以通过防火墙来抵挡, 这也是比较建议的方式。当然也可以让内核自动取消 ping 的回应。不过你必须要了解, 某些局域网路内常见的服务 (例如动态 IP 分配 DHCP 协定) 会使用 ping 的方式来侦测是否有重复的 IP ,所以你最好不要取消所有的 ping 回应比较好。

    内核取消 ping 回应的设置值有两个,分别是:/proc/sys/net/ipv4 内的 icmp_echo_ignore_broadcasts (仅有 ping broadcast 地址时才取消 ping 的回应) 及 icmp_echo_ignore_all (全部的 ping 都不回应)。鸟哥建议设置 icmp_echo_ignore_broadcasts 就好了。 你可以这么做:
    [root@www ~]# echo "1" >  \
    > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts
    

  • /proc/sys/net/ipv4/conf/网络接口/*

    咱们的内核还可以针对不同的网络接口进行不一样的参数设置喔!网络接口的相关设置放置在 /proc/sys/net/ipv4/conf/ 当中,每个接口都以接口代号做为其代表,例如 eth0 接口的相关设置数据在 /proc/sys/net/ipv4/conf/eth0/ 内。那么网络接口的设置数据有哪些比较需要注意的呢? 大概有底下这几个:

    • rp_filter:称为逆向路径过滤 (Reverse Path Filtering), 可以借由分析网络接口的路由信息配合封包的来源地址,来分析该封包是否为合理。举例来说,你有两张网卡,eth0 为 192.168.1.10/24 ,eth1 为 public IP 。那么当有一个封包自称来自 eth1 ,但是其 IP 来源为 192.168.1.200 , 那这个封包就不合理,应予以丢弃。这个设置值建议可以启动的。

    • log_martians:这个设置数据可以用来启动记录不合法的 IP 来源, 举例来说,包括来源为 0.0.0.0、127.x.x.x、及 Class E 的 IP 来源,因为这些来源的 IP 不应该应用于 Internet 啊。 记录的数据缺省放置到内核放置的注册表 /var/log/messages。

    • accept_source_route:或许某些路由器会启动这个设置值, 不过目前的设备很少使用到这种来源路由,你可以取消这个设置值。

    • accept_redirects:当你在同一个实体网域内架设一部路由器, 但这个实体网域有两个 IP 网域,例如 192.168.0.0/24, 192.168.1.0/24。此时你的 192.168.0.100 想要向 192.168.1.100 发送消息时,路由器可能会发送一个 ICMP redirect 封包告知 192.168.0.100 直接发送数据给 192.168.1.100 即可,而不需通过路由器。因为 192.168.0.100 与 192.168.1.100确实是在同一个实体线路上 (两者可以直接互通),所以路由器会告知来源 IP 使用最短路径去传递数据。但那两部主机在不同的 IP 段,却是无法实际传递消息的!这个设置也可能会产生一些轻微的安全风险,所以建议关闭他。

    • send_redirects:与上一个类似,只是此值为发送一个 ICMP redirect 封包。 同样建议关闭。(事实上,鸟哥就曾经为了这个 ICMP redirect 的问题伤脑筋!其实关闭 redirect 的这两个项目即可啊!)

    虽然你可以使用『 echo "1" > /proc/sys/net/ipv4/conf/???/rp_filter 』之类的方法来启动这个项目,不过, 鸟哥比较建议修改系统设置值,那就是 /etc/sysctl.conf 这个文件!假设我们仅有 eth0 这个乙太接口,而且上述的功能要通通启动, 那你可以这样做:
    [root@www ~]# vim /etc/sysctl.conf
    # Adding by VBird 2011/01/28
    net.ipv4.tcp_syncookies = 1
    net.ipv4.icmp_echo_ignore_broadcasts = 1
    net.ipv4.conf.all.rp_filter = 1
    net.ipv4.conf.default.rp_filter = 1
    net.ipv4.conf.eth0.rp_filter = 1
    net.ipv4.conf.lo.rp_filter = 1
    ....(以下省略)....
    
    [root@www ~]# sysctl -p
    

9.4 单机防火墙的一个实例

介绍了这么多的防火墙语法与相关的注意事项后,终于要来架设防火墙了。鸟哥还是比较偏好使用脚本来撰写防火墙, 然后通过最终的 /etc/init.d/iptables save 来将结果保存到 /etc/sysconfig/iptables 去! 而且此一特色还可以用在调用其他的 scripts ,可以让防火墙规则具有较为灵活的使用方式。 好了,那就来谈谈如何设置咱们的防火墙规则吧!


9.4.1 规则草拟

鸟哥底下介绍的这个防火墙,其实可以用来作为路由器上的防火墙,也可以用来作为本机的防火墙。 假设硬件连接如同下图所示, Linux 主机本身也是内部 LAN 的路由器!亦即是一个简单的 IP 分享器的功能啦!假设鸟哥网络接口有底下这些:

  • 外部网络使用 eth1 (如果是拨接,有可能是 ppp0,请针对你的环境来设置);
  • 内部网络使用 eth0 ,且内部使用 192.168.1.0/24 这个 Class ;
  • 主机缺省开放的服务有 WWW, SSH, https 等等;
一个局域网路的路由器架构示意图
图 9.4-1、一个局域网路的路由器架构示意图

由于希望将信任网域 (LAN) 与不信任网域 (Internet) 整个分开的完整一点, 所以希望你可以在 Linux 上面安装两块以上的实体网卡,将两块网卡接在不同的网域,这样可以避免很多问题。 至于最重要的防火墙政策是:『关闭所有的连接,仅开放特定的服务』模式。 而且假设内部用户已经受过良好的训练,因此在 filter table 的三条链个缺省政策是:

  • INPUT 为 DROP
  • OUTPUT 及 FORWARD 为 ACCEPT

鸟哥底下预计提供的防火墙流程是这样的:

本机的防火墙规则流程示意图
图 9.4-2、本机的防火墙规则流程示意图

原则上,内部 LAN 主机与主机本身的开放度很高,因为 Output 与 Forward 是完全开放不理的!对于小家庭的主机是可以接受的,因为我们内部的电脑数量不多,而且人员都是熟悉的, 所以不需要特别加以控管!但是:『在大企业的内部,这样的规划是很不合格的, 因为你不能保证内部所有的人都可以按照你的规定来使用 Network !』也就是说『家贼难防』呀! 因此,那样的环境连 Output 与 Forward 都需要特别加以管理才行!

9.4.2 实际设置

事实上,我们在设置防火墙的时候,不太可能会一个一个指令的输入,通常是利用 shell scripts 来帮我们达成这样的功能呐!底下是利用上面的流程图所规划出来的防火墙脚本,你可以参考看看, 但是你需要将环境修改成适合你自己的环境才行喔!此外,为了未来修改维护的方便,鸟哥将整个 script 拆成三部分,分别是:

  • iptables.rule:设置最基本的规则,包括清除防火墙规则、加载模块、设置服务可接受等;
  • iptables.deny:设置抵挡某些恶意主机的进入;
  • iptables.allow:设置允许某些自订的后门来源主机!

鸟哥个人习惯是将这个脚本放置到 /usr/local/virus/iptables 目录下,你也可以自行放置到自己习惯的位置去。 那底下就来瞧瞧这支脚本是怎么写的吧!

[root@www ~]# mkdir -p /usr/local/virus/iptables
[root@www ~]# cd /usr/local/virus/iptables
[root@www iptables]# vim iptables.rule
#!/bin/bash

# 请先输入您的相关参数,不要输入错误了!
  EXTIF="eth1"           # 这个是可以连上 Public IP 的网络接口
  INIF="eth0"            # 内部 LAN 的连接接口;若无则写成 INIF=""
  INNET="192.168.1.0/24" # 若无内部网域接口,请填写成 INNET=""
  export EXTIF INIF INNET

# 第一部份,针对本机的防火墙设置!##########################################
# 1. 先设置好内核的网络功能:
  echo "1" > /proc/sys/net/ipv4/tcp_syncookies
  echo "1" > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts
  for i in /proc/sys/net/ipv4/conf/*/{rp_filter,log_martians}; do
        echo "1" > $i
  done
  for i in /proc/sys/net/ipv4/conf/*/{,accept_source_route,accept_redirects,\
send_redirects}; do
        echo "0" > $i
  done

# 2. 清除规则、设置缺省政策及开放 lo 与相关的设置值
  PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/sbin:/usr/local/bin; export PATH
  iptables -F
  iptables -X
  iptables -Z
  iptables -P INPUT   DROP
  iptables -P OUTPUT  ACCEPT
  iptables -P FORWARD ACCEPT
  iptables -A INPUT -i lo -j ACCEPT
  iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT

# 3. 启动额外的防火墙 script 模块
  if [ -f /usr/local/virus/iptables/iptables.deny ]; then
        sh /usr/local/virus/iptables/iptables.deny
  fi
  if [ -f /usr/local/virus/iptables/iptables.allow ]; then
        sh /usr/local/virus/iptables/iptables.allow
  fi
  if [ -f /usr/local/virus/httpd-err/iptables.http ]; then
        sh /usr/local/virus/httpd-err/iptables.http
  fi

# 4. 允许某些类型的 ICMP 封包进入
  AICMP="0 3 3/4 4 11 12 14 16 18"
  for tyicmp in $AICMP
  do
    iptables -A INPUT -i $EXTIF -p icmp --icmp-type $tyicmp -j ACCEPT
  done

# 5. 允许某些服务的进入,请依照你自己的环境打开
# iptables -A INPUT -p TCP -i $EXTIF --dport  21 --sport 1024:65534 -j ACCEPT # FTP
# iptables -A INPUT -p TCP -i $EXTIF --dport  22 --sport 1024:65534 -j ACCEPT # SSH
# iptables -A INPUT -p TCP -i $EXTIF --dport  25 --sport 1024:65534 -j ACCEPT # SMTP
# iptables -A INPUT -p UDP -i $EXTIF --dport  53 --sport 1024:65534 -j ACCEPT # DNS
# iptables -A INPUT -p TCP -i $EXTIF --dport  53 --sport 1024:65534 -j ACCEPT # DNS
# iptables -A INPUT -p TCP -i $EXTIF --dport  80 --sport 1024:65534 -j ACCEPT # WWW
# iptables -A INPUT -p TCP -i $EXTIF --dport 110 --sport 1024:65534 -j ACCEPT # POP3
# iptables -A INPUT -p TCP -i $EXTIF --dport 443 --sport 1024:65534 -j ACCEPT # HTTPS


# 第二部份,针对后端主机的防火墙设置!###############################
# 1. 先加载一些有用的模块
  modules="ip_tables iptable_nat ip_nat_ftp ip_nat_irc ip_conntrack 
ip_conntrack_ftp ip_conntrack_irc"
  for mod in $modules
  do
      testmod=`lsmod | grep "^${mod} " | awk '{print $1}'`
      if [ "$testmod" == "" ]; then
            modprobe $mod
      fi
  done

# 2. 清除 NAT table 的规则吧!
  iptables -F -t nat
  iptables -X -t nat
  iptables -Z -t nat
  iptables -t nat -P PREROUTING  ACCEPT
  iptables -t nat -P POSTROUTING ACCEPT
  iptables -t nat -P OUTPUT      ACCEPT

# 3. 开放成为路由器,且为 IP 分享器!
  if [ "$INIF" != "" ]; then
    iptables -A INPUT -i $INIF -j ACCEPT
    echo "1" > /proc/sys/net/ipv4/ip_forward
    if [ "$INNET" != "" ]; then
        for innet in $INNET
        do
            iptables -t nat -A POSTROUTING -s $innet -o $EXTIF -j MASQUERADE
        done
    fi
  fi
  # 如果你的 MSN 一直无法连接,或者是某些网站 OK 某些网站不 OK,
  # 可能是 MTU 的问题,那你可以将底下这一行给他取消注解来启动 MTU 限制范围
  # iptables -A FORWARD -p tcp -m tcp --tcp-flags SYN,RST SYN -m tcpmss \
  #          --mss 1400:1536 -j TCPMSS --clamp-mss-to-pmtu

# 4. NAT 服务器后端的 LAN 内对外之服务器设置
# iptables -t nat -A PREROUTING -p tcp -i $EXTIF --dport 80 \
#          -j DNAT --to-destination 192.168.1.210:80 # WWW

# 5. 特殊的功能,包括 Windows 远程桌面所产生的规则,假设桌面主机为 1.2.3.4
# iptables -t nat -A PREROUTING -p tcp -s 1.2.3.4  --dport 6000 \
#          -j DNAT --to-destination 192.168.1.100
# iptables -t nat -A PREROUTING -p tcp -s 1.2.3.4  --sport 3389 \
#          -j DNAT --to-destination 192.168.1.100

# 6. 最终将这些功能保存下来吧!
  /etc/init.d/iptables save

特别留意上面代码的特殊字体部分,基本上,你只要修改一下最上方的接口部分, 应该就能够运作这个防火墙了。不过因为每个人的环境都不相同, 因此你在设置完成后,依旧需要测试一下才行喔!不然,出了问题不要怪我啊!.... 再来看一下关于 iptables.allow 的内容是如何?假如我要让一个 140.116.44.0/24 这个网域的所有主机来源可以进入我的主机的话,那么这个文件的内容可以写成这样:

[root@www iptables]# vim iptables.allow
#!/bin/bash
# 底下则填写你允许进入本机的其他网域或主机啊!
  iptables -A INPUT -i $EXTIF -s 140.116.44.0/24 -j ACCEPT

# 底下则是关于抵挡的文件设置法!
[root@www iptables]# vim iptables.deny
#!/bin/bash
# 底下填写的是『你要抵挡的那个咚咚!』
  iptables -A INPUT -i $EXTIF -s 140.116.44.254 -j DROP

[root@www iptables]# chmod 700 iptables.*

将这三个文件的权限设置为 700 且只属于 root 的权限后,就能够直接运行 iptables.rule 啰! 不过要注意的是,在上面的案例当中,鸟哥缺省将所有的服务的信道都是关闭的! 所以你必须要到本机防火墙的第 5 步骤处将一些注解符号 (#) 解开才行。 同样的,如果有其他更多的 port 想要打开时,一样需要增加额外的规则才行喔!

不过,还是如同前面我们所说的,这个 firewall 仅能提供基本的安全防护,其他的相关问题还需要再测试测试呢! 此外,如果你希望一开机就自动运行这个 script 的话,请将这个文件的完整文件名写入 /etc/rc.d/rc.local 当中,有点像底下这样:

[root@www ~]# vim /etc/rc.d/rc.local
....(其他省略)....
# 1. Firewall
/usr/local/virus/iptables/iptables.rule

事实上,这个脚本的最底下已经加入写入防火墙缺省规则档的功能,所以你只要运行一次,就拥有最正确的规则了! 上述的 rc.local 仅是预防万一而已。 ^_^!上述三个文件请你不要在 Windows 系统上面编辑后才发送到 Linux 上运作,因为 Windows 系统的断行字符问题,将可能导致该文件无法运行。建议你直接到底下去下载,发送到 Linux 后可以利用 dos2unix 指令去转换断行字符!就不会有问题!

这就是一个最简单、阳春的防火墙。同时,这个防火墙还可以具有最阳春的 IP 分享器的功能呢! 也就是在 iptables.rule 这个文件当中的第二部分了。 这部分我们在下一节会再继续介绍的。

9.5 NAT 服务器的设置

呼呼!终于来到这个地方了!我们准备要架设一个路由器的延伸服务器,就称之为 NAT 服务器。 NAT 是什么呢?简单的说,你可以称他为内部 LAN 主机的『 IP 分享器』啦!

NAT 的全名是 Network Address Translation,字面上的意思是『网络地址的转换』。由字面上的意思我们来想一想, TCP/IP 的网络封包不是有 IP 地址吗?那 IP 地址不是有来源与目的吗?我们的 iptables 指令就能够修改 IP 封包的表头数据, 嘿嘿!连目标或来源的 IP 地址都可以修改呢!甚至连 TCP 封包表头的 port number 也能修改!真是有趣!

NAT 服务器的功能可以达到类似图 9.1-2所介绍的类似 IP 分享的功能之外, 还可以达到类似图 9.1-4所介绍的 DMZ (非军事区) 的功能!这完全取决于我们的 NAT 是修改: (1)来源 IP 还是 (2)目标 IP !底下我们就来聊一聊吧! ^_^


9.5.1 什么是 NAT? SNAT? DNAT?

在谈到 NAT 的实际运作之前,让我们再来看一下比较简单的封包通过 iptables 而发送到后端主机的表格与链流程(请往前参考图 9.3-4)。 当网络布线如图 9.1-2的架构,若内部 LAN 有任何一部主机想要发送封包出去时, 那么这个封包要如何通过 Linux 主机而发送出去?他是这样的:

  1. 先经过 NAT table 的 PREROUTING 链;
  2. 经由路由判断确定这个封包是要进入本机与否,若不进入本机,则下一步;
  3. 再经过 Filter table 的 FORWARD 链;
  4. 通过 NAT table 的 POSTROUTING 链,最后发送出去。

NAT 服务器的重点就在于上面流程的第 1,4 步骤,也就是 NAT table 的两条重要的链:PREROUTING 与 POSTROUTING。 那这两条链有什么重要的功能呢?重点在于修改 IP 嘛!但是这两条链修改的 IP 是不一样的! POSTROUTING 在修改来源 IP ,PREROUTING 则在修改目标 IP 。 由于修改的 IP 不一样,所以就称为来源 NAT (Source NAT, SNAT) 及目标 NAT (Destination NAT, DNAT)。我们先来谈一谈 IP 分享器功能的 SNAT 吧!



  • 来源 NAT, SNAT:修改封包表头的『来源』项目

    你应该有听说过 IP 分享器这个玩意儿,他可以让你家庭里的好几部主机同时通过一条 ADSL 网络连接到 Internet 上面, 例如图 9.1-2连接的方式来说,那个 Linux 主机就是 IP 分享器啦!那么他是如何达到 IP 分享的功能?就是通过 NAT 表格的 POSTROUTING 来处理的。假设你的网络布线如图 9.1-2所示, 那么 NAT 服务器是如何处理这个封包的呢?

    SNAT 封包发送出去的示意图
    图 9.5-1、SNAT 封包发送出去的示意图

    如上图所示,在用户端 192.168.1.100 这部主机要连接到 http://tw.yahoo.com 去时,他的封包表头会如何变化?

    1. 用户端所发出的封包表头中,来源会是 192.168.1.100 ,然后发送到 NAT 这部主机;
    2. NAT 这部主机的内部接口 (192.168.1.2) 接收到这个封包后,会主动分析表头数据, 因为表头数据显示目的并非 Linux 本机,所以开始经过路由, 将此封包转到可以连接到 Internet 的 Public IP 处;
    3. 由于 private IP 与 public IP 不能互通,所以 Linux 主机通过 iptables 的 NAT table 内的 Postrouting 链将封包表头的来源伪装成为 Linux 的 Public IP ,并且将两个不同来源 (192.168.1.100 及 public IP) 的封包对应写入暂存内存当中, 然后将此封包发送出去了

    此时 Internet 上面看到这个封包时,都只会知道这个封包来自那个 Public IP 而不知道其实是来自内部啦。 好了,那么如果 Internet 回传封包呢?又会怎么作?

    SNAT 封包接收的示意图
    图 9.5-2、SNAT 封包接收的示意图

    1. 在 Internet 上面的主机接到这个封包时,会将回应数据发送给那个 Public IP 的主机;
    2. 当 Linux NAT 服务器收到来自 Internet 的回应封包后,会分析该封包的序号,并比对刚刚记录到内存当中的数据, 由于发现该封包为后端主机之前发送出去的,因此在 NAT Prerouting 链中,会将目标 IP 修改成为后端主机,亦即那部 192.168.1.100,然后发现目标已经不是本机 (public IP), 所以开始通过路由分析封包流向
    3. 封包会发送到 192.168.1.2 这个内部接口,然后再发送到最终目标 192.168.1.100 机器上去!

    经过这个流程,你就可以发现到,所有内部 LAN 的主机都可以通过这部 NAT 服务器连接出去, 而大家在 Internet 上面看到的都是同一个 IP (就是 NAT 那部主机的 public IP 啦!), 所以,如果内部 LAN 主机没有连上不明网站的话,那么内部主机其实是具有一定程度的安全性的啦! 因为 Internet 上的其他主机没有办法主动攻击你的 LAN 内的 PC 嘛!所以我们才会说, NAT 最简单的功能就是类似 IP 分享器啦!那也是 SNAT 的一种。
    Tips 鸟哥 NAT 服务器与路由器有啥不同?基本上,NAT 服务器一定是路由器,不过, NAT 服务器由于会修改 IP 表头数据, 因此与单纯转递封包的路由器不同。最常见的 IP 分享器就是一个路由器,但是这个 IP 分享器一定会有一个 Public IP 与一个 Private IP,让 LAN 内的 Private IP 可以通过 IP 分享器的 Public IP 发送出去喔! 至于路由器通常两边都是 Public IP 或同时为 Private IP。

  • 目标 NAT, DNAT:修改封包表头的『目标』项目

    SNAT 主要是应付内部 LAN 连接到 Internet 的使用方式,至于 DNAT 则主要用在内部主机想要架设可以让 Internet 访问的服务器啦! 就有点类似图 9.1-4的 DMZ 内的服务器啊!底下也先来谈一谈 DNAT 的运作吧!

    DNAT 的封包发送示意图
    图 9.5-3、DNAT 的封包发送示意图

    如上图所示,假设我的内部主机 192.168.1.210 启动了 WWW 服务,这个服务的 port 打开在 port 80 , 那么 Internet 上面的主机 (61.xx.xx.xx) 要如何连接到我的内部服务器呢?当然啦, 还是得要通过 Linux NAT 服务器嘛!所以这部 Internet 上面的机器必须要连接到我们的 NAT 的 public IP 才行。

    1. 外部主机想要连接到目的端的 WWW 服务,则必须要连接到我们的 NAT 服务器上头;
    2. 我们的 NAT 服务器已经设置好要分析出 port 80 的封包,所以当 NAT 服务器接到这个封包后, 会将目标 IP 由 public IP 改成 192.168.1.210 ,且将该封包相关信息记录下来,等待内部服务器的回应;
    3. 上述的封包在经过路由后,来到 private 接口处,然后通过内部的 LAN 发送到 192.168.1.210 上头!
    4. 192.186.1.210 会回应数据给 61.xx.xx.xx ,这个回应当然会发送到 192.168.1.2 上头去;
    5. 经过路由判断后,来到 NAT Postrouting 的链,然后通过刚刚第二步骤的记录,将来源 IP 由 192.168.1.210 改为 public IP 后,就可以发送出去了!

    其实整个步骤几乎就等于 SNAT 的反向发送哩!这就是 DNAT 啰!很简单吧!

9.5.2 最阳春 NAT 服务器: IP 分享功能

在 Linux 的 NAT 服务器服务当中,最常见的就是类似图 9.1-2的 IP 分享器功能了。 而由刚刚的介绍你也该知道,这个 IP 分享器的功能其实就是 SNAT 啦!作用就只是在 iptables 内的 NAT 表格当中,那个路由后的 POSTROUTING 链进行 IP 的伪装就是了。另外, 你也必须要了解,你的 NAT 服务器必须要有一个 public IP 接口,以及一个内部 LAN 连接的 private IP 接口才行。底下的范例中,鸟哥的假设是这样的:

  • 外部接口使用 eth1 ,这个接口具有 public IP 喔;
  • 内部接口使用 eth0 ,假设这个 IP 为 192.168.1.2 ;

记住!当你利用前面几章谈到的数据来设置你的网络参数后,务必要进行路由的检测, 因为在 NAT 服务器的设置方面,最容易出错的地方就是路由了!尤其是在拨接产生 ppp0 这个对外接口的环境下, 这个问题最严重。反正你要记得:『如果你的 public IP 取得的方式是拨接或 cable modem 时,你的设置档 /etc/sysconfig/network, ifcfg-eth0, ifcfg-eth1 等文件,千万不要设置 GATEWAY 啦!』否则就会出现两个 default gateway ,反而会造成问题。

如果你刚刚已经下载了 iptables.rule ,那么该文件内已经含有 NAT 的脚本了! 你可以看到该文件的第二部份关于 NAT 服务器的部分,应该有看到底下这几行:

iptables -A INPUT -i $INIF -j ACCEPT
# 这一行为非必要的,主要的目的是让内网 LAN 能够完全的使用 NAT 服务器资源。
# 其中 $INIF 在本例中为 eth0 接口

echo "1" > /proc/sys/net/ipv4/ip_forward
# 上头这一行则是在让你的 Linux 具有 router 的能力

iptables -t nat -A POSTROUTING -s $innet -o $EXTIF -j MASQUERADE
# 这一行最关键!就是加入 nat table 封包伪装!本例中 $innet 是 192.168.1.0/24
# 而 $EXTIF 则是对外接口,本例中为 eth1 

重点在那个『 MASQUERADE 』!这个设置值就是『 IP 伪装成为封包出去 (-o) 的那块设备上的 IP 』!以上面的例子来说,就是 $EXTIF ,也就是 eth1 啦! 所以封包来源只要来自 $innet (也就是内部 LAN 的其他主机) ,只要该封包可通过 eth1 发送出去, 那就会自动的修改 IP 的来源表头成为 eth1 的 public IP 啦!就这么简单! 你只要将 iptables.rule 下载后,并设置好你的内、外网络接口, 运行 iptables.rule 后,你的 Linux 就拥有主机防火墙以及 NAT 服务器的功能了!

例题:
如同上面所述的案例,那么你的 LAN 内的其他 PC 应该要如何设置相关的网络参数?
答:
答案其实很简单啊,将 NAT 服务器作为 PC 的 GATEWAY 即可!只要记得底下的参数值:
  • NETWORK 为 192.168.1.0
  • NETMASK 为 255.255.255.0
  • BROADCAST 为 192.168.1.255
  • IP 可以设置 192.168.1.1 ~ 192.168.1.254 间,不可重复!
  • 通信闸 (Gateway) 需要设置为 192.168.1.2 (NAT 服务器的 Private IP)
  • DNS (/etc/resolv.conf) 需设置为 168.95.1.1 (Hinet) 或 139.175.10.20 (Seed Net), 这个请依你的 ISP 而定;

事实上,除了 IP 伪装 (MASQUERADE) 之外,我们还可以直接指定修改 IP 封包表头的来源 IP 呢! 举例来说,如下面这个例子:

例题:
假设对外的 IP 固定为 192.168.200.250 ,若不想使用伪装,该如何处理?
答:
iptables -t nat -A POSTROUTING -o eth1 -j SNAT \
         --to-source 192.168.200.250

例题:
假设你的 NAT 服务器对外 IP 有好几个,那你想要轮流使用不同的 IP 时,又该如何设置?举例来说,你的 IP 范围为 192.168.200.210~192.168.200.220
答:
iptables -t nat -A POSTROUTING -o eth1 -j SNAT \
         --to-source 192.168.200.210-192.168.200.220

这样也可以修改网络封包的来源 IP 数据喔!不过,除非你使用的是固定 IP ,且有多个 IP 可以对外连接,否则一般使用 IP 伪装即可,不需要使用到这个 SNAT 啦!当然,你也可能有自己的独特的环境啦! ^_^

9.5.3 iptables 的额外内核模块功能

如果你刚刚在 iptables.rule 内的第二部分有仔细看的话, 那有没有觉得很奇怪,为何我们需要加载一些有用的模块?举例来说, ip_nat_ftp 及 ip_nat_irc ? 这是因为很多通信协定使用的封包传输比较特殊,尤其是 FTP 文件传输使用到两个 port 来处理数据! 这个部分我们会在 FTP 章节再来详谈,在这里你要先知道,我们的 iptables 提供很多好用的模块, 这些模块可以辅助封包的过滤用途,让我们可以节省很多 iptables 的规则拟定,好棒的呐! ^_^

9.5.4 在防火墙后端之网络服务器 DNAT 设置

既然可以做 SNAT 的 IP 分享功能,我们当然可以使用 iptables 做出 DMZ 啦! 但是再次重申,不同的服务器封包传输的方式可能有点差异,因此,建议新手不要玩这个咚咚! 否则很容易导致某些服务无法顺利对 Internet 提供的问题。

先来谈一谈,如果我想要处理 DNAT 的功能时, iptables 要如何下达指令? 另外,你必须要知道的是, DNAT 用到的是 nat table 的 Prerouting 链喔!不要搞错了。

例题:
假设内网有部主机 IP 为 192.168.1.210 ,该主机是可对 Internet 开放的 WWW 服务器。你该如何通过 NAT 机制,将 WWW 封包传到该主机上?
答:
假设 public IP 所在的接口为 eth1 ,那么你的规则就是:
iptables -t nat -A PREROUTING -i eth1 -p tcp --dport 80 \
     -j DNAT --to-destination 192.168.1.210:80 

那个『 -j DNAT --to-destination IP[:port] 』就是精髓啦!代表从 eth1 这个接口传入的,且想要使用 port 80 的服务时, 将该封包重新传导到 192.168.1.210:80 的 IP 及 port 上面!可以同时修改 IP 与 port 呢!真方便。 其他还有一些较高端的 iptables 使用方式,如下所示:

-j REDIRECT --to-ports <port number>
# 这个也挺常见的,基本上,就是进行本机上面 port 的转换就是了!
# 不过,特别留意的是,这个动作仅能够在 nat table 的 PREROUTING 以及
# OUTPUT 链上面实行而已喔!

范例:将要求与 80 连接的封包转递到 8080 这个 port
[root@www ~]# iptables -t nat -A PREROUTING -p tcp  --dport 80 \
> -j REDIRECT --to-ports 8080
# 这玩意最容易在你使用了非正规的 port 来进行某些 well known 的协定,
# 例如使用 8080 这个 port 来启动 WWW ,但是别人都以 port 80 来连接,
# 所以,你就可以使用上面的方式来将对方对你主机的连接传递到 8080 啰!

至于更多的用途,那就有待你自己的发掘啰! ^_^

9.6 重点回顾

  • 要拥有一部安全的主机,必须要有良好的主机权限设置;随时的更新套件;定期的重要数据备份;完善的员工教育训练。 仅有防火墙是不足够的;
  • 防火墙最大的功能就是帮助你『限制某些服务的访问来源』,可以管制来源与目标的 IP ;
  • 防火墙依据封包抵挡的阶层,可以分为 Proxy 以及 IP Filter (封包过滤) 两种类型;
  • 在防火墙内,但不在 LAN 内的服务器所在网域,通常被称为 DMZ (非军事区),如图 9.1-4所示;
  • 封包过滤机制的防火墙,通常至少可以分析 IP, port, flag (如 TCP 封包的 SYN), MAC 等等;
  • 防火墙对于病毒的抵挡并不敏感;
  • 防火墙对于来自内部的网络误用或滥用的抵挡性可能较不足;
  • 并不是架设防火墙之后,系统就一定很安全!还是需要更新套件漏洞以及管制用户及权限设置等;
  • 内核 2.4 以后的 Linux 使用 iptables 作为防火墙的软件;
  • 防火墙的订定与『规则顺序』有很大的关系;若规则顺序错误,可能会导致防火墙的失效;
  • iptables 的缺省 table 共有三个,分别是 filter, nat 及 mangle ,惯用者为 filter (本机) 与 nat (后端主机)。
  • filter table 主要为针对本机的防火墙设置,依据封包流向又分为 INPUT, OUTPUT, FORWARD 三条链;
  • nat table 主要针对防火墙的后端主机,依据封包流向又分为 PREROUTING, OUTPUT, POSTROUTING 三条链, 其中 PREROUTING 与 DNAT 有关, POSTROUTING 则与 SNAT 有关;
  • iptables 的防火墙为规则比对,但所有规则都不符合时,则以缺省政策 (policy) 作为封包的行为依据;
  • iptables 的指令列当中,可以下达的参数相当的多,当下达 -j LOG 的参数时,则该封包的流程会被纪录到 /var/log/messages 当中;
  • 防火墙可以多重设置,例如虽然已经设置了 iptables ,但是仍然可以持续设置 TCP Wrappers ,因为谁也不晓得什么时候 iptables 会有漏洞~或者是规则规划不良!

9.7 本章习题

  • 为什么我架设了防火墙,我的主机还是可能中毒?
    防火墙不是万灵丹,他还是可能被病毒或者是木马程序所入侵的! 此外,如果你的主机本身就已经提供了多个网络服务,则当该网络服务的软件有漏洞时, 防火墙仍然无法克服该服务的漏洞的!因此仍然需要持续的进行主机的监视与后端分析工作
  • 请说明为何架设了防火墙,我的主机还是可能被入侵?入侵的依据可能是什么方法?
    因为防火墙仅是抵挡某些不受欢迎的封包,如果你有开放 WWW 的服务时,则要求你主机 port 80 的封包将可直接进入你的主机,万一 WWW 套件有漏洞时,那么就可能被入侵了!所以软件的更新很重要!
  • 我们知道内核为 2.4 的 Linux 使用的防火墙机制为 iptables ,请问,如何知道我的 Linux 内核版本?
    利用 uname -r 可以查得!
  • 请列出 iptables 缺省的两个主要的 table ,以及各个 table 里面的 chains 与各个 chains 所代表的意义;
    filter 为缺省的 Table,里头缺省的链有:
    • INPUT:为来自外部,想要进入主机的封包;
    • OUTPUT:为来自主机,想要离开主机的封包;
    • FORWARD:为主机内部网域与外部网域的封包(不论进或者出),但该封包不会进入主机。
    还有 nat 这个 table:
    • PREROUTING:进行路由之前的封包发送过程
    • OUTPUT:离开主机的封包发送过程;
    • POSTROUTING:已经经过路由了,然后才进行的过滤规则。
  • 什么是 iptables 的缺省政策 (Policy)?若我要针对 filter 的 INPUT 做成 DROP 的缺省政策,指令如何下达?
    当封包的所有属性都不在防火墙的规则当中时,那么这个封包能否顺利的通过防火墙,则以 Policy 作为这个封包的最终动作了!
    iptables -P INPUT DROP
  • 假设今天我的 Linux 仅是作为 Client 之用,并没有对 Internet 进行任何服务, 那么你的防火墙规划应该如何设置比较好?
    既然没有对 Internet 提供任何服务,那么(1)请将所有的对外端口口先关闭吧!(2)防火墙规则当中,最重要的是 INPUT 的 Policy 一定要 DROP ,然后将『 iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT 』即可!
  • 我要将来自 192.168.1.50 这个 IP 来源的封包,只要是向我的 21~23 端口口要求的封包,就将他抵挡,应该如何下达 iptables 指令?
    iptables -A INPUT -p tcp -s 192.168.1.50 --dport 21:23 -j DROP
  • 我要将我自己主机 ping 的回应功能取消,应该如何下达 iptables 的指令?
    因为 ping 能否回应用的是 icmp 的 type 8 (请参考网络基础内的 ICMP 相关内容),所以我可以这样做:
    iptables -I INPUT -p icmp --icmp-type 8 -j DROP
  • 请说明为何这个指令是错误的?『iptables -A INPUT -p udp --syn -s 192.168.0.20 -j DROP』?
    因为只有 TCP 封包才会具有 SYN 的标志, UDP 并没有 SYN 的标志啊!所以上面的指令是错误的
  • DNS 的要求是必须的,那么我该如何设置我的主机可以接受要求 DNS 的回应呢?
    因为 DNS 的来源是 port 53 ,因此要接受来自 port 53 的封包就成为了:
    iptables -A INPUT -p udp --sport 53 -j ACCEPT
    iptables -A INPUT -p tcp --sport 53 -j ACCEPT
  • 如何取消 iptables 在我的系统上面?
    先要清除规则后,才能够将 iptables 移除!不过,我们主要将规则清除即可!
    iptables -F; iptables -X; iptables -Z
    iptables -t nat -F; iptables -t nat -X; iptables -t nat -Z
  • 如何保存目前的防火墙机制,以及如何将上次保存下来的机制回复到目前的系统中?
    请利用 iptables-save 以及 iptables-restore 这两个指令,配合命令重导向即可! 也可以使用 /etc/init.d/iptables save 来保存喔!
  • 如果你的区网当中有个 PC 用户老是连上 Internet 乱搞,你想要将他的 IP 锁住,但他总是有办法修改成其他 IP 来连外, 那你该怎么办?让他无法继续连外?
    可以利用封锁网络卡卡号 MAC 来处理!

9.8 参考数据与延伸阅读

修改历史:
2002/08/20:第一次完成日期!
2003/08/25:重新设计内容,改写一些指令介绍,与前一篇『认识网络安全』 分的比较完整一点!
2006/09/06:将旧的文章移动到此处
2006/09/11:拿掉了已经在基础篇有介绍过的 认识服务之 TCP Wrappers
2006/09/13:加入 NAT 的说明了,将旧的 NAT 主机移动到 此处
2006/09/15:将 iptables.rule 的链接粘贴去了!之前忘记修改该文件了~
2006/11/08:因为 PPPoE 拨接与 Ethernet 的 MTU 不同,可能在某些情况下会导致用户无法连接,更新了 iptables.rule 了。
2010/10/27:将旧的基于 CentOS 4.x 的版本移动到此处
2011/02/08:修改了很多图标,并且将文句作个整理,大方向并没有特殊的修改!
其他链接
环境工程模式篇
鸟园讨论区
鸟哥旧站

今日 人数统计
昨日 人数统计
本月 人数统计
上月 人数统计