iptables原理知识

1、iptables的原理

iptables其实是定义防火墙规则的工具,真正对数据报文处理的是内核中的netfilter模块。netfilter对报文的处理方式通常有:过滤,地址转换,链接追踪linux

一、经常使用的数据报文格式的解释

防火墙其实是对进出本机的各类报文进行控制,因此了解常见报文的结构(格式)能够精确的控制报文。web

1)IP报文的格式

ip报文的结构以下图:vim

1

在这里与防火墙关系最大的是源地址、目标地址、协议。源地址指明报文的来源,目标地址说明报文的去处,协议指明传输层所使用的协议。安全

补充:bash

ip报文在互联网中传输的时候,要通过各类各样的网络设备,可是这些网络设备的MTU(通常为1500字节),因此ip报文在传输过程当中须要进行分段,每段都有一个分段标识。在目标地址的主机接收到,这些报文后,须要进行组装,此时就须要靠段偏移来实现。有时候,在网络中可能会造成回环现象,为了不诸如此类现象的发生,TTL(time-to-live)帮咱们解决这个问题,ip报文每通过一个网络设备,其值会减小1。若是值为0,咱们就认为网络不可达。服务器

2)TCP报文的格式

2

这里咱们使常关注的是:网络

源地址端口:源地址进程的端口号并发

目标地址端口:目标地址进程对应的端口号ssh

FIN: 结束标识符,tcp断开链接时,此标志位为1tcp

SYN: 请求标志符,客户端发起请求时,用于标识三次握手

ACK: 序列确认号,创建链接后,此标志位是1。ACK=0,FIN=1一般用来肯定是第一次”握手”

补充:

RST:重置标识,从新创建链接的时候会用到

PSH: 此标志位为1时,代表在接受端不缓冲,直接处理

URG: 来讲明紧急指针是否有效

窗口大小:目的告诉接收方在未收到“我”的确认时,接收方能够容许发送的数据的最大字节数

二、netfilter的原理

原理以下图所示:

3

Netfilte在内核中使用5个钩子(Hook)函数来实现,对应netfilter的5个链,它们分别是PREROUTING,INPUT,FORWARD,OUTPUT,POSTROUTING。对报文作出的动做有4张表raw,mangle,nat,filter来实现。

1)每一个表的做用

raw:目标是关闭nat表的链接追踪功能;

mangle:自定义功能。

nat:实现地址转换(SNAT,DNAT),启用链接追踪(connection_track)

filter: 实现数据包的过滤功能

2)每一个链(chain)或钩子的意义

PREROUTING:路由前,数据包最早到达的链      
INPUT:到达本机内部的报文必经之路      
FORWARD:由本机转发的报文必经之路      
OUTPUT:由本机发出的报文的必经之路      
POSTROUTING:路由后,报文出本机的最后一个链

3)表和链的对应关系

filter: INPUT, FORWARD, OUTPUT

nat: PREROUTING(DNAT),POSTROUTING(SNAT),OUTPUT(SNAT)

mangle: PREROUTING, INPUT, FORWARD, OUTPUT, POSTROUTING

raw: PREROUTING, OUTPUT

4)表的优先级

优先级从高到底的是:raw,mangle,nat,filter

5)数据报文流程:

跟本机内部进程通讯:

  • 进入:PREROUTING, INPUT

  • 出去:OUTPUT, POSTROUTING

由本机转发:

  • PREROUTING, FORWARD, POSTROUTING

2、iptables工具的使用

启动脚本:/etc/init.d/iptables {start|stop|restart|save}

save是将写好的规则保存到/etc/sysconfig/iptables,下次启动时会去读取此文件中的规则。也可以使用iptables-save重定向到某个文件中,下次可使用iptables-restore命令来导入规则。

一、iptables命令的选项说明

基本语法:

iptables [-t TABLE] COMMAND CHAIN  [RULE] [-j TARGET]

选项 意义
-t 指明处理的表名,默认是filter
-A|-D|-I|R 增长、删除、插入、替换匹配的规则,后面是对应要处理的链名
  -F 刷新规则库
-Z 清空计数器
-N|-X|-E 本身 建立、删除、重命名一个链
-P 设置默认策略,常常用来设置黑名单、白名单
-L 列出对应表的防火墙规则,可使用如下子选项          
-n 以数字形式显示ip地址和端口号          
-v -vv -vvv 显示信息的详细程度          
-x 精确显示匹配到的包数和包的字节数          
--line-numbers 列出每一个规则的序列号          
--modprobe=command 能够经过这个加载必要的模块

匹配条件的说明:

说明,如下每一个选项前面均可以加 ! 来取反

1)通用的匹配条件

-s 指明报文的源地址
-d 指明报文的目的地址
-p 指明报文的协议
-i 指明报文的进入的网卡,与INPUT链一块儿使用
-o 指明报文出去的网卡,与OUTPUT一块儿使用

2)扩展匹配

扩展匹配有隐式扩展和显式扩展,隐式扩展是 -p 指定协议的补充说明,显式扩展是用 -m 来指定特定的其余扩展选项。

常见的隐式扩展以下:

tcp协议的扩展选项:

--sport 指定源端口,udp协议也一样适用
--dport 指定目标端口,udp协议也一样适用
--tcp-flags 指明tcp报文中的状态时,格式:--tcp-flags mask(要检查的状态值) comp(为1的状态值)          
能够设置的状态值有SYN ACK FIN RST URG PSH ,ALL表示全部的状态,NONE表示全部没有设定          
例如:--tcp-flags ALL ALL 检查全部状态都为1          
      --tcp-flags ALL NONE 检查全部状态都为0
--syn 只检查SYN状态标志位为1

icmp协议的常见扩展:

icmp-type:icmp报文的类型,常见的有0和8,0表明响应报文,8表明请求报文。

常见的显式扩展以下:

iprange:指明ip范围的

--src-range 指明源地址的范围          
用法:--src-range from[-to] 例如:--src-range 192.168.1.1-192.168.1.24
--dst-range 指明目标地址的范围,用法同--src-range相同

multiport:指明多端口,只能用于tcp和udp协议

--sports 指明多个源端口          
例如:--sports 21,22,80,53
--dports 指明多个目标端口
--ports 指明多个端口,这些端口包括源端口和目标端口

connlimit:限定链接的并发数

--connlimit-above 同一客户端的链接并发数
--connlimit-msak 指明客户端的有掩码位数(prefix length)

limit:限制传输速率的

--limit-rate 限制传输速率的的          
用法:--limit rate[/second|/minute|/hour|/day]
--limit-brust brust是令牌桶,里面存放的是令牌的个数。简单的来讲,客户端只用得带令牌才能够传输数据,此令牌数会累加

string:过滤字符串的

--algo 指明匹配字符串的加密类型 kmp和bm(根据人名命名的)
--string 指明匹配的字符串
--hex-string 匹配的字符串使用十六进制形式给出
--from 指明匹配字符串的开始处,默认是0
--to 指明匹配字符串的结束处,默认是65535

time:限定时间和日期

--datestart 起始日期,格式:YYYY[-MM[-DD[Thh[:mm[:ss]]]]]
--datestop 截止日期,格式同上
--timestart 起始时间,格式是:hh:mm[:ss]
--timestop 截止时间,格式同上
--weekdays 指定星期数:Mon, Tue, Wed, Thu, Fri, Sat,Sun 也可使用1-7
--monthdays day 指明一个月中的特定天数,1-31均可以使用

state:指明链接的状态

--state 指明链接状态,状态有:          
NEW:新创建的链接          
ESTABLISHED: 已创建的链接          
RELATED: 关联的链接          
INVILID:表示无效的状态

recent: 阻挡大量的请求,例如能够防止DOS的***

在内核里面维护了地址列表,这个列表能够经过--set, --rcheck, --update and --remove四种方法来修改列表。--set, --rcheck, --update and --remove 是相互排斥的,不可同时使用。recent模块个规则有返回值(布尔值),为真会执行 -j 指定的动做。

--set 将地址添加到地址列表中,包含地址的时间戳
--name 指定地址列表的名字,默认是DEFAULT
--rsource --rdest 指明当前的规则是应用到数据包的源地址仍是目标地址,默认是源地址
--rcheck 检查地址是否在地址列表中
--remove 删除地址列表中的
--update 和rcheck做用同样,但他会刷新时间戳
--hitcount 指定时间内的命中数(在地址列表中匹配的次数)          
必须与-rcheck和--update同时使用
--seconds 用法:--seconds n          
限制数据包里的地址记录到地址列表里的时间要小于n          
必须与-rcheck和--update同时使用

layre7:从应用层来协议来控制,不过CentOS6.5的内核不支持,此时咱们须要向内核打补丁,这一块会在下面详细的介绍。

目标:

通常有-j选项指定,常见的有:

DROP,ACCEPT,REJECT,DNAT,SNAT,MASQUERADE,RETRUN,MARK,LOG

  • DROP,ACCEPT,REJECT经常使用与过滤数据包

  • DNAT,SNAT,MASQUERADE用在地址转换的模块

DNAT常与--to-destination一块儿使用,指明目标地址转换的地址

SNAT常与--to-source一块儿使用,指明目标地址转换的地址,但有时这个地址是动态获取的,因此就要借助于MASQUERADE来动态指明要转换的地址

  • RETRUN:是跳转,一般用在自定义的链上,在自义链中没法匹配报文时,将其返回主链

  • LOG:是定义日志功能的

常见的选项有 --log-prefix (用于在日志信息中标注信息) --log-level(用于指明日志的级别)

二、iptables示例

示例一:

INPUT和OUTPUT默认策略为DROP,要求:

    一、限制本地主机的web服务器在周一不容许访问;新请求的速率不能超过100个每秒;web服务器包含了admin字符串的页面不容许访问;web服务器仅容许响应报文离开本机;

    二、在工做时间,即周一到周五的8:30-18:00,开放本机的ftp服务给172.168.1.0  网络中的主机访问;数据下载请求的次数每分钟不得超过5个;

    三、开放本机的ssh服务给192.168.1.1-192.168.1.100中主机,新请求创建的速率一分钟不得超过2个;仅容许响应报文经过其服务端口离开本机;

    四、拒绝TCP标志位所有为1及所有为0的报文访问本机;

    五、容许本机ping别的主机;但不开放别的主机ping本机;

# 设置防火墙规则机器的ip地址是192.168.1.99
iptables -A INPUT -p tcp --dport 80 -m time ! --weekdays Mon -m string \
--algo kmp ! --string "admin" -m limit --limit 100/second -j ACCEPT

# ftp运行依赖于nf_conntrack_ftp 模块,因此须要加载此模块。
#在CerntOS中也能够编辑/etc/sysconfig/iptables-config配置文件中的IPTABLES_MODULES选项修改

iptables -A INPUT -p tcp --dport 21 -m time --weekdays 1,2,3,4,5 --start-time 08:30 \
--stop-time 18:00 -m limit --climit-rate 5/minute \
--modprobe="modprobe nf_conntrack_ftp" -j ACCEPT 
iptables -A INPUT -p tcp --dport 22 -m iprange \
--src-range 192.168.1.1-192.168.10.100 -m limit --limit-rate 2/minute -j ACCEPT

iptables -A INPUT -p tcp --tcp-flags ALL ALL -j DROP
iptables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP

# 把这条规则放入到INPUT链的第一条,对于已创建的链接直接放行,提升效率。
# RELATED是相关联的状态。例如ftp的被动链接
iptables -I INPUT 1 -m state --state ESTABLISED,RELATED -j ACCEPT

iptables -A OUTPUT -s 192.168.1.99 -p icmp --icmp-type 8 -j ACCEPT 

iptables -P INPUT DROP
iptables -P OUTPUT DROP

# 对于各类响应报文,只要是能进入的数据包,而且是已创建或者相关联的链接都予以放行
iptables -I OUTPUT 1 -m state --state ESTABLISED,RELATED -j ACCEPT

另外一种设置的方法:(使用自定义链)

iptables -N httpd_in

iptables -A httpd_in  -m time ! --weekdays Mon -m string --algo kmp \
 ! --string "admin" -m limit --limit 100/second -j ACCEPT
iptables -A httpd_in -j RETURN 

iptables -N ftp_in

iptables -A INPUT  -m time --weekdays 1,2,3,4,5 --start-time 08:30 \
--stop-time 18:00 -m limit --climit-rate 5/minute \
--modprobe="modprobe nf_conntrack_ftp" -j ACCEPT 

iptables -A ftp_in -j RETURN 

iptables -N ssh_in

iptables -A ssh_in -m iprange --src-range 192.168.1.1-192.168.10.100 \
-m limit --limit-rate 2/minute -j ACCEPT
 
iptables -A ftp_in -j RETURN 

iptables -A INPUT -p tcp --dport 80 -d 192.168.1.99 -j httpd_in
iptables -A INPUT -p tcp --dport 21 -d 192.168.1.99 -j ftp_in
iptables -A INPUT -p tcp --dport 22 -d 192.168.1.99  -j ssh_in 

iptables -A INPUT -d 192.168.1.99 -p icmp --icmp-type 8 -j DROP
iptables -A INPUT -p tcp --tcp-flags ALL ALL -j DROP
iptables -A INPUT -p tcp --tcp-flags ALL NONE. -j DROP
iptables -I INPUT -m state ESTABLISHED,RELEATED -j ACCEPT

iptables -P INPUT DROP
iptables -P OUTPUT DROP

iptables -I OUTPUT 1 -m state --state ESTABLISED,RELATED -j ACCEPT

示例2、FORWARD示例

情形以下:172.16.10.22经过192.168.1.99这台主机做为转发访问192.168.1.77的资源。

4 

前提:192.168.1.99主机必须打开路由转发功能,即内核参数net.ipv4.ip_forward=1

防火墙规则以下:

# 设置转发策略,放行请求和响应的报文,可是每次这样转发效率就不是很高了
## iptables -A FORWARD -d 192.168.1.77 -p tcp --dport 80 -j ACCEPT

iptables -A FORWARD -s 192.168.1.77 -p tcp --sport 80 -j ACCEPT
iptables -P FOREARD DROP

# 优化策略以下,实现状态匹配。但此种模式,要开启链接追踪的功能,很大程度上会消耗防火墙资源
iptables -I FORWARD 1 ESTABLISHED -j ACCEPT
iptables -A FORWARD -s 192.168.1.77 -p tcp --sport 80 -m state --state NEW -j ACCEPT
iptables -P FOREARD DROP

示例3、NAT表的示例

NAT实现网络地址转换,早期是为了安全角度设置的,如今也可使用节约ip资源,实现内网共享地址上网。常见的地址转换有:SNAT 源地址转换,DANT 目的地址转换,PNAT 端口转换(一般原DNAT有关),FNAT (在虚拟局域网中会用到)源地址和目标地址转换。

SNAT:在内网报文离开网络防火墙以前,作源地址转换。在外网接收到报文请求后,会先将报文发送到网络防火墙处,网络防火墙出会进行目标地址转换,转换到请求的内网主机。可是,这一步骤是由网络防火墙中本身维护的地址映射表来完成的,不须要咱们参与。

8

前提:(在网络防火墙处)

有路由功能:net.ipv4.ip_forward=1

FORWARD默认策略是DROP

在网络防火墙处配置策略:

iptables -I FORWARD 1 -m state --state ESTABLISHED -j ACCEPT
iptables -A FORWARD  -s 192.168.1.77 -p tcp --dport 80 -m state \
--state NEW -j ACCEPT

# 若是SNAT时,地址是不肯定的,可使用MASQUERADE
iptables -t nat -A POSTROUTING -s 192.168.1.77 -p tcp --sport 80 \
-j SNAT --to-source 172.16.10.16

DNAT:我想访问内网中的web服务,在么办?内网地址但是不能在公网上路由。因此,此时就须要DNAT转换,直接请求172.16.10.16(在这里模拟的是公网地址),由它转换给内网主机。

 

9

前提:(在网络防火墙处)

有路由功能:net.ipv4.ip_forward=1

FORWARD默认策略是DROP

在网络防火墙处配置策略:

iptables -I FORWARD 1 -m state --state ESTABLISHED -j ACCEPT
iptables -A FORWARD  -d 192.168.1.77 -p tcp --dport 80 -m state --state NEW -j ACCEPT

# 此时还能够作端口转换PNAT,真正的web服务是192.168.1.77:8080端口上
iptables -t nat -A PREROUTING -d 172.16.10.16  -p tcp --dport 80 -j SNAT \
--to-source 192.168.1.77:8080

示例四:利用iptables的recent模块来抵御DOS***

限制一分钟以内同一客户端的ip访问http协议请求最多10次

# 设置每一个IP的最大http并发请求
iptables -I INPUT -p tcp --dport 80 -m connlimit --connlimit-above 10 -j DROP
 
# 对于刚刚创建的请求时,记录到HTTP的地址列表中,在/proc/net/xt_recent/HTTP
iptables -A INPUT  -p tcp --dport 80 -m state --state NEW -m recent --set --name HTTP

# 同一源地址在一分钟以内请求到达11次时,会对它进行LOG记录
iptables -A INPUT  -p tcp --dport 80 -m state --state NEW -m recent --update \
--seconds 60 --hitcount 11 --name HHTP -j LOG --log-prefix "HHTP Attach: "

# 同一源地址在一分钟以内请求到达11次时,会将其拒绝
iptables -A INPUT  -p tcp --dport 80 -m state --state NEW -m recent --update \
--seconds 60 --hitcount 11 --name SSH -j DROP

示例5、layer7模块的使用

layer7是能够识别应用层协议的模块,可是CentOS6.5的内核是不支持这个模块的,此时要对内核打补丁,从新编译内核。对iptables打补丁,支持layer7模块,从新编译iptables。

1、打补丁工具介绍

diff:

diff是Unix系统的一个很重要的工具程序。它用来比较两个文本文件的差别,是代码版本管理的核心工具之一。其用法很是简单:
# diff <变更前的文件> <变更后的文件>

patch:

尽管并无指定patch和diff的关系,但一般patch都使用diff的结果来完成打补丁的工做,这和patch自己支持多种diff输出文件格式有很大关系。patch经过读入patch命令文件(能够从标准输入),对目标文件进行修改。一般先用diff命令比较新老版本,patch命令文件则采用diff的输出文件,从而保持原版本与新版本一致。

patch的标准格式为:
patch [options] [originalfile] [patchfile]

常使用的选项:

-p参数决定了是否使用读出的源文件名的前缀目录信息,不提供-p参数,则忽略全部目录信息,-p0(或者-p 0)表示使用所有的路径信息,-p1将忽略第一个"/"之前的目录,依此类推。如/usr/src/linux-2.4.15/Makefile这样的文件名,在提供-p3参数时将使用linux-2.4.15/Makefile做为所要patch的文件。

-R 相逆补丁,降级

2、向内核打补丁

下载real的源码格式的rpm,下载地址http://ftp.redhat.com/pub/redhat/linux/enterprise/6Server/en/os/SRPMS/

具体步骤:

#一、获取并编译内核
useradd mockbuild
rpm -ivh kernel-2.6.32-431.5.1.x86_64.el6.src.rpm
tar -xf rpmbuild/SOURCES/linux-2.6.32-431.11.2.el6.tar.bz2 -C /usr/src/cd /usr/src
cd /usr/src/
ln -sv linux-2.6.32-431.11.2.el6 linux 

#二、给内核打补丁
tar xf netfilter-layer7-v2.23.tar.bz2 -C /usr/src
cd /usr/src/linux
patch -p1 < ../netfilter-layer7-v2.23/kernel-2.6.32-layer7-2.23.patch
cp /boot/config-*  .config
# 先肯定安装 ncurses 包
make menuconfig

按以下步骤启用layer7模块		
Networking support → Networking Options →Network packet filtering framework\
 → Core Netfilter Configuration
 
<M>  “layer7” match support
关闭内核签名功能:
Enable loadable modules support -> [ ] Module signature verification 
Cryptographic API -> [ ] In-kernel signature checker
#三、编译并安装内核
make
make modules_install
make install

# 四、重启系统,启用新内核

3、向iptables打补丁

具体步骤:

# 一、获取iptables源码的rpm包
rpm -ivh /root/iptables-1.4.7-11.el6.src.rpm 
tar xf /root/rpmbuild/SOURCES/iptables-1.4.7.tar.bz2 

# 二、向iptables打补丁
cd /root/rpmbuild/SOURCES/iptables-1.4.7
cp /root/netfilter-layer7-v2.23/iptables-1.4.3forward-for-kernel-2.6.20forward/* ./extensions/
rm -rf iptables-1.4.7.tar.bz2 
tar jcf iptables-1.4.7.tar.bz2 iptables-1.4.7/*

# 三、修改rpm包的spec文件的下面内容
# vim /root/rpmbuild/SPECS/iptables.spec
Release: 12%{?dist}
./configure --enable-devel --enable-libipq --bindir=/bin --sbindir=/sbin --sysconfdir=/etc --libdir=/%{_lib} --libexecdir=/%{_lib} --mandir=%{_mandir} --includedir=

%{_includedir}  --with-ksource=/usr/src/linux

# 四、从新制做rpm包
rpmbuild -ba /root/rpmbuild/SPECS/iptables.spec

# 五、升级iptables源码包
rpm -Uvh /root/rpmbuild/RPMS/x86_64/iptables-1.4.7-12.el6.x86_64.rpm /root/rpmbuild/RPMS/x86_64/iptables-ipv6-1.4.7-12.el6.x86_64.rpm  

# 六、确认iptables打补丁成功,成功后会出现libxt_layer7.so的模块
rpm -ql iptables | grep "layer"
/lib64/xtables/libxt_layer7.so

4、导入应用层协议特征码

具体步骤:

tar zxvf l7-protocols-2009-05-28.tar.gz
cd l7-protocols-2009-05-28
make install

5、加载模块启用iptables的layer7模块

# 一、加载内核模块
modprobe nf_conntrack
modprobe xt_layer7

# 二、修改内核参数,此参数须要装载nf_conntrack模块后方能生效。
net.netfilter.nf_conntrack_acct = 1

 

至此,layer7模块就可使用了。

用法以下:

iptables [specify table & chain] -m layer7 --l7proto [protocol name] -j [action]

例如:iptables -A FORWARD -m layer7 --l7proto qq -j REJECT # 在应用层放行qq协议的数据包

实验拓扑图:实现内网主机上网功能,可是不容许qq,xunlei协议的数据包。

11

前提:(在网络防火墙处)

有路由功能:net.ipv4.ip_forward=1

FORWARD默认策略是ACCEPT

在网络防火墙处配置策略:

iptables -A FORWARD -m layer7 --l7proto qq,xunlei -j REJECT 
iptables -t nat -A POSTROUTING -s 192.168.1.77 -j SNAT --to-source 172.16.10.16

三、raw表

RAW表只使用在PREROUTING链和OUTPUT链上,由于优先级最高,从而能够对收到的数据包在链接跟踪前进行处理。一但用户使用了RAW表,在某个链上,RAW表处理完后,将跳过NAT表和 ip_conntrack处理,即再也不作地址转换和数据包的连接跟踪处理了。

RAW表能够应用在那些不须要作nat的状况下,以提升性能。如大量访问的web服务器,可让80端口再也不让iptables作数据包的连接跟踪处理,以提升用户的访问速度。

实际测试发现filter链仍然处理一些NOTRACK的包,但没有进行connect tracking,因此filter链条里必须将UNTRACKED状态的包放行

iptables的连接跟踪表最大容量为/proc/sys/net/ipv4/ip_conntrack_max,连接碰到各类状态的超时后就会从表中删除。

因此解決方法通常有两个:

(1) 加大 ip_conntrack_max 值

# vi /etc/sysctl.conf
net.ipv4.ip_conntrack_max = 393216
net.ipv4.netfilter.ip_conntrack_max = 393216

(2): 下降 ip_conntrack timeout时间

#vi /etc/sysctl.conf
net.ipv4.netfilter.ip_conntrack_tcp_timeout_established = 300
net.ipv4.netfilter.ip_conntrack_tcp_timeout_time_wait = 120
net.ipv4.netfilter.ip_conntrack_tcp_timeout_close_wait = 60
net.ipv4.netfilter.ip_conntrack_tcp_timeout_fin_wait = 120

至此,iptables的基础配置介绍完毕。

相关文章
相关标签/搜索