kernel 已更新至 2.4.x 就有很多人知了,但随着 kernel 改变而要更新的软件就有很多不为人知,这个 iptables 即为其中一个。kernel 2.4 已经推出这么久,但仍然有人问︰为甚么我的 ipchains 不能使用?皆因 Rusty Russell 等人(ipchains,即 kernel 2.2.x 所用的防火墙工具﹐也是他的杰作!)觉得 ipchains 仍未完善,于是决定在 kernel 2.3.15 时开始重写,希望在 kernel 2.4 推出时有一个功能更强的 firewall 出现。他们的心血就是今期要介绍的 iptables 了。 这个 iptables 的前身称为 netfilter,作者仍未搞清楚为何突然会改名,但新名称约是在 kernel 2.3.99 时出现的。在本章末后的 URL 也可看到点端倪。 话又说回来,凭甚么说它的功能强大呢?这要由stateless firewall 这名词说起了。所谓 stateless firewall,乃是存在于普遍的 router 中,会对每个 packet 分别加以检查,再决定是否让它通过、回传错误还是完全忽略。要点是 "分别" 两个字。这里拿 TCP 作个例子。所有 TCP connection 都是以三个 packet 开始︰一是由 client 送出一个 set 了 SYN bit 的 packet 到 server(不明白的,可当是一个特别的卷标表示 connection 开始),第二个是由 server 送出一个 set 了 SYN 和 ACK bit 的 packet 回答 client,而最后是由 client 传回一个 set 了 ACK bit 的 packet 给 server。 问题来了。如果有人无故send 一个有 ACK bit 的 packet,那怎分办是故意的呢,还是一个正常的 connection 呢?stateless firewall 不能分办这一点,于是就让它通过了。这种技巧经常被用来 scan 网络,因这方法可骗过很多的 firewall。 stateful firewall 和 stateless firewall 的分别就在于此了。statefull firwall 会记着每个 connection,若有任何 packet,会先看看这个 packet 是否已知的 connection 的一部份,若找过记忆中的 connection 还没有任何资料,就可肯定这 packet 是假的,把它丢进垃圾桶里去!当然,这是简化了的例子,不过可向大家解释个大概了。 它还有甚么好处呢?以往的ipchains 只用一个 binary,要加入其它功能十分艰难,需要直接修改源程序代码所有有关的地方并再编译一次 ipchains 才行;但现在 iptables 使用 modules 的架构,所有外加的功能只要写一个 module 就行,可发展的功能不限于只修改主要的 source code 才可实现,连发展速度也顺带加快了。 没了?等等,笔者还未说完呢iptables 能限制 connection 的速率 ── 这个对于防止长期轰炸造成的系统资源完全用尽的情况很有效。最后一点和刚才笔者提及的甚么 SYN、ACK bit 等有关,统称 TCP flag。ipchains 只能检查数种可能的 flag 的其中一种,于是其它不正常的 packet 甚至某些正常的 packet 都可肆无忌惮地通过。现在 iptables 可检查任何这类的 packet,使得许多的 scanning 无所遁形。 唔...好象在说教似的,到现在还是在讲理论。不过,笔者会假设读者对 IP、TCP、connection 等等有点概念,否则整本书也放不下呢!而且暂时只会简简单单地讲解一些非常"小儿科"的设定,希望将来会有机会让各位真正触摸到 iptables 的威力!
安装指示
文末 iptables 主网页的 URL 里有下载 iptables 的 link,很易看见。下载最新版本前(笔者所能找到的最新版本是 1.2.1a),先得弄清楚︰你的 kernel 是甚么版本?如果不是 2.4.x,不好意思!还是用 ipchains 罢!另外,也要清楚你的 kernel 是否预先支持了 iptables。从以下两点可以判断︰
1. /proc/net/ip_tables_names 是否存在?
2. /lib/modules/2.x.x/kernel/net/ipv4/netfilter/ip_tables.o 是否存在?
只要其中一个答案是肯定的,就表示可跳过以下两段 recompile kernel 的步骤了。否则继续看看怎样 recompile kernel……
下载 kernel 后(截稿前最新还是 2.4.2,但做清兵的有特权下载 2.4.3-pre4),在 "Networking option" 中选上 "Network packet filtering (replaces ipchains)",之后就会多了一个 "IP: Netfilter Configuration --->" 的选项在 "TCP/IP Networking" menu 下,在那里按 enter 即可开始选择你想支持的防火墙功能了。个人提议里面所有选项都是 "M" (即 module),因为这样可不用浪费内存在没有用的地方,也可减少 boot 机时间,同时也不怕某些功能会因没有 compile 而用不到。
这时开始 compile kernel 并 reboot 及使用新的 kernel 吧。若在 compile 时或 compile 后的 depmod 步骤出问题,而且肯定出错在有关 netfilter(iptables)的地方,随时可以把刚才有关的 module 选回 "Y"(即内建在 kernel 里)并重新 compile,没问题的!(笔者试过了)
接下来就是 compile iptables 了。把 iptables-1.x.x.tar.gz 解压后,先开启文字编辑器看看有没有问题或要修改的地方(例如想将所有 binary 放在 /usr/sbin 里,便设定 BINDIR 为 /usr/sbin,如此类推)。修改完毕后,键入
# make all experimental
就会开始 compile……哎唷,出了 error?是不是像以下那样?
libipulog/libipulog.c: In function `ipulog_create_handle':
libipulog/libipulog.c:142: `NETLINK_NFLOG' undeclared (first use in this function)
libipulog/libipulog.c:142: (Each undeclared identifier is reported only once
libipulog/libipulog.c:142: for each function it appears in.)
make: *** [libipulog/libipulog.o] Error 1
不紧要,再 edit 一次 Makefile,将 COPT_FLAGS 的一行由
COPT_FLAGS:=-O2 -DNDEBUG
变成
COPT_FLAGS:=-O2 -DNDEBUG -DNETLINK_NFLOG=4
再 compile 一次就行了!最后,输入
# make install install-experimental
它就会把 iptables、iptables-save 及 iptables-restore 抄到 /usr/local/sbin 中。如果要用,就要把 /usr/local/sbin 加进你的 PATH 里,这里不详细说明了。
若急不及待要试一试,好,键入以下一句︰
# iptables -L -v -n
是否 warn 你说甚么不支持 iptables?这样似乎是不知何故不能加载 kernel module,需要先用人手加入 module︰
# modprobe iptables
再 run 一次 iptables,就该看到像以下的输出︰
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
是吗?那就成功了!且看看下一章,教你怎样建立简单的 firwall!
设定 firewall
处理 firewall rule 的选项
且不忙着设计甚么的,先来热热身︰
# iptables -A INPUT -j ACCEPT
大小楷绝不可以乱!输入这条 rule 后,用 "iptables -L -v -n" 该看到类似以下结果︰
Chain INPUT (policy ACCEPT 2939 packets, 1124863 bytes)
pkts bytes target prot opt in out source destination
1 241 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0
它表示甚么呢?-A 是 append,它会在 INPUT、FORWARD、OUTPUT 其中一条 "chain" 里加一条 "rule" 而这条 rule 在随后的参数将会见到。而 -j 呢,则是定义究竟那些 packet 该怎样处理。现在是 ACCEPT,即让它通过。如果不想让任何 packet 通过呢?十分简单︰
# iptables -R INPUT 1 -j DROP
今次由 ACCEPT 变 DROP,就不会有任何 packet 可以过关了。但…… -R 又是甚么?那是 replace 的意思,随后的 "INPUT 1" 即 replace 了第一条 chain,即刚才 ACCEPT 那一条呀!
当然,firewall 的功用不可能是禁止任何 traffic 吧!因此让我们先清除它︰
# iptables -D INPUT 1
-D 表示 delete,用法和上面的 -R 一样。除了 -A、-R、-D 外还有 -I 表示 insert;-A 是逐条逐条 rule 加上去,-I 则是在整串的 rule 中间加插某一条 rule,除此之外没有其它分别了。
最后还有 -F 表示 flush,顾名思义它会把你辛辛苦苦 set 好的 rule 都冲进马桶里!
有关 IP address 的选项
再多点热身才好办事,试试吧︰
# iptables -A INPUT -s 199.95.206.201 -j DROP
为甚么用这个 IP 作示范?总之是个讨人厌的地方吧!不要问了!一句说完,就是 block 了这一个 IP 不准它有任何 traffic 进入自己的地盘。不单是一个 IP,一个 range 的 IP 也可以︰
# iptables -A INPUT -s 10.0.0.0/8 -j DROP
如果你的 LAN 是使用 192.168.0.x 的,那当然不希望有 10.x.x.x 地址出现!因此 DROP 了这种 IP 是很正常的。
上面两个例子是用 -s(即 source IP)的,且看看它的反面,即 -d(destination)的例子︰
# iptables -A INPUT -d 192.168.0.1 -j DROP
假设你的 IP 是 192.168.0.2 吧,那么这条 rule 对你完全没有影响;相反,若你的 IP 是 192.168.0.1,那任何到你的机器的 packet 都会被 DROP 了。
-s 和 -d 可以放在一起用,而且它们和 IP address 之间可以放一个叹号(!)表示 "not" 的意思。例如︰
# iptables -P INPUT DROP
# iptables -A INPUT -s ! 192.168.0.3 -d 192.168.0.0/24 -j ACCEPT
笔者漏了 -P 未介绍,那是 default policy 的意思,即预先定义如果甚么 rule 也不能决定 packet 的去向的时候,会预设让它通过呢,还是预设拒诸门外,还是做其它动作。这里预设是 DROP。好了,下一句才是笔者想讲的,意思是︰如果 source 不是 192.168.0.3,而 destination 是 192.168.0.x 任何一个 IP,都会让它通过。那即是封杀了 192.168.0.3!
在看下一节前,先清一清旧的垃圾 rules 罢︰
# iptables -F
指定 network interface 的选项
属于这类的选项很少,和上面的一样,只有两个︰-i 和 -o。-i 是指明 input 的 interface,只会在 INPUT chain 时有用;相反,-o 是 output interface,只会在 output 时有用。先看看实例︰
# iptables -A INPUT -i eth1 -s 192.168.0.0/24 -d 192.168.0.0/24 -j ACCEPT
很简单,接受所有 LAN 的 traffic 罢了。不过还加上 "-i eth1",防止 LAN 外有人刻意送入一些假的 packet,扮成是内部的 traffic。但这个其实已不需要了,因 kernel 本身已有机制可防止这种情况,输入以下一句就行,解释就免了。^_^
# echo '1' > /proc/sys/net/ipv4/conf/all/rp_filter
还有 -o……用一个简单的例子吧。
# iptables -A OUTPUT -o ppp0 -d 205.138.3.22 -j REJECT
其实并不简单。首先,-j REJECT 和 -j DROP 的相同之处都是拒绝,但 DROP 是当没事发生,REJECT 则是送出响应说这个 packet 被 REJECT 了。另外,紧记︰-o 是和 OUTPUT chain 一起用的!至于那个 IP 嘛……总之这条 rule 可防止你的资料在不知情的情况下被送出到某间专收集全世界所有人的上网习惯等资料的公司吧!
这恐怕暂时已经够一部份读者们学一段时间了。至于其它早已懂得这方面知识的朋友,笔者谨此致歉!将来希望会有机会和大家探讨一些较深入的设定呢!
iptables 主网址︰
http://netfilter.kernelnotes.org
http://netfilter.filewatcher.org
http://netfilter.samba.org
ipchains 网址︰
http://netfilter.kernelnotes.org/ipchains/
http://netfilter.filewatcher.org/ipchains/
http://netfilter.samba.org/ipchains/