iptables的原理及使用
Linux内核里有一个称为Netfilter的子系统,当包经过内核时,必须依次通过此子系统的各个检查点。管理员可使用一个user-space机制 (iptables命令),在各检查点设置过滤规则,借此架设IP防火墙。Netfilter可对包采取三种处理方式: 过滤(filtering)、拆分(mangling)、转址(Network Address Translation, NAT)。“过滤"是在包到达检查点时,判断是否应该让包通往下一站。凡是会修改包内容的行为,都统称为”拆分"。NAT是改变包的来源地址、来源端口、目的地址、目的端口,在无形中影响包的去处或改变外界对包来源的认知。实际上,NAT只是“拆分”的一种特殊应用。
过滤IP包
当包从网络接口进入Linux内核后,会依次通过一系列检查点,管理员可以在各检查点设置“过滤规则",这些过滤规则描述"怎样的包”(比对条件)应该给予“怎样的处理"(丢弃、拒绝、通过)。常见的比对条件如下:
- 协议类型:TCP、UDP、ICMP等。
- 通信端口编号(对于TCP/UDP协议)。
- 包类型: SYN/ACK、数据、ICMP Echo Request等。
- 来源地址:发出包的主机的IP地址。
- 目的地址:包的最终接受者的IP地址。
对于符合条件的包,可能的处理方式有下列三种:
- 丢弃(Drop):直接让包消失,包来源不会收到通知。
- 拒绝(Reject):让包消失,但是以ICMP通知包来源。
- 通过(Accept):让包流入下一个检查点。
有个非常重要的概念:IP过滤动作是发生在网络层,这表示Netfilter对于使用网络连接的应用程序一无所知,唯一知道的是网络连接本身。举例来说,假设你想要禁止外界telnet到内部网络主机,为此,你封锁了目的通信端口为23(Telnet的默认通信端口)、从外界通往内部网络的TCP包。然而,这并不能阻止外界使用telnet程序访问内部主机上的其他通信端口。
iptables的概念
iptables在内核对于包的处理过程中定义了五个"检查点"(hook point),每个检查点各对应到一组链,分别是:PREROUTING、INPUT、FORWARD、POSTROUTING与OUTPUT。这些内置的链可供管理员安排过滤表规则,每一条过滤表规则各代表依次监视或影响包流程的机会。
了解iptables的工作原理对于理解其各种命令、参数和选项都非常有帮助,也是设计iptables的基础。开启了iptables后,系统网卡上的各个数据包都会经过iptables的检查和处理。iptables就像一个流水线,各个规则就像流水线上的工人按照一定的顺序排列在流水线上。所有进入iptables的数据包在这个过程中会依次被各个规则检查。
这个图展示了包从网络接口流入系统、通过内核、离开内核(如果没被丢弃的话)的流程。五个方框分别代表iptables的”链“,方框内部是该链可能执行的处理方式(过滤表类型)。仔细观察发现每一个链的第一个过滤表都是mangle,这表示包经过拆分之后,才被交给后续的过滤表继续处理。
检查点的作用
检查点 |
可处理何种状态的包 |
FORWARD |
经过网关(从某接口进来,再从另一个接口出去)的包 |
INPUT |
即将递交给本地进程的包 |
OUTPUT |
本地进程刚产生的包 |
POSTROUTING |
即将进入网络接口而离开的包 |
PREROUTING |
刚从网络接口进入的有效包(因“混杂模式”才得以进入的任何包以及校验码错误的包,会被排除在外) |
规则应该写在哪一个链中,取决于规则应该作用在包的哪一段生命周期。举例来说,如果要过滤出站包,你应该选择OUTPUT链(因为POSTROUTING链没有filter过滤表)。
过滤表
iptables内置了三个过滤表:filter、mangle和nat。各个过滤表被预先设置了几个合适的链(检查点)。
过滤表 | 说明 |
filter | 用于设定"进入”、“穿越”、“离开”三种通信的过滤检查原则。内置的链包括INPUT、FORWARD和OUTPUT |
mangle | 用于执行特殊的包修改程序,比如说,裁掉IP options(此动作须搭配IPV4OPTSSTRIP扩充模块)。本过滤表是五个内置链(FORWARD、INPUT、OUTPUT、POSTROUTING和PREROUTING)的第一站 |
nat | 用于搭配连接跟踪机制来进行转址操作(将穿越包的来源地址和目的地址改成NAT网关的地址)。内置的链包括OUTPUT、POSTROUTING和PREROUTING |
iptables根据包的来源和目的地址,在各个过滤表安排了适当的链(检查点),塑造"包依次经过xxx过滤表的aa、bb、cc链”的假象。
当使用iptables时,若没以-t选项指出要操作的过滤表,iptables会假设你要操作的是filter过滤表。
链
链(chain)本身象征包流程中的特定“检查点”,当包到达某个检查点时,必须依次接受该检查点所包含的一系列过滤规则的考验。若包符合某规则的匹配条件,则以该规则的“目标”来处置该包;相对地,若包不符合规则的匹配条件,则必须继续接受链里的下一条过滤规则的考验;若包成功通过链里的所有规则,则以链的“默认政策”(default policy)来处理包。
系统刚开机时,所有过滤表和链都是空的,直到管理员以iptables命令添加新规则,或是由开机脚本执行iptables-restore加载预先有iptables-save所存储的规则时才会有内容。
除了默认链之外,也可以定义新链来组织你自己的过滤规则。
每一个链都有所谓的默认策略(default policy)。当包成功流过链里的每一条规则,而未被任何规则的“目标”处理过,则以默认策略来处理包。内置链的策略只能是ACCEPT(默认)与DROP这两个内置目标(稍后解释)的其中之一。用户自定义的链,其默认策略为RETURN,不可以改变。
尽管有这些限制,但是仍可以用取巧的方法,改变内置链的“实质策略”:在链末端安装一条所有包都可以符合条件的“完全匹配规则”(match-all),这样,所有到达该规则的包,都会被送到完全匹配规则的目标。运用同样的技巧,我们也可以使自定义链具有RETURN之外的其他实质策略。使用这种末端拦截技术时,可将链的(形式上的)政策改成DROP,借此阻止任何通过完全匹配规则的包。
过滤规则
iptables的过滤规则(rule),由一个或多个匹配条件(match)与一个目标(target)构成,前者用于挑出适合处理的包,后者决定如何处理包。只有同时符合所有匹配条件的包,才会受到过滤规则的影响。
对于每一条规则,系统各维护两个计数器,一个计算包数,另一个计算字节数。每当有包符合匹配条件时,便累加这两个计数值。
匹配条件与目标两者都有选择性。没有明确指定匹配条件时,表示所有包都算。没有明确指定目标时,则除了更新计数器之外,不对包进行任何变动。举例来说,下列命令添加一条“空规则”到filter过滤表的FORWARD链中:# iptables -t filter -A FORWARD 像这样的空规则,常用于累计通过某一检查点的包数(与字节数)。
匹配条件
“匹配条件”(match)的作用是挑出适合处理的包。Linux内核内置了常用的匹配条件,例如,适用于任何IP包的一般性IP(Internet Protocol)匹配条件(像协议类型、来源地址、目的地址)。
有些匹配条件需要用户以-m(或--match)选项来加载额外的扩充模块。比如说,若你想以Ethernet的Media Access Controller (MAC)地址作为匹配条件,则需要另外加载mac模块。
目标
“目标”决定如何处理符合匹配条件的包,也可以用来作为链的默认策略。iptables内置了四种目标,对于其他目标,则需要另外加载扩充模块。
目标 | 说明 |
ACCEPT | 跳过当前链的后续流程,让包进入下一个链 |
DROP | 完全终止后续的处理过程,就当作没收到包一样。包来源不会收到任何通知。如果需要让包来源知道包已被丢弃,请改用REJECT扩充目标 |
QUEUE | 将包交给userspace(内核之外的程序)。细节请参阅 lipipq manpage |
RETURN | 对于用户自定义链中的规则,表示停止该链的后续过滤规则,让包回到先前使得包进入本自定义链的原链,由分支点的下一条过滤规则继续处理;对于内置链中的规则,则跳过链的后续规则,直接以链的默认策略来处理包 |
Linux防火墙的基本安装步骤
首先,必须确定Netfilter被编译进Linux内核。如果你使用厂商提供的内核,这应该不成问题。
加载内核模块
如果将netfilter编译进内核里了,可以直接使用iptables命令而不必另外加载任何模块;相对地,如果将netfilter编译成外挂模块的形式(馊主意!),则必须先以modprobe加载模块:# modprobe ip_tables
当使用到被编译成模块的外挂功能时(例如REJECT目标、tcp匹配条件等),iptables会自动加载相关模块,不必另外以modprobe加载它们。
iptables的操作方法
iptables是用于设定Netfilter的user-space命令,它的语法因为有条理可循,所以不算太复杂。不过,由于扩充模块很多,而每个模块都有自己的特殊选项,所以你可能需要一本小手册以方便查阅。
iptables的基本语法结构如下:
iptables subcmd rule-specification extention
其中的subcmd描述你想操作的过滤表与链、对于链的操作方式(插入、添加、删除、清空)以及表所列的杂项选项。rule-specification描述过滤规则(包括筛选条件与处理目标)。extension是扩充模块的选项。
常用防火墙的配置
1 #清空所有链 2 iptables -F INPUT 3 #删除自定义链 4 iptables -X 5 #将所有链中所有规则的计数值归零 6 iptables -Z 7 #将INPUT链的默认规则改成丢弃 8 iptables -P INPUT DROP 9 #允许本地回环 10 iptables -A INPUT -i lo -j ACCEPT 11 #开放22,80端口允许外网主动访问 12 iptables -A INPUT -p tcp -m multiport --dports 22,80 -j ACCEPT 13 #允许主机主动访问的内容通过 14 iptables -A INPUT -p tcp -m state --state ESTABLISHED -j ACCEPT 15 #允许外网主机ping 16 iptables -A INPUT -m icmp -p icmp --icmp-type ping -j ACCEPT 17 #允许ping外网机器回应的数据包 18 iptables -A INPUT -m icmp -p icmp --icmp-type pong -j ACCEPT 19 #允许接收DNS服务器的返回结果,否则无法使用域名访问 20 iptables -A INPUT -p udp --sport 53 -j ACCEPT
Debian 开启IP转发功能:
两种方式:
- 临时:echo "1">/proc/sys/net/ipv4/ip_forward
- 系统启动时自动开启:
修改/etc/sysctl.conf,取消这一行的注释:net.ipv4.ip_forward= 1 使该配置立即生效可以使用如下命令 sysctl -p 或者 重新启动系统
常用的网络其他命令: