免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 4326 | 回复: 3
打印 上一主题 下一主题

Linux 防火墙与 NAT 主机(轉自鸟哥的 Linux 私房菜) [复制链接]

论坛徽章:
0
1 [报告]
发表于 2006-09-21 11:54 |只看该作者
--------------------------------------------------------------------------------
Linux 的封包过滤机制:iptables

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


--------------------------------------------------------------------------------
不同 Linux 核心版本的防火墙软体

Linux 的防火墙為什麼功能这麼好?这是因為他本身就是由 Linux kernel 所提供, 由於直接经过核心来处理,因此效能非常好!不过,不同核心版本所使用的防火墙软体是不一样的! 因為核心支援的防火墙是逐渐演进来的嘛!

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 版的核心啊! ^_^



--------------------------------------------------------------------------------
iptables 的表格与封包进入流程

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

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



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


当一个网路封包要进入到主机之前,会先经由 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 的封包都给他丢弃,就这三个规则来说,您要如何设定防火墙检验顺序呢?

Rule 1 先抵挡 192.168.100.100 ;
Rule 2 再让要求 WWW 服务的封包通过;
Rule 3 将所有的封包丢弃。
这样的排列顺序就能符合您的需求,不过,万一您的顺序排错了,变成:

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


--------------------------------------------------------------------------------

iptables 的表格与链 (chain)

事实上,那个图五所列出的规则仅是 iptables 眾多表格当中的一个链 (chain) 而已。 什麼是链呢?这得由 iptables 的名称说起。為什麼称為 ip"tables" 呢? 因為这个防火墙软体裡面有多个表格 (table) ,每个表格都定义出自己的预设政策与规则, 且每个表格都用途都不相同。我们可以使用底下这张图来稍微瞭解一下:



图六、iptables 的表格示意图


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

filter:主要跟 Linux 本机有关,这个是预设的 table 喔!
INPUT:主要与封包想要进入我们 Linux 本机有关;
OUTPUT:主要与我们 Linux 本机所要送出的封包有关;
FORWARD:这个咚咚与 Linux 本机比较没有关係,他可以封包『转递』到后端的电脑中,与 nat 这个 table 相关性很高。


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


mangle:这个表格主要是与特殊的封包的路由旗标有关, 早期仅有 PREROUTING 及 OUTPUT 链,不过从 kernel 2.4.18 之后加入了 INPUT 及 FORWARD 链。 由於这个表格与特殊旗标相关性较高,所以像咱们这种单纯的环境当中,较少使用 mangle 这个表格。
那麼各个表格与链的相关性可以使用下图来表示:



图七、iptables 内建各表格与链的相关性


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

如上图的 A ,封包主要是要读取我们 Linux 本机内的资料,会经过 filter 的 INPUT 链, 而资料的输出则是经过 filter 的 OUTPUT 链;
如上图的 B ,封包主要是要透过防火墙而去后端,也就是说,该封包的目标并非我们的 Linux 本机。 主要经过的链是 filter 的 FORWARD 以及 nat 的 POSTROUTING, PREROUTING。
由於 mangle 这个表格很少被使用,如果将图七的 mangle 拿掉的话,那就容易看的多了:



图八、iptables 内建各表格与链的相关性(简图)


透过图八你就可以更轻鬆的瞭解到,事实上与本机最有关的其实是 filter 这个表格内的 INPUT 与 OUTPUT 这两条链,如果你的 iptables 只是用来防备 Linux 主机本身的话,那 nat 的规则根本就不需要理他,直接设定為开放即可。

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


--------------------------------------------------------------------------------
本机的 iptables 语法

理论上,当你安装好 Linux 之后,系统应该会主动的帮你啟动一个阳春的防火墙规则才是。 不过如果您是依照鸟哥的建议来安装 Linux 时,那麼安装完毕后,你的系统应该是没有防火墙的啦。 另外,某些早期的版本 (例如 Red Hat 9) 本身同时提供 iptables 及 ipchains 这两个防火墙模组, 不过这两个模组是无法同时存在的!所以你仅能啟动其中一个,那当然是啟动 iptables 才对啊! 如果不小心啟动了 ipchains 的话 (新版的 Linux 都不会有这个困扰) ,那请使用 rmmod 来移除吧!

不过,在开始进行底下的练习之前,鸟哥这裡有个很重要的事情要告知一下。 因為 iptables 的指令会将网路封包进行过滤及抵挡的动作,所以 请不要在远端主机上进行防火墙的练习,因為您很有可能一不小心将自己关在家门外! 尽量在本机前面登入 tty1-tty6 终端机进行练习,否则常常会发生悲剧啊! 鸟哥以前刚刚在玩 iptables 时,就常常因為不小心规则设定错误,导致常常要请远端的朋友帮忙重新开机...

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

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


--------------------------------------------------------------------------------

规则的清除与观察

如果你在安装的时候选择没有防火墙的话,那麼 iptables 在一开始的时候应该是没有规则的,不过, 可能因為你在安装的时候就有选择系统自动帮您建立防火墙机制,那系统就会有预设的防火墙规则了! 无论如何,我们先来看看目前本机的防火墙规则是如何吧!
[root@linux ~]# iptables [-t tables] [-L] [-nv]
参数:
-t :后面接 table ,例如 nat 或 filter ,若省略此项目,则使用预设的 filter
-L :列出目前的 table 的规则
-n :不进行 IP 与 HOSTNAME 的反查,显示讯息的速度会快很多!
-v :列出更多的资讯,包括通过该规则的封包总位元数、相关的网路介面等

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

Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

范例:列出更多的资讯
[root@linux ~]# iptables -L -nv
Chain INPUT (policy ACCEPT 5748 packets, 746K bytes)
pkts bytes target     prot opt in     out     source               destination
....底下省略....


仔细看到上面表格的输出,因為没有加上 -t 的参数,所以预设就是 filter 这个表格内的 INPUT, OUTPUT, FORWARD 三条链的规则囉。由於没有规则嘛!所以每个链内部的规则都是空的。 同时注意一下,在每个 chain 后面括号内的 policy 项目,那就是『预设动作(政策)』咯!以上面来看, 虽然我们啟动了 iptables ,但是我们没有设定规则,然后政策又是 ACCEPT, 所以是『任何封包都会接受』的意思喔!至於如果加上 -v 的参数时, 则连同该规则所通过的封包总位元数也会被列出来啊。底下则是 nat 表格的规则项目:
[root@linux ~]# iptables -t nat -L -n
Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination

Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination


瞧!与 fiter 表格一模一样吧!只是三条链的内容不同囉!要注意啊! ^_^! 以后当你设定每一条防火墙的规则时,记得瞧一瞧设定先!好,那如何清除规则?这样做就对了:
[root@linux ~]# iptables [-t tables] [-FXZ]
参数:
-F :清除所有的已订定的规则;
-X :杀掉所有使用者 "自订" 的 chain (应该说的是 tables )囉;
-Z :将所有的 chain 的计数与流量统计都归零

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


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

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



--------------------------------------------------------------------------------

定义预设政策 (policy)

清除规则之后,再接下来就是要设定规则的政策啦!还记得政策指的是什麼吗?『 当您的封包不在您设定的规则之内时,则该封包的通过与否,以 Policy 的设定為準』,在本机方面的预设政策中,假设您对於内部的使用用者有信心的话, 那麼 filter 内的 INPUT 链方面可以定义的比较严格一点,而 FORWARD 与 OUTPUT 则可以订定的鬆一些!通常鸟哥都是将 INPUT 的 policy 定义為 DROP 啦,其他两个则定义為 ACCEPT。 至於 nat table 则暂时不理会他。
[root@linux ~]# iptables [-t nat] -P [INPUT,OUTPUT,FORWARD] [ACCEPT,DROP]
参数:
-P :定义政策( Policy )。注意,这个 P 為大写啊!
ACCEPT :该封包可接受
DROP   :该封包直接丢弃,不会让 client 端知道為何被丢弃。

范例:将本机的 INPUT 设定為 DROP ,其他设定為 ACCEPT
[root@linux ~]# iptables -P   INPUT DROP
[root@linux ~]# iptables -P  OUTPUT ACCEPT
[root@linux ~]# iptables -P FORWARD ACCEPT
[root@linux ~]# iptables -L -n
Chain FORWARD (policy ACCEPT)
target     prot opt source               destination

Chain INPUT (policy DROP)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination
# 由於 INPUT 设定為 DROP 而又尚未有任何规则,所以上面的输出结果显示:
# 所有的封包都无法进入你的主机!是不通的防火墙设定!(网路连线是双向的)


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



--------------------------------------------------------------------------------

封包的基础比对 IP/netmask I/O 装置

开始来进行封包的比对设定吧!我们先由最基础的 IP 与网域的特徵谈起,再谈装置 (网路卡) 的限制等等。
[root@linux ~]# iptables [-AI 链] [-io 网路介面] [-p 协定] \
> [-s 来源IP/网域] [-d 目标IP/网域] -j [ACCEPT|DROP]
参数:
-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) 及记录 (LOG)


iptables 的基本参数就如同上面所示的,仅只谈到 IP 、网域与装置等等的资讯, 至於 TCP, UDP 封包特有的埠口 (port number) 与状态 (如 SYN 旗标) 则在下小节才会谈到。 好,先让我们来看看最基础的几个规则,例如开放 lo 这个本机的介面以及某个 IP 来源吧!
范例一:所有的来自 lo 这个介面的封包,都予以接受
[root@linux ~]# iptables -A INPUT -i lo -j ACCEPT
# 仔细看上面并没有列出 -s, -d 等等的规则,这表示:不论封包来自何处或去到哪裡,
# 只要是来自 lo 这个介面,就予以接受!这个观念挺重要的,就是
#『没有设定的规定,则表示该规定完全接受』的意思!例如这个案例当中,
# 关於 -s, -d...等等的参数没有规定时

范例二:目标来自 192.168.0.1 这个 IP 的封包都予以接受
[root@linux ~]# iptables -A INPUT -i eth0 -s 192.168.0.1 -j ACCEPT
# 不管什麼封包格式,只要来自 192.168.0.1 就予以接受。

范例三:目标来自 192.168.1.0/24 可接受,但 192.168.1.10 丢弃
[root@linux ~]# iptables -A INPUT -i eth0 -s 192.168.1.10 -j DROP
[root@linux ~]# iptables -A INPUT -i eth0 -s 192.168.1.0/24 -j ACCEPT
# 上述这两个范例很重要啊!因為有点关係!要先丢弃 192.168.1.10 才能接受该网域。

[root@linux ~]# iptables -L -n
Chain INPUT (policy DROP)
target     prot opt source               destination
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0
ACCEPT     all  --  192.168.0.1          0.0.0.0/0
DROP       all  --  192.168.1.100        0.0.0.0/0
ACCEPT     all  --  192.168.1.0/24       0.0.0.0/0
# 瞧!刚刚的设定在这裡已经生效囉!


这就是最单纯、简单的防火墙规则的设定与观察方式。你在设定完毕后,都可以利用 iptables -L -n 或 iptables -L -v 来简单的查阅一下。而如果你想要记录某个规则的纪录怎麼办?可以这样做:
[root@linux ~]# iptables -A INPUT -s 192.168.2.200 -j LOG
[root@linux ~]# 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 封包的其他规则比对吧!

[ 本帖最后由 superchen 于 2006-9-21 13:15 编辑 ]

论坛徽章:
0
2 [报告]
发表于 2006-09-21 11:56 |只看该作者
--------------------------------------------------------------------------------

TCP, UDP 的规则比对

我们在网路基础谈过各种不同的封包格式, 在谈到 TCP 与 UDP 时,比较特殊的就是那个埠口 (port number),在 TCP 方面则另外有所谓的连线封包状态, 包括最常见的 SYN 主动连线的封包格式。那麼如何针对这两种封包格式进行防火墙规则的设定呢?你可以这样看:
[root@linux ~]# iptables [-AI 链] [-io 网路介面] [-p tcp,udp] \
> [-s 来源IP/网域] [--sport 埠口范围] \
> [-d 目标IP/网域] [--dport 埠口范围] -j [ACCEPT|DROP]
参数:
--sport 埠口范围:限制来源的埠口号码,埠口号码可以是连续的,例如 1024:65535
--dport 埠口范围:限制目标的埠口号码。


事实上就是多了那个 --sport 及 --dport 这两个玩意儿,重点在那个 port number 上面啦! 底下让我们来进行几个小测试:
范例一:想要连线进入本机 port 21 的封包都抵挡掉:
[root@linux ~]# iptables -A INPUT -i eth0 -p tcp --dport 21 -j DROP

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


瞧!你可以利用 UDP 与 TCP 协定所拥有的埠口号码来进行某些服务的开放或关闭喔! 你还可以综合处理呢!例如:只要来自 192.168.1.0/24 的 1024:65535 埠口的封包, 只要想要连线到本机的 ssh port 就予以抵挡,可以这样做:
[root@linux ~]# iptables -A INPUT -i eth0 -p tcp -s 192.168.1.0/24 \
> --sport 1024:65534 --dport ssh -j DROP


注意啊!如果你有使用到 --sport 及 --dport 的参数时,就必须指定 udp 或 tcp 的封包格式才行!否则的话, iptables 的指令就会出现如下的错误:
[root@linux ~]# iptables -A INPUT -i eth0 --dport 21 -j DROP
iptables v1.2.11: Unknown arg `--dport'
Try `iptables -h' or 'iptables --help' for more information.


你应该会觉得很奇怪,怎麼『 --dport 』会是未知的参数 (arg) 呢?这是因為你没有加上 -p tcp 或 -p udp 的缘故啊!因為 port 是 TCP,UDP 特有的,其他类似 ICMP 则没有这种类的埠口资料啊! 这样说,您可以理解吧! ^_^

除了埠口之外,在 TCP 还有特殊的旗标啊!最常见的就是那个主动连线的 SYN 旗标了。 我们在 iptables 裡面还支援『 --syn 』的处理方式,我们以底下的例子来说明好了:
范例:将来自任何地方来源 port 1:1023 的主动连线到本机端的 1:1023 连线丢弃
[root@linux ~]# iptables -A INPUT -i eth0 -p tcp --sport 1:1023 \
> --dport 1:1023 --syn -j DROP


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



--------------------------------------------------------------------------------

状态模组:MAC 与 RELATED

在早期的 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@linux ~]# iptables -A INPUT -m state --state 状态
参数:
-m :一些 iptables 的模组,主要常见的有:
     state :状态模组
     mac   :网路卡硬体位址 (hardware address)
--state :一些封包的状态,主要有:
     INVALID    :无效的封包,例如资料破损的封包状态
     ESTABLISHED:已经连线成功的连线状态;
     NEW        :想要新建立连线的封包状态;
     RELATED    :这个最常用!表示这个封包是与我们主机发送出去的封包有关

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


所以说,如果你的 Linux 主机只想要作為 client 的用途,不许所有主动对你连线的来源, 那麼你可以这样做即可:

清除所有已经存在的规则 (iptables -F...)
设定预设政策,除了 INPUT 预设為 DROP 其他為预设 ACCEPT;
开放本机的 lo 可以自由放行;
设定有相关的封包状态可以连线进入本机。
这就是最最阳春的防火墙,你可以透过第二步骤抵挡所有远端的来源封包, 而透过第四步骤让你要求的远端主机回应封包可以进入, 加上让本机的 lo 这个内部迴圈装置可以放行,嘿嘿!一部 client 专用的防火墙规则就 OK 了! 你可以在某个 script 上面这样做即可:
#!/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/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 -i eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT
#iptables -A INPUT -i eth0 -s 192.168.1.0/24 -j ACCEPT


那如果区域网路内有其他的主机时,再将上表最后一行的 # 取消,就可以接受来自本地 LAN 的其他主机的连线了。 而如果你担心某些 LAN 内的恶意来源主机会主动的对你连线时,那你还可以针对信任的本地端主机的 MAC 进行过滤! 同样是使用状态模组!这次的状态则是 MAC 的比对。举例来说:
范例一:针对区域网路内的 aa:bb:cc:dd:ee:ff 主机开放其连线
[root@linux ~]# iptables -A INPUT -m mac --mac-source aa:bb:cc:dd:ee:ff \
>  -j ACCEPT
参数:
--mac-source :就是来源主机的 MAC 啦!


透过这个玩意儿,你就可以定义更严格的 LAN 内的其他主机能否连线到你的主机的权限了!



--------------------------------------------------------------------------------

ICMP 封包规则的比对

在网路基础的 ICMP 协定当中我们知道 ICMP 的格式相当的多,而且很多 ICMP 封包的类型格式都是為了要用来进行网路检测用的! 所以最好不要将所有的 ICMP 封包都丢弃!通常我们会把 ICMP type 8 (echo request) 拿掉而已, 让远端主机不知道我们是否存在,也不会接受 ping 的回应就是了。ICMP 封包格式的处理是这样的:
[root@linux ~]# 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@linux ~]# 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@linux ~]# sh  somefile


这样就能够开放部分的 ICMP 封包格式进入本机进行网路检测的工作了!真好!不是嘛!^_^

--------------------------------------------------------------------------------
防火墙的记录、回復与测试

刚刚上面我们谈了很多的设定了,那麼我该如何观察目前主机上面的防火墙规则呢? 我们可以使用『iptables -L -n 』来观察,不过,该指令所显示的资讯其实还是不太足够的。 这个时候,我们其实可以使用底下的两个指令来将目前主机上面的防火墙机制『储存』下来, 在下次想要将这个规则『回復』的时候,就能够直接利用指令将规则直接回復喔!
[root@linux ~]# iptables-save > filename
[root@linux ~]# iptables-restore < filename


一个是储存一个是回復!而在 Red Hat 系统的 RHEL,CentOS,Fedora 当中,如果你将那个 filename 档案存成『 /etc/sysconfig/iptables 』,并且利用 chkconfig 将 iptables 在开机时预设啟动的话,那麼一开机系统就会主动的帮你把防火墙的规则给载入了就是! 那麼使用 iptables-save 所得到的结果会是如何呢?让我们来看看:
[root@linux ~]# iptables-save
# Generated by iptables-save v1.2.11 on Mon Sep 11 17:47:35 2006
*filter    <==使用的 table
:INPUT DROP [7335:859454] <==三条预设的链与预设政策
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [16992:13134791]
-A INPUT -i lo -j ACCEPT  <==开始各个规则的设定
-A INPUT -m state --state RELATED -j ACCEPT
-A INPUT -m mac --mac-source 00:04:750:A2:58 -j ACCEPT
-A INPUT -m state --state ESTABLISHED -j ACCEPT
-A INPUT -i eth0 -p icmp -m icmp --icmp-type 0 -j ACCEPT
-A INPUT -i eth0 -p icmp -m icmp --icmp-type 3 -j ACCEPT
....中间省略....
-A INPUT -i eth0 -p tcp -m tcp --dport 22 -j ACCEPT
COMMIT
# Completed on Mon Sep 11 17:47:35 2006
# 井号 (#) 是註解,星号 (*) 代表预设的 table,而冒号 ( 代表各条链的预设政策;
# 后续的动作则是各个规则啦!


你瞧到输出的结果啦!整个资料几乎就是类似手动在指令列模式输入的指令! 比起 iptables -L -n 所得到的资讯要仔细的多。这也是 iptables 的特殊格式, 可以用在 iptables-restore 的指令读入呢! 比起这种方式,鸟哥还是比较喜欢使用 script 来撰写自己的防火墙规则啦。 制订好规则后当然就是要测试囉!那麼如何测试呢?

先由主机向外面主动连线试看看;
再由私有网域内的 PC 向外面主动连线试看看;
最后,由 Internet 上面的主机,主动连线到您的 Linux 主机试看看;
一步一步作下来,看看问题出在哪裡,然后多多的去改进、改良!基本上, 网路上目前很多的资料可以提供您不错的参考了!这一篇的设定写的是很简单, 大部分都还在介绍阶段而已!希望对大家有帮助! 鸟哥在参考资料当中列出几个有用的防火墙网页, 希望大家有空真的要多多的去看看!会很有帮助的!



--------------------------------------------------------------------------------
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 这个网站下载任何一个核心原始码后,解压缩就能够看到。 鸟哥这裡也放一份备份:

http:/linux.vbird.org/linux_server/0250simple_firewall/ip-sysctl.txt
有兴趣的话应该要自行去查一查比较好的喔!我们底下就拿几个简单的档案来作说明吧!


--------------------------------------------------------------------------------

/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@linux ~]# 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@linux ~]# echo "1" >  \
> /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts

论坛徽章:
0
3 [报告]
发表于 2006-09-21 11:56 |只看该作者
--------------------------------------------------------------------------------

/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.10.100/24 ,eth1 為 public IP 。那麼当有一个封包自称来自 eth1 ,但是其 IP 来源為 192.168.10.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 的这两个项目即可啊!)
要达成上面的功能你必须要这样做:
[root@linux ~]# vi somefile
for i in /proc/sys/net/ipv4/conf/*/rp_filter; do
    echo "1" > $i
done
for i in /proc/sys/net/ipv4/conf/*/log_martians; do
    echo "1" > $i
done
for i in /proc/sys/net/ipv4/conf/*/accept_source_route; do
    echo "0" > $i
done
for i in /proc/sys/net/ipv4/conf/*/accept_redirects; do
    echo "0" > $i
done
for i in /proc/sys/net/ipv4/conf/*/send_redirects; do
    echo "0" > $i
done

[root@linux ~]# sh somefile




--------------------------------------------------------------------------------
本机防火墙的一个实例

介绍了这麼多的防火墙语法与相关的注意事项后,终於要来架设防火墙了。如同前面谈到的, 你当然可以使用 iptables-save 的语法将相关的防火墙规则转存到 /etc/sysconfig/iptables 去, 然后透过 iptables-restore 或者是重新啟动 iptables 来啟用你的新防火墙规则。 不过鸟哥还是比较习惯使用 shell script 来撰写防火墙规则,而且此一特色还可以用在呼叫其他的 scripts , 可以让防火墙规则具有较為灵活的使用方式。好了,那就来谈谈如何设定咱们的防火墙规则吧!


--------------------------------------------------------------------------------
规则草拟

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

外部网路使用 eth1 (如果是拨接,有可能是 ppp0,请针对您的环境来设定);
内部网路使用 eth0 ,且内部使用 192.168.1.0/24 这个 Class ;
主机预设开放的服务有 WWW, SSH, SMTP 等等;
由於希望将信任网域 (LAN) 与不信任网域 (Internet) 整个分开的完整一点, 所以希望你可以在 Linux 上面安装两块以上的实体网卡,将两块网卡接在不同的网域,这样可以避免很多问题。 至於最重要的防火墙规则是:『关闭所有的连线,仅开放特定的服务』模式。 而且假设内部使用者已经受过良好的训练,因此在 filter table 的三条链个预设政策是:

INPUT 為 DROP
OUTPUT 及 FORWARD 為 ACCEPT
為了未来修改的方便,鸟哥将整个 script 拆成三部分,分别是:

iptables.rule:设定最基本的规则,包括清除防火墙规则、载入模组、设定服务可接受等;
iptables.deny:设定抵挡某些恶意主机的进入;
iptables.allow:设定允许某些自订的后门来源主机!
鸟哥底下预计提供的防火墙流程是这样的:



图九、防火墙规则的流程


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



--------------------------------------------------------------------------------
实际设定

事实上,我们在设定防火墙的时候,不太可能会一个一个指令的输入,通常是利用 shell scripts 来帮我们达成这样的功能吶!底下是利用上面的流程图所规划出来的防火墙 scripts,您可以参考看看, 但是您需要将环境修改成适合您自己的环境才行喔!
[root@linux ~]# mkdir -p /usr/local/virus/iptables
[root@linux ~]# cd /usr/local/virus/iptables
[root@linux iptables]# vi iptables.rule
#!/bin/bash

# 请先输入您的相关参数,不要输入错误了!
  EXTIF="eth1"              # 这个是可以连上 Public IP 的网路介面
  INIF="eth0"               # 内部 LAN 的连接介面;若无请填 ""
  INNET="192.168.1.0/24"    # 内部 LAN 的网域,若没有内部 LAN 请设定為 ""
  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; do
        echo "1" > $i
  done
  for i in /proc/sys/net/ipv4/conf/*/log_martians; do
        echo "1" > $i
  done
  for i in /proc/sys/net/ipv4/conf/*/accept_source_route; do
        echo "0" > $i
  done
  for i in /proc/sys/net/ipv4/conf/*/accept_redirects; do
        echo "0" > $i
  done
  for i in /proc/sys/net/ipv4/conf/*/send_redirects; do
        echo "0" > $i
  done

# 2. 清除规则、设定预设政策及开放 lo 与相关的设定值
  PATH=/sbin:/usr/sbin:/bin:/usr/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 -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
  iptables -A INPUT -m state --state ESTABLISHED -j ACCEPT

# 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  22  -j ACCEPT   # SSH
# iptables -A INPUT -p TCP -i $EXTIF --dport  25  -j ACCEPT   # SMTP
# iptables -A INPUT -p UDP -i $EXTIF --sport  53  -j ACCEPT   # DNS
# iptables -A INPUT -p TCP -i $EXTIF --sport  53  -j ACCEPT   # DNS
# iptables -A INPUT -p TCP -i $EXTIF --dport  80  -j ACCEPT   # WWW
# iptables -A INPUT -p TCP -i $EXTIF --dport 110  -j ACCEPT   # POP3
# iptables -A INPUT -p TCP -i $EXTIF --dport 443  -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} "`
        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

# 4. 内部伺服器的设定:
# iptables -t nat -A PREROUTING -p tcp -i $EXTIF --dport 80  \
           -j DNAT --to 192.168.1.210:80


特别留意上面程式码的特殊字体部分,基本上,你只要修改一下最上方的介面部分, 应该就能够运作这个防火墙了。不过因為每个人的环境都不相同, 因此你在设定完成后,依旧需要测试一下才行喔!不然,出了问题不要怪我啊!.... 再来看一下关於 iptables.allow 的内容是如何?假如我要让一个 140.116.44.0/24 这个网域的所有主机来源可以进入我的主机的话,那麼这个档案的内容可以写成这样:
[root@linux iptables]# vi iptables.allow
#!/bin/bash
# 底下则填写你允许进入本机的其他网域或主机啊!
  iptables -A INPUT -i $EXTIF -s 140.116.44.0/24 -j ACCEPT

# 底下则是关於抵挡的档案设定法!
[root@linux iptables]# vi iptables.deny
#!/bin/bash
# 底下填写的是『你要抵挡的那个咚咚!』
  iptables -A INPUT -i $EXTIF -s 140.116.44.254 -j DROP

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


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

不过,还是如同前面我们所说的,这个 firewall 仅能提供基本的安全防护,其他的相关问题还需要再测试测试呢! 此外,如果你希望一开机就自动执行这个 script 的话,请将这个档案的完整档名写入 /etc/rc.d/rc.local 当中,有点像底下这样:
[root@linux ~]# vi /etc/rc.d/rc.local
.....其他省略.....
# 1. Firewall
/usr/local/virus/iptables/iptables.rule
.....其他省略.....


上述三个档案请你不要在 Windows 系统上面编辑后传送到 Linux 上运作,因為 Windows 系统的断行字元问题, 将可能导致该档案无法执行。建议你直接到底下去下载,传送到 Linux 后可以利用 dos2unix 指令去转换断行字元! 就不会有问题!

http://linux.vbird.org/download/ ... etail&fileid=43
这就是一个最简单、阳春的防火墙。同时,这个防火墙还可以具有最阳春的 IP 分享器的功能呢! 也就是在 iptables.rule 这个档案当中的第二部分了。 这部分我们在下一节会再继续介绍的。

[ 本帖最后由 superchen 于 2006-9-21 13:16 编辑 ]

论坛徽章:
0
4 [报告]
发表于 2006-09-21 11:57 |只看该作者
--------------------------------------------------------------------------------
NAT 主机的设定

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

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

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


--------------------------------------------------------------------------------
什麼是 NAT? SNAT? DNAT?

在谈到 NAT 的实际运作之前,让我们再来看一下比较简单的封包透过 iptables 而传送到后端主机的流程(请往前参考图八)。当网路佈线如图二的架构, 若内部 LAN 有任何一部主机想要传送封包出去时,那麼这个封包要如何透过 Linux 主机而传送出去? 他是这样的:

先经过 NAT table 的 PREROUTING 链;
经由路由判断确定这个封包是要进入本机与否,若不进入本机,则下一步;
再经过 Filter table 的 FORWARD 链;
通过 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 上面, 例如图二连线的方式来说,那个 Linux 主机就是 IP 分享器啦!那麼他是如何达到 IP 分享的功能?就是透过 NAT 表格的 POSTROUTING 来处理的。假设你的网路佈线如图二所示, 那麼 NAT 主机是如何处理这个封包的呢?



图十、SNAT 封包传送出去的示意图


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

用户端所发出的封包表头中,来源会是 192.168.1.100 ,然后传送到 NAT 这部主机;
NAT 这部主机的内部介面 (192.168.1.2) 接收到这个封包后,会主动分析表头资料, 因為表头资料显示目的并非 Linux 本机,所以开始经过路由, 将此封包转到可以连接到 Internet 的 Public IP 处;
由於 private IP 与 public IP 不能互通,所以 Linux 主机透过 iptables 的 NAT table 内的 Postrouting 链将封包表头的来源偽装成為 Linux 的 Public IP ,并且将两个不同来源 (192.168.1.100 及 public IP) 的封包对应写入暂存记忆体当中, 然后将此封包传送出去了;
此时 Internet 上面看到这个封包时,都只会知道这个封包来自那个 Public IP 而不知道其实是来自内部啦。 好了,那麼如果 Internet 回传封包呢?又会怎麼作?



图十一、SNAT 封包接收的示意图



在 Internet 上面的主机接到这个封包时,会将回应资料传送给那个 Public IP 的主机;
当 Linux NAT 主机收到来自 Internet 的回应封包后,会分析该封包的序号,并比对刚刚记录到记忆体当中的资料, 由於发现该封包為后端主机之前传送出去的,因此在 NAT Prerouting 链中,会将目标 IP 修改成為后端主机,亦即那部 192.168.1.100,然后发现目标已经不是本机 (public IP), 所以开始透过路由分析封包流向;
封包会传送到 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 存取的伺服器啦! 就有点类似图四的 DMZ 内的主机啊!底下也先来谈一谈 DNAT 的运作吧!



图十二、DNAT 的封包传送示意图


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

外部主机想要连接到目的端的 WWW 服务,则必须要连接到我们的 NAT 主机上头;
我们的 NAT 主机已经设定好要分析出 port 80 的封包,所以当 NAT 主机接到这个封包后, 会将目标 IP 由 public IP 改成 192.168.1.210 ,且将该封包相关资讯记录下来,等待内部伺服器的回应;
上述的封包在经过路由后,来到 private 介面处,然后透过内部的 LAN 传送到 192.168.1.210 上头!
192.186.1.210 会回应资料给 61.xx.xx.xx ,这个回应当然会传送到 192.168.1.2 上头去;
经过路由判断后,来到 NAT Postrouting 的链,然后透过刚刚第二步骤的记录,将来源 IP 由 192.168.1.210 改為 public IP 后,就可以传送出去了! (类似图十的状态!)。
其实整个步骤几乎就等於 SNAT 的反向传送哩!这就是 DNAT 囉!很简单吧!


--------------------------------------------------------------------------------
最阳春 NAT 主机: IP 分享功能

在 Linux 的 NAT 主机服务当中,最常见的就是类似图二的 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
# 这一行在让 NAT 主机可接受来自内部 LAN 的封包
echo "1" > /proc/sys/net/ipv4/ip_forward
# 上头这一行则是在让你的 Linux 具有 router 的能力
iptables -t nat -A POSTROUTING -s $innet -o $EXTIF -j MASQUERADE
# 这一行最关键!就是加入 nat table 封包偽装!


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


--------------------------------------------------------------------------------

LAN 内其他 PC 的设定

上面提到的是 NAT 主机的设定,那麼在 LAN 内的其他 PC 网路参数要如何设定呢?很简单啊, 只要记得底下的参数值即可:

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 而定;
这样就搞定一部阳春的 NAT 主机了!简单的要命啊!

事实上,除了 IP 偽装 (MASQUERADE) 之外,我们还可以直接指定修改 IP 封包表头的来源 IP 呢! 举例来说,如下面这个例子:
范例:将要由 eth1 传送出去的封包,封包来源改為 192.168.200.250
[root@linux ~]# iptables -t nat -A POSTROUTING -o eth1 \
>  -j SNAT --to 192.168.200.250

范例:同上,但封包来源為 192.168.200.210~220
[root@linux ~]# iptables -t nat -A POSTROUTING -o eth1 \
>  -j SNAT --to 192.168.200.210-192.168.200.210


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



--------------------------------------------------------------------------------
iptables 的额外核心模组功能

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



--------------------------------------------------------------------------------
在防火墙后端之网路伺服器 DNAT 设定

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

先来谈一谈,如果我想要处理 DNAT 的功能时, iptables 要如何下达指令? 另外,你必须要知道的是, DNAT 用到的是 nat table 的 Prerouting 链喔!不要搞错了。
范例:将连接到 eth1 介面的 port 80 传导到内部的 192.168.1.210
[root@linux ~]# iptables -t nat -A PREROUTING -p tcp -i eth1 \
> --dport 80 -j DNAT --to 192.168.1.210:80


那个『 -j DNAT --to 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@linux ~]# iptables -t nat -A PREROUTING -p tcp  --dport 80 \
> -j REDIRECT --to-ports 8080
# 这玩意最容易在您使用了非正规的 port 来进行某些 well known 的协定,
# 例如使用 8080 这个 port 来啟动 WWW ,但是别人都以 port 80 来连线,
# 所以,您就可以使用上面的方式来将对方对您主机的连线传递到 8080 囉!


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

--------------------------------------------------------------------------------
重点回顾

要拥有一部安全的主机,必须要有良好的主机权限设定;随时的更新套件;定期的重要资料备份;完善的员工教育训练。 仅有防火墙是不足够的;
防火墙最大的功能就是帮助你『限制某些服务的存取来源』,可以管制来源与目标的 IP ;
防火墙依据封包抵挡的阶层,可以分為 Proxy 以及 IP Filter (封包过滤) 两种类型;
為了将整个网路的信任 (LAN) 与不信任 (Internet) 网域完整切割,防火墙通常具有两个实体网路介面, 分别连结信任与不信任网域;
在防火墙内,但不在 LAN 内的伺服器所在网域,通常被称為 DMZ (非军事区),如图四所示;
封包过滤机制的防火墙,通常至少可以分析 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) 作為封包的行為依据;
核心本身有提供很多网路相关功能,针对 IPv4 之设定值都在 /proc/sys/net/ipv4/* 内;
iptables 的指令列当中,可以下达的参数相当的多,当下达 -j LOG 的参数时,则该封包的流程会被纪录到 /var/log/messages 当中;
防火墙可以多重设定,例如虽然已经设定了 iptables ,但是仍然可以持续设定 TCP Wrappers ,因為谁也不晓得什麼时候 iptables 会有漏洞~或者是规则规划不良!

--------------------------------------------------------------------------------
课后练习

為什麼我架设了防火墙,我的主机还是可能中毒?
防火墙不是万灵丹,他还是可能被病毒或者是木马程式所入侵的! 此外,如果您的主机本身就已经提供了多个网路服务,则当该网路服务的套件有漏洞时, 防火墙仍然无法克服该服务的漏洞的!因此仍然需要持续的进行主机的监视工作
请说明為何架设了防火墙,我的主机还是可能被入侵?入侵的依据可能是什麼方法?
因為防火墙仅是抵挡某些不受欢迎的封包,如果您有开放 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 这两个指令,配合命令重导向即可!
如果你的区网当中有个 PC 使用者老是连上 Internet 乱搞,你想要将他的 IP 锁住,但他总是有办法修改成其他 IP 来连外, 那你该怎麼办?让他无法继续连外?
可以利用封锁网路卡卡号 MAC 来处理!

--------------------------------------------------------------------------------
参考资料

中文网站:
http://www.study-area.org/linux/servers/linux_nat.htm
http://linux.tnc.edu.tw/techdoc/firewall/
http://www.linuxyes.com/tw/tutorial/iptables.html
英文网站:
http://www.netfilter.org/
http://www.linuxguruz.org/iptables/
http://www.netfilter.org/documen ... iltering-HOWTO.html
http://www.interhack.net/pubs/fwfaq/
其他书籍与资料:
Robert L. Ziegler 著,朱亮愷等译,『实战 Linux 防火墙--iptables 应用全蒐录』,上奇出版社,2004。
本机的核心文件:/usr/src/linux-{version}/networking/ip-sysctl.txt
iptables 的内建 tables 与各个 chain 的相关性:
核心参数的相关说明:http://www.study-area.org/tips/a ... uting-HOWTO-12.html

--------------------------------------------------------------------------------
2002/08/20:第一次完成日期!
2003/08/25:重新设计内容,改写一些指令介绍,与前一篇『认识网路安全』 分的比较完整一点!
2006/09/06:将旧的文章移动到此处
2006/09/11:拿掉了已经在基础篇有介绍过的 认识服务之 TCP Wrappers。
2006/09/13:加入 NAT 的说明了,将旧的 NAT 主机移动到 此处。
2006/09/15:将 iptables.rule 的连结贴上去了!之前忘记修改该档案了~

--------------------------------------------------------------------------------

[ 本帖最后由 superchen 于 2006-9-21 13:17 编辑 ]
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP