iptables

iptables与Netfilter的关系

iptables很多人都熟知,相比于iptables,Netfilter知道的人就会少很多。

有些人可能也没有明白两者的区别

我们可以先看如下这样的幅图

我们可以看得到的是。iptables是位于用户空间,而Netfilter却是位于内核空间

两者的区别可以归纳于下

Netfilter是官方内核中提供对报文数据包过滤和修改的一个功能,它位于内核中的tcp/ip协议栈的报文处理框架,它可以用于在不同阶段将某些钩子函数(hook)作用域网络协议栈。Netfilter 本身并不对数据包进行过滤,它只是允许可以过滤数据包或修改数据包的函数挂接到内核网络协议栈中的适当位置。这些函数是可以自定义的。

iptables是用户层的工具,它提供命令行接口,能够向 Netfilter 中添加规则策略,从而实现报文过滤,修改等功能。在linux中的这样的工具有很多,在centos6上面是iptables,在centos7上面则是firewalld,不过在7上面的时候,依习惯依然会称为iptables。

可以简单的这样理解,我们驱车旅游,Netfilter是车,而iptables是坐在车里面的人,车并没有对路线选择的能力,但是有车能提供行驶及改变路线的能力,决定是否行驶以及行驶到哪里去,这则是由坐在车里面的人来决定的。

Netfilte为什么能拦截数据

在回答这个问题之前,我们可以看一下通信过程的原理图

数据从发送方送至接收方,是通过光纤这样的基础设备完成,光纤属于物理层,在数据从用户的应用发出之后,通过应用层向下传递,一层一层的进行封装,然后到达物理层之后,通过物理层进行传输,到达接收方物理层之后,再向应用一层一层的解包。

因为这样的封装和解包,所以每段数据上面都会有相应的tag,当数据进行路由之后,会依据对应的tag来决定此数据的动向,是转发出去,还是流入接收。

其整个流程如下:

我们可以看出,Netfilter一共有五个协议栈点,分别是prerouting,input,forward,output,postrouting。

通过这五个栈点,对数据的流向进行管理。

每个链中有都对应的函数,称之为hook函数,这函数可以自定义。当hook函数遇到匹配自身设定规则的数据之后,它会跳出来进行处理,形如hook(钩子)把数据钩一下。如果没有匹配自身规则设定,则不处理。

某个数据在送达至路由前,存在一个prerouting链,如果规则设定中对该类型的数据拒收,而该数据不会流入后面的其它栈点。

表和链的区别

iptables中经常听到的概念就是四表五链,但是这些又都是什么

,我们可以很容易联想到钩子,就是上图中的那五个协议栈中出现的概念。

五链:

PREROUTING
INPUT
FORWARD
OUTPUT
POSTROUTING

,表就是链的集合,多条链的组成,就形成了一张表,也因为不同链之间的组合,所以不同的表对数据有着不同的处理功能。

每个表中均会内置一组链。

常见的表中链的组合如下:

raw:PREROUTING,OUTPUT
mangle:PREROUTING,INPUT,FORWARD,OUTPUT,POSTROUTING
nat:PREROUTING,OUTPUT,POSTROUTING,INPUT(centos 7新增INPUT)
filter:INPUT,FORWARD,OUTPUT

其中nat表中的INPUT是在centos7中新增的

四表的基础功能:

raw:关闭nat表上启用的连接追踪机制
mangle:拆解报文,做出修改,并重新封装起来
nat:network address translation,用于修改报文源地址或目标地址,甚至端口
filter:过滤,防火墙

其实相比于四表,还有一个基础表security,可以通过iptables -t security -vnL查看其中的对应链,不过用的很少。

平时我们所常用的是filter表

其中的链我们可以使用iptables -vnL查看

[root@iZ25la2y7noZ ~]# iptables -vnL
Chain INPUT (policy ACCEPT 21M packets, 1877M 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 21M packets, 31G bytes)
 pkts bytes target     prot opt in     out     source               destination 

可以看到其中有三条链

而查看nat表时,可以看到其中有四条链

[root@iZ25la2y7noZ ~]# iptables -t nat -vnL
Chain PREROUTING (policy ACCEPT 11 packets, 792 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain INPUT (policy ACCEPT 11 packets, 792 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain OUTPUT (policy ACCEPT 8 packets, 3800 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain POSTROUTING (policy ACCEPT 8 packets, 3800 bytes)
 pkts bytes target     prot opt in     out     source               destination   

表的执行优先级

raw-->mangle-->net-->filter

iptables的简单使用

规则编写格式:

iptables [-t table] COMMAND chain [-m matchname [per-match-options]] [-j targetname [per-target-options]]

表类型:- t table

filter:默认类别
net
mangle
raw

管理类命令:

管理链:

	-P:policy,定义默认策略
	-N:new,新建一条自定义规则链
	-F:flush,清空指定的链
	-E:rename chain,重命名自定义的引用计数为零的链
	-X:drop,删除自定义的引用计数为零的链

管理规则:

	-A:append,在指定链的尾部追加一条规则
	-I:insert,在指定位置插入一条规则,默认表示在链首
	-D:delete,删除指定的规则
	-R:replace,替换指定的规则

管理查看:

	-L:list,列出表中链的规则
	-n:numeric,以数值格式显示,不反解
	-v:verbose,显示详细信息
	-x:exactly,显示计数器的精确结果,不进行换算
	--line-number:显示链中的规则编号

管理重置规则计数器:

	-Z:zero,置零

处理动作: -j targetname [per-target-options]

	DROP:丢弃
	ACCEPT:接收
	REJECT:拒绝
	REDIRET:端口转换
		--to-ports port[-port] 指定映射的端口
	SNAT:源地址转换
		--to-source [ipaddr[-ipaddr]][:port[-port]] 指定修改的源地址和端口
	DNAT:目标地址转换
		--to-destination [ipaddr[-ipaddr]][:port[-port]] 指定修改的目标地址和端口
	MASQUERADE:地址伪装
		--to-ports port[-port] 指定伪装的端口
	LOG:日志记录
		--log-prefix 日志前缀样式

匹配条件:

每条规则都包含一组匹配与一个处理动作,只有数据包匹配到规则后,iptables才会依据指定的动作来处理数据

基本匹配:

	[!] -s:soure address,匹配报文的ip源地址
	[!] -d:destination address,匹配报文的ip目标地址
	[!] -i:in interface name,匹配数据报文的流入接口(如eno16777736)
	[!] -o:out interface name,匹配数据报文的流出接口
	[!] -p:protocol,匹配协议类型{tcp|udp.icmp}

扩展匹配:

隐式扩展:

不需要使用-m选项指出match name

		-p tcp:隐含了-m tcp
			[!] --sport port[:port] 匹配报文中tcp的源端口
			[!] --dport port[:port] 匹配报文中tcp的目标端口
			[!] --tcp-flags mask comp
				检查tcp标志位,各标志以逗号分隔,comp中指定的标记必须为1,comp中没出现,而mask中出现的必须为0。
				标志有以下几种: SYN ACK FIN RST URG PSH ALL NONE
			[!] --syn 相当于tcp第一次握手,等价于--tcp-flags  SYN,RST,ACK,FIN  SYN
					相当于SYN=1,RST=0,ACK=0,FIN=0
		-p udp
			[!] --sport port[:port] 匹配报文中的udp源端口
			[!] --dport port[:port] 匹配报文中的udp目标端口
		-p icmp
			[!] --icmp-type {type[/code]|typename} 匹配icmp中的类型
				8:echo-request
				0:echo-reply
显示扩展:

必须使用-m选项指出match name

		-m multiport:多端口匹配
			[!] --sports port[,port|,port:port]...] 匹配多个源端口
			[!] --dports port[,port|,port:port]...] 匹配多个目标端口
			[!]--ports port[,port|,port:port]...] 匹配指定多个端口,
		-m iprange:ip地址范围匹配
			[!] --src-range IPADDR-IPADDR 源地址范围
			[!] --dst-range IPADDR-IPADDR 目标地址范围
		-m string:对应用层数据作字符串匹配
			--algo {bm|kmp} 选择匹配策略,可选择bm或kmp
			[!] --string "STRING" 匹配指定的字符串
			[!] --hex-string "STRING" 十六进制的字符串
		-m time:时间匹配
			--datestart YYYY[-MM[-DD[Thh[:mm[:ss]]]]] 起始时间
			--datestop YYYY[-MM[-DD[Thh[:mm[:ss]]]]] 结束时间
			--timestart hh:mm[:ss]
			--timestop hh:mm[:ss]
			[!] --monthdays day[,day...]
			[!] --weekdays day[,day...]
		-m connlimit:依客户端ip并发连接数作匹配
			--connlimit-upto n 连接数小于n时允许
			--connlimit-above n 连接数大于n时拒绝
		-m limit:基于接收报文速率作匹配
			--limit rate[/second|/minute|/hour|/day] 平均速率
			--limit-burst number N 峰值连接数
		-m state:状态匹配
			--state STATE
			 	有以下五种STATE:
				INVALID:无法识别的状态
				ESTABLISHED:已建立的连接
				NEW:新连接
				RELATED:相关联的连接
				UNTRACKED:未追踪的连接
conntrack机制:
状态检测基于追踪机制(conntrack),负责该功能模块为nf_conntrack
启用nf_conntrack模块
	modprobe nf_conntrack
nf_conntrack模块被nf_nat模块所关联,所以查看nat表即会自动开启nf_conntrack模块
查看是否启用nf_conntrack模块
	lsmod | grep conntrack
查看追踪的连接
	cat /proc/net/nf_conntrack
定义最大追踪数量
	定义在/proc/sys/net/nf_conntrack_max中
定义连接追踪时长
	定义在/proc/sys/net/netfilter/目录中
conntrack机制的实际举例
在iptables中放行ftp服务的访问
	因为ftp服务有两种模式,一种是主动模式,其访问端口为20+1,而被动模式使用随机端口进行访问,故在iptables中直接无法通过设置指定端口来放行ftp服务的访问。在此通过nf_conntrack机制就很容易解决
        iptables -A INPUT -d 172.16.45.21 -p tcp -m state --state ESTABLISHED -j ACCEPT
        iptables -A INPUT -d 172.16.45.21 -p tcp --dprot 21 -m state --state NEW -j ACCEPT
        iptables -A OUTPUT -s 172.16.45.21 -p tcp -m state --state RELATED -j ACCEPT

iptables规则的保存与重载

iptables-save > /PATH/TO/SOME_RULE_FILE
iptables-restore < /PATH/TO/SOME_RULE_FILE

iptables的修改正确步骤

1.在修改iptables规则之前,先备份原有规则
    iptables-save > /etc/sysconfit/iptables.bak
2.将要修改的规则写入脚本
    vim iptables.sh
3.添加计划任务,防止iptables的错误规则导致服务器无法访问
        at now +2 miniute
        at > /sbin/iptables-restore < /etc/sysconfig/iptables.bak
        at > <EOT>
4.运行修改规则脚本
    sh ./iptables.sh
5.如果新的规则无问题,则取消计划任务
    atrm N(N表示at队列号)
原文地址:https://www.cnblogs.com/marility/p/7448407.html