Linux的2.4版内核引入了一种全新的包过滤引擎,称为Netfilter.控制Netfilter的工具iptables是linux2.2版内核比较老的命令ipchains的兄弟。iptables把有次序的规则“链(chains)”应用到网络包上。链的集合就构成了“表(tables)”,用于处理特殊类型的流量。
默认的iptables表名叫“filter(过滤器)”。这个表里的规则链都用于根据包来过滤流量。除了filter表之外,iptables还包含”nat”和“mangle”表名,”nat“表包含的规则链控制着NAT(Network Address Translation,网络地址转换,mangle表包含了链可以修改或者改变在nat和包过滤之外的网络包内容。
以下内容来自:http://linux.vbird.org/linux_server/0250simple_firewall.php
事实上, iptables 就是一个可以加载的模块,在开始进行 iptables 的设定之前,先确认一下,由于 ipchains 与 iptables 是不能同时存在的,所以先检查一下 ipchains 是否不小心被加载到系统当中了呢?
[root@test root]# lsmod
# 若有发现 ipchains 的字样,表示系统不小心加载了 ipchains 了,请使用:
[root@test root]# rmmod ipchains
# 这样就能够移除 ipchains 了!然后加载 iptables 吧!
[root@test root]# modprobe ip_tables
iptables 的语法
清除规则与观察规则
iptables 在一开始的时候,应该是没有规则的,不过,可能因为您在安装的时候就有选择系统自动帮您建立防火墙机制,此时系统就会有预设的防火墙规则了!好了,无论如何,我们先来看看目前本机的防火墙规则是如何吧!?
[root@test root]# iptables [-t tables] [-L] [-n] 参数说明:
-t:后面接 iptables 的 table ,例如 nat 或 filter ,如果没有 -t table 的话,那么预设就是 -t filter 这个 table 喔!
-L:列出目前的 table 的规则
-n:不进行 IP 与 HOSTNAME 的转换,屏幕显示讯息的速度会快很多! 范例:
[root@test root]# iptables -L -n
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
# 仔细看到上面,因为没有加上 -t 的参数,所以预设就是 filter 这个表格,
# 在这个表格当中有三条链,分别是 INPUT, OUTPUT 与 FORWARD ,而且因为
# 没有规则,所以规则里面都是空的!同时注意一下,在每个 chain 的后面 ()
# 里面,会发现有 policy 对吧!那就是『预设动作(政策)』咯!以上面来看,
# 虽然我们启动了 iptables ,但是我们没有设定规则,然后政策又是 ACCEPT,
# 所以『任何封包都会接受』的意思喔!
[root@test root]# 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
# 与 filter 类似的, nat 这个表格里面有的则是 PREROUTING, POSTROUTING
# 以及 OUTPUT 三条链啊!
至于要清除规则的话,就得要这样下达指令了!
[root@test root]# /sbin/iptables [-t tables] [-FXZ] 参数说明:
-F :清除所有的已订定的规则;
-X :杀掉所有使用者建立的 chain (应该说的是 tables )啰;
-Z :将所有的 chain 的计数与流量统计都归零 范例:
[root@test root]# /sbin/iptables -F
[root@test root]# /sbin/iptables -X
[root@test root]# /sbin/iptables -Z
[root@test root]# /sbin/iptables -t nat -F
# 请注意,如果在远程联机的时候,『这三个指令必须要用 scripts 来连续执行』,
# 不然肯定『会让您自己被主机挡在门外!』
一般来说,我们在重新定义防火墙的时候,都会先将规则给他清除掉。还记得我们前面谈到的,防火墙的『规则顺序』是有特殊意义的,所以啰,当然先清除掉规则,然后一条一条来设定会比较容易一点啦!
定义政策 清除规则之后,再接下来就是要设定规则的政策啦!还记得政策指的是什么吗?『当您的封包不在您设定的规则之内时,则该封包的通过与否,以 Policy 的设定为准』,通常这个政策在 filter 这个 table 的 INPUT 链方面可以定义的比较严格一点,而 FORWARD 与 OUTPUT 则可以订定的松一些!通常我都是将 INPUT 的 policy 定义为 DROP 啦!全部都挡掉再说!
[root@test root]# /sbin/iptables [-t tables] [-P] [INPUT,OUTPUT,FORWARD| PREROUTING,OUTPUT,POSTROUTING] [ACCEPT,DROP] 参数说明:
-P :定义政策( Policy )。注意,这个 P 为大写啊! INPUT :封包为输入主机的方向; OUTPUT :封包为输出主机的方向; FORWARD:封包为不进入主机而向外再传输出去的方向; PREROUTING :在进入路由之前进行的工作; OUTPUT :封包为输出主机的方向; POSTROUTING:在进入路由之后进行的工作。 范例:
[root@test root]# /sbin/iptables -P INPUT DROP
[root@test root]# /sbin/iptables -P OUTPUT ACCEPT
[root@test root]# /sbin/iptables -P FORWARD ACCEPT
[root@test root]# /sbin/iptables -t nat -P PREROUTING ACCEPT
[root@test root]# /sbin/iptables -t nat -P OUTPUT ACCEPT
[root@test root]# /sbin/iptables -t nat -P POSTROUTING ACCEPT
# 除了 INPUT 之外,其它都给他设定为接受啰!在上面的设定之后,
# 我们的主机发出的封包可以出去,但是任何封包都无法进入,
# 包括响应给我们送出封包的响应封包(ACK)也无法进入喔!
增加与插入规则 好了,接下来准备要来定义规则了!请注意,在这个小节里面我们完全都针对 Linux 本机来进行设定 ( 就是仅针对 filter table 啰! ),至于 NAT 后面的主机,我们一部分留到 NAT 主机设定再谈,一部分留在本章最后面的进阶篇再谈,这里先学基础的就好了!要设定 iptables 规则的基本语法如下:
[root@test root]# iptables [-t filter] [-AI INPUT,OUTPUT,FORWARD]
> [-io interface] [-p tcp,udp,icmp,all] [-s IP/network] [--sport ports]
> [-d IP/network] [--dport ports] -j [ACCEPT,DROP] 参数说明:
-A :新增加一条规则,该规则增加在最后面,例如原本已经有四条规则, 使用 -A 就可以加上第五条规则!
-I :插入一条规则,如果没有设定规则顺序,预设是插入变成第一条规则, 例如原本有四条规则,使用 -I 则该规则变成第一条,而原本四条变成 2~5 INPUT :规则设定为 filter table 的 INPUT 链 OUTPUT :规则设定为 filter table 的 OUTPUT 链 FORWARD:规则设定为 filter table 的 FORWARD 链
-i :设定『封包进入』的网络卡接口
-o :设定『封包流出』的网络卡接口 interface :网络卡接口,例如 ppp0, eth0, eth1....
-p :请注意,这是小写呦!封包的协定啦! tcp :封包为 TCP 协定的封包; upd :封包为 UDP 协定的封包; icmp:封包为 ICMP 协定、 all :表示为所有的封包!
-s :来源封包的 IP 或者是 Network ( 网域 );
--sport:来源封包的 port 号码,也可以使用 port1:port2 如 21:23 同时通过 21,22,23 的意思
-d :目标主机的 IP 或者是 Network ( 网域 );
--dport:目标主机的 port 号码;
-j :动作,可以接底下的动作; ACCEPT :接受该封包 DROP :丢弃封包 LOG :将该封包的信息记录下来 (预设记录到 /var/log/messages 档案) 范例: 范例一:所有的来自 lo 这个接口的封包,都予以接受
[root@test root]# iptables -A INPUT -i lo -j ACCEPT
# 注意一下,因为 -d, --dport, -s, --sport 等等参数都没有设定,这表示:
# 不论封包来自何处或去到哪里,只要是来自 lo 这个界面,就予以接受!
# 这个观念挺重要的,就是『没有设定的规定,则表示该规定完全接受』的意思!
# 例如这个案例当中,关于 -s, -d...等等的参数没有规定时! 范例二:来自 192.168.0.1 这个 IP 的封包都予以接受:
[root@test root]# iptables -A INPUT -i eth0 -p tcp -s 192.168.0.1 -j ACCEPT
# 新增一条规则,只要是来自于 192.168.0.1 的封包,不论他要去哪里,
# 使用的是那个协议 (port) 主机都会予以接受的意思~ 范例三:来自 192.168.1.0 这个 C Class 的网域的任何一部计算机,就予以接受!
[root@test root]# iptables -A INPUT -i eth0 -p tcp -s 192.168.1.0/24 -j ACCEPT
# 这个是网域的写法喔!稍微注意一下的是,在范例二当中我们仅针对一个 IP ,
# 至于这个范例当中,则是针对整个网域来开放吶!而网域的写法可以是:
# 192.168.1.0/24 也可以是 192.168.1.0/255.255.255.0 都能够接受喔! 范例四:来自 192.168.1.25 的封包都给他丢弃去!
[root@test root]# iptables -A INPUT -i eth0 -p tcp -s 192.168.1.25 -j DROP
范例五:只要是想进入本机的 port 21 的封包就给他丢弃
[root@test root]# iptables -A INPUT -i eth0 -p tcp --dport 21 -j DROP
范例六:来自 192.168.0.24 这个 IP 的封包,想要到我的 137,138,139 埠口时,都接受
[root@test root]# iptables -A INPUT -i eth0 -p tcp -s 192.168.0.24
> --dport 137:139 -j ACCEPT 范例七:只要是接触到我主机的 port 25 就将该封包记录 (LOG) 下来
[root@test root]# iptables -A INPUT -p tcp --dport 25 -j LOG
# 还是请特别注意到『规则的顺序排列』的问题喔!
如上面的基本语法所示,我们的 iptables 可以规定封包『来自哪里、要去哪里、使用什么协议(port number)』等等的信息呢!所以他的功能就真的是挺强大的啊!而除了上述的功能之外,我们不是谈过,好像还可以使用网络卡的硬件地址(MAC)来进行分析吗?而且,那个 ping 的指令响应封包的 ICMP 协议也可以进行设定喔!此外,TCP 封包 Header 上面的 SYN 旗标的功能与否,也能够设定呢!底下谈一谈这些更深入的规则喔!
iptables 的其它相关参数说明:
[!] --syn :这个设定仅能用于 -p tcp 的规则中,因为 TCP 封包有 syn 的旗标存 在啊!当 TCP 封包存有 syn 旗标,表示这个联机是对方『主动』连过来的! 若于 --syn 之前加上 ! 表示该封包不带有 syn 的意思~(刚好相反之意!) 范例一:将来自 192.168.100.200 的主动联机封包丢弃:
[root@test root]# iptables -A INPUT -p tcp -i eth0 -s 192.168.1.235
> --syn -j DROP
--icmp-type:可以管制 ICMP 封包的某些类型!还记得我们在 网络基础 里面 谈到的 ICMP 的某些类型吧!对啦!如果您不想要让对方 ping 到您的机器, 就是利用这个项目啦! 范例二:别的主机 ping 我们主机时,我们主机不予以响应
[root@test root]# iptables -A INPUT -p icmp --icmp-type 8 -j DROP
# 当您下达这样的指令后,就表示未来别人对您使用 ping 的时候,
# 我们的主机将不会响应,所以对方主机就会显示我们主机『无法连接』的状态!
-m :表示封包的状态,状态有底下数种: -m mac --mac-source aa:bb:cc:dd:ee:ff 这个就是我们上面提到的可以控制『网络卡卡号, MAC』的设定方法啰! 那个 aa:bb:cc:dd:ee:ff 就是网络卡的 MAC ! -m state --state <状态> 有数种状态,状态有: INVALID:无效的封包,例如数据破损的封包状态 ESTABLISHED:已经联机成功的联机状态; NEW:想要新建立联机的封包状态; RELATED:这个最常用!表示这个封包是与我们主机发送出去的封包有关, 可能是响应封包或者是联机成功之后的传送封包!这个状态很常被设定, 因为设定了他之后,只要未来由本机发送出去的封包,即使我们没有设定 封包的 INPUT 规则,该有关的封包还是可以进入我们主机喔! 可以简化相当多的设定规则啦! 范例三:让 bb:cc:dd:aa:ee:ff 网络卡无法使用我们主机的资源 [root@test root]# iptables -A INPUT -p all -m mac --mac-source > 01:01:01:01:02:01 -j DROP # 这种方式可以用来管制网络卡卡号喔!就不怕别人使用 IP 搞怪了! 范例四:让已经建立或者是与我们主机有关的响应封包通过,但是让不合法的, 以及想要尝试新建立的封包被抵挡在外!
[root@test root]# iptables -A INPUT -p tcp -m state
> --state ESTABLISHED,RELATED -j ACCEPT
[root@test root]# iptables -A INPUT -p tcp -m state
> --state INVALID,NEW -j DROP
# 需要设定两条喔!至于封包状态则可以使用逗号隔开!逗号两边不要有空格
-j <动作>:除了比较常见的 ACCEPT 与 DROP 之外,还有哪些动作? REDIRECT --to-ports
[root@test root]# iptables -t nat -A PREROUTING -p tcp --dport 80
> -j REDIRECT --to-ports 8080
# 这玩意最容易在您使用了非正规的 port 来进行某些 well known 的协议,
# 例如使用 8080 这个 port 来启动 WWW ,但是别人都以 port 80 来联机,
# 所以,您就可以使用上面的方式来将对方对您主机的联机传递到 8080 啰! 范例六:进行封包的伪装,将来自 192.168.0.0/24 的封包的来源 IP 伪装成为 本机的 ppp0 那个界面的 IP
[root@test root]# iptables -t nat -A POSTROUTING -s 192.168.0.0/24
> -o ppp0 -j MASQUERADE
纪录与回复防火墙规则 刚刚上面我们谈了很多的设定了,那么我该如何观察目前主机上面的防火墙规则呢?我们可以使用『iptables -L -n 』来观察,不过,该指令所显示的信息其实还是不太足够的!这个时候,我们其实可以使用底下的两个指令来将目前主机上面的防火墙机制『储存』下来,在下次想要将这个规则『回复』的时候,就能够直接利用指令将规则直接回复喔
[root@test root]# iptables-save > filename
# 将目前的防火墙机制储存成 filename 那个档案!该档案为 ASCII 格式,
# 您可以进入查阅一下喔!
[root@test root]# iptables-restore < filename
# 将 filename 那个防火墙档案 (注意!并不是 shell scripts 的格式) 的规则
# 读入目前的 Linux 主机环境中!