Jan
5
元旦出外逛了逛,回来马上就上班,挺累的。
好久以前就接触过iptables,也就是刚学习linux的时候,几乎每个人都是先从用他做防火墙开始认识的。但今天,我重新回顾了一下iptables,感觉理解的东西不一样了,有兴趣就写写。
一、介绍
iptables是目前linux内核自带的一套非常优秀的防火墙工具,无论是2.4或2.6核心使用的都是它。需要说明的是,它是基于网络层的,也就是只能实现网络层的功能,不要和应用层的防火墙搞混了。
官网地址:netfilter
二、基础
命令格式
iptables都是类似这样的结构建立各种规则,并从上往下执行。通过的话执行下面的匹配,但扔掉的数据表就不会参与下面的语句操作了。
1、table表
表是指包含有要处理的信息包的规则和链的过滤信息。默认有三个可供使用的表:filter、nat和mangle。若不指定,则用filter作为缺省表。
filter表:
用于过滤数据包,几乎所有的target都可以里面使用;
nat表:
用于网络地址转换(NAT),属于一个流的包只会经过这个表一次。如果第一个包被允许做NAT,那么余下的包都会自动地被做同样的操作。(也就是说,只要一个流的第一个包通过了NAT,那余下的包都会被NAT,而且是自动进行的)所以,这个表里面一般不会做任何的过滤;它可以进行的操作有:
◎SNAT:改变包的源地址,也就是网络共享;
◎DNAT:反向NAT,改变的是目标地址,可以用于内网服务器的发布;
◎MASQUERADE:类似SNAT,但它不用指定源地址,可以使用动态源地址,特别适用于拨号网络的共享;
Mangle表:
用于改表包及包头的内容,但并不是真正的改动数据包,只是在内核空间为包设定一个标记,那其他的规则或程序就可以使用这种标记堆包进行过滤或高级路由。它改变的是数据包的以下几个值:
◎TOS:设置数据包的服务类型域,常用于指定数据包如何被路由。不过,Internet的路由器不会注意这个值,所以不要用于Internet上。
◎TTL:设置数据包的生存时间域,数据包经过一个路由节点,TTL就会减少一次,通过设置这个值可以给数据包固定一个值,以避免给其他程序发现经过的路由次数。
◎MARK:给数据包设置特殊的标记,用这些标记,配合支持的软件包iproute2等,就可以做出带宽限制和基于QoS等。
2、command命令
命令很重要,它决定了链里面的规则和规则的顺序。
3、match匹配
指定那些是匹配规则的数据包。可以分开几个类:
◎第一类是通用匹配,适用于所有的规则;
◎第二类是TCP匹配,也就是只对TCP有效;
◎第三类是UDP匹配,当然就是只针对UDP啦;
◎第四类是ICMP包匹配;
◎最后一类是针对状态的,指所有者和访问的频率限制;
-i :流入的网卡
-o :流出的网卡
interface :网卡接口,例如 ppp0, eth0, wlan0等
-p :小写!封包的协定啦!
TCP :封包为 TCP 协定的封包;
UDP :封包为 UDP 协定的封包;
-s :来源数据包的 IP 或者是 Network ( 网络 );
--sport:来源主机的 port 号码;
-d :目标数据包的 IP 或者是 Network ( 网络 );
--dport:目标主机的 port 号码;
4、target目标
目标就是说规则指定的操作,只要匹配规则的数据包就会执行target的操作。比较常用的就是ACCEPT、DROP、LOG、REJECT、REDIRECT、MASQUERADE等。
除了上述的几个参数外,要用好iptables还需要理解几个概念:
5、Chain链和Policy策略
在讲解前,我们先来看看默认的状态:
上面的是默认表filter内建的链以及每个链的策略。
链:可以理解为表里的多层结构,数据包都是从上往下匹配和过滤的;
策略:就是每个链的默认执行操作,当数据包通过链,但匹配不到的时候,就会执行策略指定的操作。
在filter表里面,包含的链有:
INPUT:进入防火墙的阶段;
FORWARD:流过防火墙路由的阶段;
OUTPUT:离开防火墙的阶段;
正如上面提到的,除了filter表以外,还有nat和mangle表:
nat表和filter表不同在于,有PREROUTING和POSTROUTING链:
PREROUTING:在包刚到达防火墙,未进入路由的阶段;通常是改变它的目的地址(否则防火墙就不认识该数据包,而直接扔掉了);
POSTROUTING:在包已经离开路由,准备离开防火墙之前改变的阶段;通常是改变其源地址(让应答也是回到防火墙);
OUTPUT:由于本地产生的包不经过路由,用它来改变本地产生包的目的地址;
mangle表能够给数据包打上标记,或者将一个由Netfilter维护的值与数据包联系起来,也可以在把数据包送到目的地址之前对其进行修改。由于mangle表改变的信息不同,所以可以使用的链定义有点不同:
PREROUTING:指定了当入站数据到达接口,但还没有做出任何路由或本地传递的决定时,对数据包所做的修改;
INPUT:指定数据包处理时对数据包所做的修改,但要在通过PREROUTING链后使用;
FORWARD:指定了对转发出防火墙的数据包所做的修改;
OUTPUT:指定了对本地产生的出站数据包所做的修改;
POSTROUTING:指定了数据包将要出防火墙时,对数据包所做的修改,但要通过OUTPUT链后使用。
对于TOS字段来说,本地Linux路由可以被配置用以支持mangle表或本地主机设置的TOS标记。除此以外,也被用于Linux中服务质量的实现,或作为iptables模块间的通信标志。
6、conntrack连接跟踪
connection tracking连接跟踪也叫状态机制,也就是说在iptables里,包是被跟踪的,有四个状态:NEW、ESTABLISHED、RELATED、INVALID。
◎NEW:就是conntrack模块看到的第一个包,只要是首次进入的就被认为是NEW;
◎ESTABLISHED:只要发送并接受到应答的,就是这个状态;包括经过防火墙的包和ICMP的错误包、重定向包等等都是;
◎RELATED:在有一个ESTABLISHED连接,并由这个连接在产生一个主连接外的连接,那这个新的连接就是RELATED了;(比较难理解?想想ftp?)
◎INVALID:所有错误的信息,如ICMP的错误信息等都是它,DROP就可以。
除了本地产生的包由OUTPUT链处理外,所有连接跟踪都是在PREROUTING链里面处理。也就是说iptables会在PREROUTING链里重新计算所有的状态。例如:我们发送一个流的初始包,状态就会在OUTPUT链里被设置为NEW,当我们收到回应包时,状态就会在PREROUTING链里被设置为ESTABLISHED。当第一个包不是本地产生的,那就会在PREROUTING链里被设置为NEW。还有一点,所有状态的改变和计算都是在nat表中的OUTPUT链和PREROUTING链里面完成的。
三、应用
基本了解iptables的用法后,我们从实际的应用实例来看看如何使用。
1、原则
防火墙最基本的原则是:先拒绝所有的数据包,然后再运行需要的。而且一般认为外部来的包是危险的,但内部出去是可以通过的。
2、准备
一般在配置防火墙前,都应该清空一下旧的配置信息和状态:
※小心,如果你是远程连接到主机的,上述的命令最好一次执行,或写到脚本里面,以免出现以外。
3、策略
我们先根据大原则制定策略,以避免没有考虑到的数据包:
※不指定table,默认使用的就是filter表。
我不建议把FORWARD设为DROP,这样会引起很多考虑不到的问题。打开他,然后再其他地方过滤非法的数据包,不失为一个容易配置的方法。
4、定义规则
规则的定义就根据不同的情况来改变了,以下是部分的例子:
iptables -A INPUT -i lo -j ACCEPT
运行来自lo网卡的数据包
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
通过eth0的数据包执行NAT转换(网络共享)
iptables -A INPUT -i eth1 -p TCP -s 10.0.0.0/8 -j ACCEPT
允许来自10.0.0.0/8网段,并且通过eth1进来的TCP数据包
iptables -A INPUT -i eth1 -p TCP -s 10.0.0.5 -j DROP
但来自10.0.0.5的TCP数据包就扔掉(不给进来)
iptables -A INPUT -i eth1 -p TCP --dport 21 -j DROP
只要从eth1进来,访问21端口的就扔掉
iptables -A INPUT -i eth1 -p TCP -s 10.0.0.1 --dport 22 -j ACCEPT
从10.0.0.1通过eth1进来,访问22端口的,就给它通过
iptables -A FORWARD -i eth0 -o eth1 -m state --state RELATED,ESTABLISHED -j ACCEPT
对于通过eth0流入,eth1流出的数据包,只在RELATED和ESTABLISHED状态下才能通过
(这也就是说,流入的数据包只有在属于一个已经存在的连接时才时允许的,但由外部直接发起的连接时禁止的)
iptables -A INPUT -i eth0 -p tcp --syn -j DROP
当本地没有对外提供服务的时候,是不应该收到syn标识的TCP数据包的,用此规则就可以直接把这些包扔掉
iptables -t nat -A PREROUTING -p tcp --dport 8000 -i eth0 -j DNAT --to-destination 192.168.0.20:8000
把从eth0进来访问8000端口的数据流,转到内部的192.168.0.20机器上。(发布内网服务器)
iptables -t nat -A PREROUTING -p tcp --dport 8000 -i eth0 -j redirect --to-port 80
把从eth0进来访问8000端口的数据流转到80端口(端口重定向,配合squid做透明代理)
5、保存和调用
使用脚本更改规则,那每次调用iptables命令的时候,需要从内核空间中把整个规则提出出来,然后再增加、插入和更改,这样效率就很低。
我们可以使用两个命令解决此问题:
iptables-save运行一次就可以从内核提出整套的规则集,通过标准输出到文件里。这样,我们根据实际情况,直接修改此文件。然后用:
iptables-restore可以导入一个整个规则表,这样就避免了反复加载规则的问题。
通常的情况是,我们用iptables命令动态的修改规则表,如果确认没有问题的话,就保存到文件里面,再下次直接载入即可。(直接输入命令需要留意先后次序,小心匹配问题)
※2006-01-05 第一次编写
※2006-01-09 修改部分错误,整理
好久以前就接触过iptables,也就是刚学习linux的时候,几乎每个人都是先从用他做防火墙开始认识的。但今天,我重新回顾了一下iptables,感觉理解的东西不一样了,有兴趣就写写。
一、介绍
iptables是目前linux内核自带的一套非常优秀的防火墙工具,无论是2.4或2.6核心使用的都是它。需要说明的是,它是基于网络层的,也就是只能实现网络层的功能,不要和应用层的防火墙搞混了。
官网地址:netfilter
二、基础
命令格式
iptables [-t table] command [match] [target]
iptables都是类似这样的结构建立各种规则,并从上往下执行。通过的话执行下面的匹配,但扔掉的数据表就不会参与下面的语句操作了。
1、table表
表是指包含有要处理的信息包的规则和链的过滤信息。默认有三个可供使用的表:filter、nat和mangle。若不指定,则用filter作为缺省表。
filter表:
用于过滤数据包,几乎所有的target都可以里面使用;
nat表:
用于网络地址转换(NAT),属于一个流的包只会经过这个表一次。如果第一个包被允许做NAT,那么余下的包都会自动地被做同样的操作。(也就是说,只要一个流的第一个包通过了NAT,那余下的包都会被NAT,而且是自动进行的)所以,这个表里面一般不会做任何的过滤;它可以进行的操作有:
◎SNAT:改变包的源地址,也就是网络共享;
◎DNAT:反向NAT,改变的是目标地址,可以用于内网服务器的发布;
◎MASQUERADE:类似SNAT,但它不用指定源地址,可以使用动态源地址,特别适用于拨号网络的共享;
Mangle表:
用于改表包及包头的内容,但并不是真正的改动数据包,只是在内核空间为包设定一个标记,那其他的规则或程序就可以使用这种标记堆包进行过滤或高级路由。它改变的是数据包的以下几个值:
◎TOS:设置数据包的服务类型域,常用于指定数据包如何被路由。不过,Internet的路由器不会注意这个值,所以不要用于Internet上。
◎TTL:设置数据包的生存时间域,数据包经过一个路由节点,TTL就会减少一次,通过设置这个值可以给数据包固定一个值,以避免给其他程序发现经过的路由次数。
◎MARK:给数据包设置特殊的标记,用这些标记,配合支持的软件包iproute2等,就可以做出带宽限制和基于QoS等。
2、command命令
命令很重要,它决定了链里面的规则和规则的顺序。
引用
--append -A chain
附加一条新规则
--delete -D chain [rulenum]
删除一条已有的规则(可以直接指定规则号),规则号从1开始。
--insert -I chain [rulenum]
插入一条规则(默认是1)
--replace -R chain rulenum
替换一条已用的规则
--list -L [chain]
列举链里所有的规则
--flush -F [chain]
删除链里所有的规则
--zero -Z [chain]
重置链里所有规则的状态
--new -N chain
新建一个用户自定义的链
--delete-chain -X [chain]
删除用户自定义的链
--policy -P chain target
改变链的策略
--rename-chain -E old-chain new-chain
更改链的名称
附加一条新规则
--delete -D chain [rulenum]
删除一条已有的规则(可以直接指定规则号),规则号从1开始。
--insert -I chain [rulenum]
插入一条规则(默认是1)
--replace -R chain rulenum
替换一条已用的规则
--list -L [chain]
列举链里所有的规则
--flush -F [chain]
删除链里所有的规则
--zero -Z [chain]
重置链里所有规则的状态
--new -N chain
新建一个用户自定义的链
--delete-chain -X [chain]
删除用户自定义的链
--policy -P chain target
改变链的策略
--rename-chain -E old-chain new-chain
更改链的名称
3、match匹配
指定那些是匹配规则的数据包。可以分开几个类:
◎第一类是通用匹配,适用于所有的规则;
◎第二类是TCP匹配,也就是只对TCP有效;
◎第三类是UDP匹配,当然就是只针对UDP啦;
◎第四类是ICMP包匹配;
◎最后一类是针对状态的,指所有者和访问的频率限制;
引用
-i :流入的网卡
-o :流出的网卡
interface :网卡接口,例如 ppp0, eth0, wlan0等
-p :小写!封包的协定啦!
TCP :封包为 TCP 协定的封包;
UDP :封包为 UDP 协定的封包;
-s :来源数据包的 IP 或者是 Network ( 网络 );
--sport:来源主机的 port 号码;
-d :目标数据包的 IP 或者是 Network ( 网络 );
--dport:目标主机的 port 号码;
4、target目标
目标就是说规则指定的操作,只要匹配规则的数据包就会执行target的操作。比较常用的就是ACCEPT、DROP、LOG、REJECT、REDIRECT、MASQUERADE等。
除了上述的几个参数外,要用好iptables还需要理解几个概念:
5、Chain链和Policy策略
在讲解前,我们先来看看默认的状态:
引用
# iptables -t filter -L
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
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
上面的是默认表filter内建的链以及每个链的策略。
链:可以理解为表里的多层结构,数据包都是从上往下匹配和过滤的;
策略:就是每个链的默认执行操作,当数据包通过链,但匹配不到的时候,就会执行策略指定的操作。
在filter表里面,包含的链有:
INPUT:进入防火墙的阶段;
FORWARD:流过防火墙路由的阶段;
OUTPUT:离开防火墙的阶段;
正如上面提到的,除了filter表以外,还有nat和mangle表:
引用
# iptables -t nat -L
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 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
nat表和filter表不同在于,有PREROUTING和POSTROUTING链:
PREROUTING:在包刚到达防火墙,未进入路由的阶段;通常是改变它的目的地址(否则防火墙就不认识该数据包,而直接扔掉了);
POSTROUTING:在包已经离开路由,准备离开防火墙之前改变的阶段;通常是改变其源地址(让应答也是回到防火墙);
OUTPUT:由于本地产生的包不经过路由,用它来改变本地产生包的目的地址;
引用
# iptables -t mangle -L
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
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
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
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
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
mangle表能够给数据包打上标记,或者将一个由Netfilter维护的值与数据包联系起来,也可以在把数据包送到目的地址之前对其进行修改。由于mangle表改变的信息不同,所以可以使用的链定义有点不同:
PREROUTING:指定了当入站数据到达接口,但还没有做出任何路由或本地传递的决定时,对数据包所做的修改;
INPUT:指定数据包处理时对数据包所做的修改,但要在通过PREROUTING链后使用;
FORWARD:指定了对转发出防火墙的数据包所做的修改;
OUTPUT:指定了对本地产生的出站数据包所做的修改;
POSTROUTING:指定了数据包将要出防火墙时,对数据包所做的修改,但要通过OUTPUT链后使用。
对于TOS字段来说,本地Linux路由可以被配置用以支持mangle表或本地主机设置的TOS标记。除此以外,也被用于Linux中服务质量的实现,或作为iptables模块间的通信标志。
6、conntrack连接跟踪
connection tracking连接跟踪也叫状态机制,也就是说在iptables里,包是被跟踪的,有四个状态:NEW、ESTABLISHED、RELATED、INVALID。
◎NEW:就是conntrack模块看到的第一个包,只要是首次进入的就被认为是NEW;
◎ESTABLISHED:只要发送并接受到应答的,就是这个状态;包括经过防火墙的包和ICMP的错误包、重定向包等等都是;
◎RELATED:在有一个ESTABLISHED连接,并由这个连接在产生一个主连接外的连接,那这个新的连接就是RELATED了;(比较难理解?想想ftp?)
◎INVALID:所有错误的信息,如ICMP的错误信息等都是它,DROP就可以。
除了本地产生的包由OUTPUT链处理外,所有连接跟踪都是在PREROUTING链里面处理。也就是说iptables会在PREROUTING链里重新计算所有的状态。例如:我们发送一个流的初始包,状态就会在OUTPUT链里被设置为NEW,当我们收到回应包时,状态就会在PREROUTING链里被设置为ESTABLISHED。当第一个包不是本地产生的,那就会在PREROUTING链里被设置为NEW。还有一点,所有状态的改变和计算都是在nat表中的OUTPUT链和PREROUTING链里面完成的。
三、应用
基本了解iptables的用法后,我们从实际的应用实例来看看如何使用。
1、原则
防火墙最基本的原则是:先拒绝所有的数据包,然后再运行需要的。而且一般认为外部来的包是危险的,但内部出去是可以通过的。
2、准备
一般在配置防火墙前,都应该清空一下旧的配置信息和状态:
# iptables -F;iptables -X;iptables -Z;
※小心,如果你是远程连接到主机的,上述的命令最好一次执行,或写到脚本里面,以免出现以外。
3、策略
我们先根据大原则制定策略,以避免没有考虑到的数据包:
引用
iptables -P INPUT DROP
iptables -P FORWARD ACCEPT
iptables -P OUTPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -P OUTPUT ACCEPT
※不指定table,默认使用的就是filter表。
我不建议把FORWARD设为DROP,这样会引起很多考虑不到的问题。打开他,然后再其他地方过滤非法的数据包,不失为一个容易配置的方法。
4、定义规则
规则的定义就根据不同的情况来改变了,以下是部分的例子:
引用
iptables -A INPUT -i lo -j ACCEPT
运行来自lo网卡的数据包
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
通过eth0的数据包执行NAT转换(网络共享)
iptables -A INPUT -i eth1 -p TCP -s 10.0.0.0/8 -j ACCEPT
允许来自10.0.0.0/8网段,并且通过eth1进来的TCP数据包
iptables -A INPUT -i eth1 -p TCP -s 10.0.0.5 -j DROP
但来自10.0.0.5的TCP数据包就扔掉(不给进来)
iptables -A INPUT -i eth1 -p TCP --dport 21 -j DROP
只要从eth1进来,访问21端口的就扔掉
iptables -A INPUT -i eth1 -p TCP -s 10.0.0.1 --dport 22 -j ACCEPT
从10.0.0.1通过eth1进来,访问22端口的,就给它通过
iptables -A FORWARD -i eth0 -o eth1 -m state --state RELATED,ESTABLISHED -j ACCEPT
对于通过eth0流入,eth1流出的数据包,只在RELATED和ESTABLISHED状态下才能通过
(这也就是说,流入的数据包只有在属于一个已经存在的连接时才时允许的,但由外部直接发起的连接时禁止的)
iptables -A INPUT -i eth0 -p tcp --syn -j DROP
当本地没有对外提供服务的时候,是不应该收到syn标识的TCP数据包的,用此规则就可以直接把这些包扔掉
iptables -t nat -A PREROUTING -p tcp --dport 8000 -i eth0 -j DNAT --to-destination 192.168.0.20:8000
把从eth0进来访问8000端口的数据流,转到内部的192.168.0.20机器上。(发布内网服务器)
iptables -t nat -A PREROUTING -p tcp --dport 8000 -i eth0 -j redirect --to-port 80
把从eth0进来访问8000端口的数据流转到80端口(端口重定向,配合squid做透明代理)
5、保存和调用
使用脚本更改规则,那每次调用iptables命令的时候,需要从内核空间中把整个规则提出出来,然后再增加、插入和更改,这样效率就很低。
我们可以使用两个命令解决此问题:
#iptables-save > iptables-script
iptables-save运行一次就可以从内核提出整套的规则集,通过标准输出到文件里。这样,我们根据实际情况,直接修改此文件。然后用:
iptables-restore iptables-script
iptables-restore可以导入一个整个规则表,这样就避免了反复加载规则的问题。
通常的情况是,我们用iptables命令动态的修改规则表,如果确认没有问题的话,就保存到文件里面,再下次直接载入即可。(直接输入命令需要留意先后次序,小心匹配问题)
※2006-01-05 第一次编写
※2006-01-09 修改部分错误,整理