Netfilter/Iptables(以下简称Iptables)是unix/linux自带的一款优秀且开放源代码的完全自由的基于包过滤的防火墙工具,它的功能十分强大,使用非常灵活,可以对流入和流出服务器的数据包进行很精细的控制。Iptables主要工作在OSI七层的二、三、四层。
Iptables 是Linux 内核集成的 IP 信息包过滤系统。如果Linux 系统连接到因特网或 LAN、服务器或连接 LAN 和因特网的代理服务器, 则该系统有利于在 Linux 系统上更好地控制 IP 信息包过滤和防火墙配置。
防火墙在做信息包过滤决定时,有一套遵循和组成的规则,这些规则存储在专用的信息包过滤表中,而这些表集成在 Linux 内核中。在信息包过滤表中,规则被分组放在我们所谓的链(chain)中。而netfilter/iptables IP 信息包过滤系统是一款功能强大的工具,可用于添加、编辑和移除规则。
虽然Netfilter/iptables IP 信息包过滤系统被称为单个实体,但它实际上由两个组件netfilter 和 iptables 组成。
Netfilter 组件也称为内核空间(kernelspace),是内核的一部分,由一些信息包过滤表组成,这些表包含内核用来控制信息包过滤处理的规则集。
Iptables 组件是一种工具,也称为用户空间(userspace),它使插入、修改和除去信息包过滤表中的规则变得容易。
Iptables的规则链分为三种:输入、转发和输出。
输入——这条链用来过滤目的地址是本机的连接。例如,如果一个用户试图使用SSH登陆到你的PC/服务器,iptables会首先匹配其IP地址和端口到iptables的输入链规则。转发——这条链用来过滤目的地址和源地址都不是本机的连接。例如,路由器收到的绝大数数据均需要转发给其它主机。如果你的系统没有开启类似于路由器的功能,如NATing,你就不需要使用这条链。输出——这条链用来过滤源地址是本机的连接。例如,当你尝试ping linuxer.org 时,iptables会检查输出链中与ping和 linuxer.org 相关的规则,然后决定允许还是拒绝你的连接请求。注意:当ping一台外部主机时,看上去好像只是输出链在起作用。但是请记住,外部主机返回的数据要经过输入链的过滤。当配置iptables规则时,请牢记许多协议都需要双向通信,所以你需要同时配置输入链和输出链。人们在配置SSH的时候通常会忘记在输入链和输出链都配置它。
数据包先经过PREOUTING,由该链确定数据包走向:
目的地址是本地,则发送到INPUT,让INPUT决定是否接收下来送到用户空间,流程为①—>②;若满足PREROUTING的nat表上的转发规则,则发送给FORWARD,然后再经过POSTROUTING发送出去,流程为: ①—>③—>④—>⑥;主机发送数据包时,流程则是⑤—>⑥;其中PREROUTING和POSTROUTING指的是数据包的流向,如上图所示POSTROUTING指的是发往公网的数据包,而PREROUTING指的是来自公网的数据包。iptables具有Filter, NAT, Mangle, Raw四种内建表。
Filter表示iptables的默认表,因此如果你没有自定义表,那么就默认使用filter表,它具有以下三种内建链:
INPUT链 – 处理来自外部的数据;OUTPUT链 – 处理向外发送的数据;FORWARD链 – 将数据转发到本机的其他网卡设备上。NAT (网络地址转换) 技术在平时是很多见的,如家庭中在使用路由器共享上网时,一般用的就是 NAT 技术,它可以实现众多内网 IP 共享一个公网 IP 上网。
NAT 的原理,简单的说就是当内网主机访问外网时,当内网主机的数据包要通过路由器时,路由器将数据包中的源内网 IP 地址改为路由器上的公网 IP 地址,同时记录下该数据包的消息;
外网服务器响应这次由内而外发出的请求或数据交换时,当外网服务器发出的数据包经过路由器时,原本是路由器上的公网 IP 地址被路由器改为内网 IP 。
SNAT 和 DNAT 是 iptables 中使用 NAT 规则相关的的两个重要概念。如上图所示,如果内网主机访问外网而经过路由时,源 IP 会发生改变,这种变更行为就是 SNAT;反之,当外网的数据经过路由发往内网主机时,数据包中的目的 IP (路由器上的公网 IP) 将修改为内网 IP,这种变更行为就是 DNAT 。NAT表有三种内建链:
PREROUTING链 – 处理刚到达本机并在路由转发前的数据包。它会转换数据包中的目标IP地址(destination ip address),通常用于DNAT(destination NAT)。POSTROUTING链 – 处理即将离开本机的数据包。它会转换数据包中的源IP地址(source ip address),通常用于SNAT(source NAT)。OUTPUT链 – 处理本机产生的数据包。iptables命令是Linux上常用的防火墙软件,是netfilter项目的一部分。可以直接配置,也可以通过许多前端和图形界面配置,命令格式如下:
[root@localhost ~]# iptables [选项] [参数] iptables命令选项输入顺序: [root@localhost ~]# iptables -t 表名 <-A/I/D/R> 规则链名 [规则号] <-i/o 网卡名> -p 协议名 <-s 源IP/源子网> --sport 源端口 <-d 目标IP/目标子网> --dport 目标端口 -j 动作 选项说明-t <表>指定要操纵的表;-A顺序添加,向规则链中添加新规则;-D从规则链中删除条目,-D 后面加一数字表示删除哪行规则;-I插入,插入一条新规则,-I 后面加一数字表示插入到哪行前面;-R替换规则链中的条目,-R 后面加一个数字表示替换哪行规则;-i <数据包进入的网卡>指定数据包进入本机的网络接口;-o <数据包出口的网卡>指定数据包要离开本机所使用的网络接口。-p tcp/udp/icmp指定要匹配的数据包协议类型;-s指定要匹配的数据包源ip地址;-d指定要匹配的数据包目的ip地址–sport port指定源端口–dport port指定目标端-j <目标>指定要跳转的目标;-L显示规则链中已有的条目;-n表示以数字形式显示真实IP地址–line-numbers表示显示规则序列号-F清楚规则链中已有的条目;-Z清空规则链中的数据包计算器和字节计数器;-N创建新的用户自定义规则链;-X删除一个自定义链,删除之前要保证次链是空的,而且没有被引用;-P定义规则链中的默认规则;-h显示帮助信息;-E重命名链;扩展匹配:除了上述的条件可以用于匹配,还有很多其他的条件可以用于匹配,这些条件泛称为扩展条件,这些扩展条件其实也是netfilter中的一部分,只是以模块的形式存在,如果想要使用这些条件,则需要依赖对应的扩展模块。
扩展匹配说明-m state --state匹配状态的-m multiport --source-port端口匹配,指定一组端口;多个端口格式为:80,81;范围格式为:79:81;-m limit --limit 3/minute任意IP每分种访问3次-m limit --limit-burst 5只匹配5个数据包-m string --string --algo bmkmp --string"xxxx"-mtime–timestart 8:00 --timestop 12:00表示从哪个时间到哪个时间段-mtime–days表示哪天-m mac --mac-source xx:xx:xx:xx:xx:xx匹配源MAC地址-m layer7 --l7proto qq表示匹配腾讯qq的 当然也支持很多协议,这个默认是没有的,需要我们给内核打补丁并重新编译内核及iptables才可以使用 -m layer7 这个显示扩展匹配表名包括:
表名说明raw高级功能,如mangle数据包修改(QOS),用于实现服务质量。net地址转换,用于网关路由器。filter包过滤,用于防火墙规则。规则链名包括:
规则链名说明INPUT处理输入数据包。OUTPUT处理输出数据包。PORWARD处理转发数据包。PREROUTING用于目标地址转换(DNAT)。POSTOUTING用于源地址转换(SNAT)。动作包括:
动作说明ACCEPT接收数据包。DROP丢弃数据包。REJECT丢掉数据包,但是回复信息;REDIRECT重定向、映射、透明代理。SNAT源地址转换。DNAT目标地址转换。MASQUERADEIP伪装(NAT),用于ADSL。LOG, --log-prefix “说明信息,自己随便定义”日志记录。下面来介绍一下,我添加的每个参数是什么意思,跟我讲得允许22端口的一样:
-A INPUT -m state –state NEW -m tcp -p tcp –dport 22 -j ACCEPT 说明: -A:最后添加一条规则 -j:后面接动作,主要的动作有接受(ACCEPT)、丢弃(DROP)、拒绝(REJECT)及记录(LOG) –dport:限制目标的端口号码。 -p 协议:设定此规则适用于哪种封包格式 主要的封包格式有: tcp, udp, icmp 及 all 。 -m state –state:模糊匹配一个状态, NEW:用户发起一个全新的请求 ESTABLISHED:对一个全新的请求进行回应 RELATED:两个完整连接之间的相互关系,一个完整的连接,需要依赖于另一个完整的连接。 INVALID:无法识别的状态。注意:IPtables规则文件中的规则是从上往下执行的,所以规则的顺序很重要!
当在服务器安装好iptables软件之后,首先看看规则文件中默认的规则都有哪些,命令如下:
[root@localhost ~]# iptables -L -n --line-numbers #该命令是查询当前系统内存中的规则 Chain INPUT (policy ACCEPT) num target prot opt source destination 1 ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED 2 ACCEPT icmp -- 0.0.0.0/0 0.0.0.0/0 3 ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 4 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:22 5 REJECT all -- 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited Chain FORWARD (policy ACCEPT) num target prot opt source destination 1 REJECT all -- 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited Chain OUTPUT (policy ACCEPT) num target prot opt source destination COMMIT在这里重点关注的是filter表中第5条规则,意思是拒绝所有其他不符合上述任何一条规则的数据包。并且发送一条host prohibited的消息给被拒绝的主机。所以如果我们需要添加规则则需要添加到此项规则前面才行,否则在第5条规则就会被拒绝,那么下面的规则也就补齐作用了。
WEB服务器,开启80端口; [root@localhost ~]# iptables -t filter -I INPUT 5 -p tcp --dport 80 -j ACCEPT [root@localhost ~]# iptables -t filter -A OUTPUT -p tcp --sport 80 -j ACCEPT我们来解释下:当客户端访问服务器的web服务时,客户端发送报文到网卡,而tcp/ip协议栈是属于内核的一部分,所以,客户端的信息会通过内核的TCP协议传输到用户空间中的web服务中,而此时,客户端报文的目标终点为web服务所监听的套接字(IP:Port)上,所以在INPUT中使用“–dport 80”;当web服务需要响应客户端请求时,web服务发出的响应报文的目标终点则为客户端,这个时候,web服务所监听的IP与端口反而变成了原点,所以在OUPUT中需要使用“–sport 80”;如下图所示:
邮件服务器,开启25,110端口; [root@localhost ~]# iptables -A INPUT -p tcp --dport 110 -j ACCEPT [root@localhost ~]# iptables -A INPUT -p tcp --dport 25 -j ACCEPT #上面的两条规则也可以合并为一条规则,命令如下: [root@localhost ~]# iptables -A INPUT -m multiport -p tcp --dport 25,110 -j ACCEPT FTP服务器,开启21,20端口 [root@localhost ~]# iptables -A INPUT -p tcp --dport 21 -j ACCEPT [root@localhost ~]# iptables -A INPUT -p tcp --dport 20 -j ACCEPT 或 [root@localhost ~]# iptables -A INPUT -m multiport -p tcp --dport 20,21 -j ACCEPT DNS服务器,开启53端口 [root@localhost ~]# iptables -A INPUT -p tcp --dport 53 -j ACCEPT 允许icmp包通过,也就是允许ping, [root@localhost ~]# iptables -A OUTPUT -p icmp -j ACCEPT #如果默认OUTPUT规则设置成DROP了,那么在下面的规则中必须添加一个单独的OUTPUT,否则会采用默认的OUTPUT规则 [root@localhost ~]# iptables -A INPUT -p icmp -j ACCEPT #同理,如果默认INPUT设置成DROP的了,那么下面的规则必须单独添加INPUT规则,否则会采用默认的INPUT规则注意:iptables默认规则的优先级低于单独设置的规则。
将本机的80端口转发至本机的8080端口; 将本机的8080端口转发至其他主机80端口,主机IP:192.168.100.120,目标主机IP和端口:192.168.100.100:80,规则如下; [root@localhost ~]# iptables -t nat -A PREROUTING -d 192.168.100.120/32 -p tcp -m tcp --dport 8080 -j DNAT --to-destination 192.168.100.100:80 [root@localhost ~]# iptables -t nat -A POSTROUTING -d 192.168.100.100/32 -p tcp -m tcp --dport 80 -j SNAT --to-source 192.168.100.120 [root@localhost ~]# echo 1 > /proc/sys/net/ipv4/ip_forward #同时开启iptables forward转发功能。 查看当前内存中的iptables规则; [root@localhost ~]# iptables -t filter -L -n --line-numbers #其中-L表示显示匹配规则类别,-t指定表,-n表示以数字形式显示真实IP地址,--line-numbers表示显示规则序列号 [root@localhost ~]# iptables -L -v #输出详细信息,包含通过该规则的数据包数量,总字节数及相应的网络接口 [root@localhost ~]# iptables -L -x #显示精确信息 保存iptables规则: [root@localhost ~]# service iptables save 或 [root@localhost ~]# iptables-save > /etc/sysconfig/iptables #iptables-save 打印当前内存中的规则生产环境,线上门户网站iptables规则策略如下:
[root@localhost ~]# vim /etc/sysconfig/iptables #Generated by iptables-save v1.4.7 on Wed Dec 14 21:05:31 2016 *filter :INPUT ACCEPT [0:0] :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [602:39593] -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT ######################### -A INPUT -i lo -j ACCEPT -A INPUT -s 116.22.202.146 -j DROP -A INPUT -s 139.224.227.121 -j ACCEPT ########################## -A INPUT -p icmp -j ACCEPT -A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT -A INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT -A INPUT -p tcp -m state --state NEW -m tcp --dport 443 -j ACCEPT -A INPUT -s 116.243.139.7 -p tcp -m state --state NEW -m tcp --dport 7001 -j ACCEPT -A INPUT -p tcp -m state --state NEW -m tcp --dport 8801 -j ACCEPT -A INPUT -p tcp -m state --state NEW -m tcp --dport 25 -j ACCEPT -A INPUT -p tcp -m state --state NEW -m tcp --dport 110 -j ACCEPT #### -A INPUT -j REJECT --reject-with icmp-host-prohibited -A FORWARD -j REJECT --reject-with icmp-host-prohibited COMMIT #Completed on Wed Dec 14 21:05:31 2016