1、常用的数据报文格式的解释
1)IP报文的格式
2)TCP报文的格式
2、netfilter的原理
1)每个表的作用
2)每个链(chain)或钩子的意义
3)表和链的对应关系
4)表的优先级
5)数据报文流程:
-
进入:PREROUTING, INPUT
-
出去:OUTPUT, POSTROUTING
-
PREROUTING, FORWARD, POSTROUTING
二、iptables工具的使用
1、iptables命令的选项说明
基本语法:
选项 | 意义 |
-t | 指明处理的表名,默认是filter |
-A|-D|-I|R | 增加、删除、插入、替换匹配的规则,后面是对应要处理的链名 |
-F | 刷新规则库 |
-Z | 清空计数器 |
-N|-X|-E | 自己 创建、删除、重命名一个链 |
-P | 设置默认策略,经常用来设置黑名单、白名单 |
-L | 列出对应表的防火墙规则,可以使用以下子选项 -n 以数字形式显示ip地址和端口号 -v -vv -vvv 显示信息的详细程度 -x 精确显示匹配到的包数和包的字节数 –line-numbers 列出每个规则的序列号 –modprobe=command 可以通过这个加载必要的模块 |
匹配条件的说明:
-s | 指明报文的源地址 |
-d | 指明报文的目的地址 |
-p | 指明报文的协议 |
-i | 指明报文的进入的网卡,与INPUT链一起使用 |
-o | 指明报文出去的网卡,与OUTPUT一起使用 |
–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 |
–src-range | 指明源地址的范围 用法:–src-range from[-to] 例如:–src-range 192.168.1.1-192.168.1.24 |
–dst-range | 指明目标地址的范围,用法同–src-range相同 |
–sports | 指明多个源端口 例如:–sports 21,22,80,53 |
–dports | 指明多个目标端口 |
–ports | 指明多个端口,这些端口包括源端口和目标端口 |
–connlimit-above | 同一客户端的连接并发数 |
–connlimit-msak | 指明客户端的有掩码位数(prefix length) |
–limit-rate | 限制传输速率的的 用法:–limit rate[/second|/minute|/hour|/day] |
–limit-brust | brust是令牌桶,里面存放的是令牌的个数。简单的来说,客户端只用得带令牌才可以传输数据,此令牌数会累加 |
–algo | 指明匹配字符串的加密类型 kmp和bm(根据人名命名的) |
–string | 指明匹配的字符串 |
–hex-string | 匹配的字符串使用十六进制形式给出 |
–from | 指明匹配字符串的开始处,默认是0 |
–to | 指明匹配字符串的结束处,默认是65535 |
–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 | 指明连接状态,状态有: NEW:新建立的连接 ESTABLISHED: 已建立的连接 RELATED: 关联的连接 INVILID:表示无效的状态 |
–set | 将地址添加到地址列表中,包含地址的时间戳 |
–name | 指定地址列表的名字,默认是DEFAULT |
–rsource –rdest | 指明当前的规则是应用到数据包的源地址还是目标地址,默认是源地址 |
–rcheck | 检查地址是否在地址列表中 |
–remove | 删除地址列表中的 |
–update | 和rcheck作用一样,但他会刷新时间戳 |
–hitcount | 指定时间内的命中数(在地址列表中匹配的次数) 必须与-rcheck和–update同时使用 |
–seconds | 用法:–seconds n 限制数据包里的地址记录到地址列表里的时间要小于n 必须与-rcheck和–update同时使用 |
目标:
-
DROP,ACCEPT,REJECT常用与过滤数据包
-
DNAT,SNAT,MASQUERADE用在地址转换的模块
-
RETRUN:是跳转,通常用在自定义的链上,在自义链中无法匹配报文时,将其返回主链
-
LOG:是定义日志功能的
2、iptables示例
示例一:
# 设置防火墙规则机器的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
示例二、FORWARD示例
# 设置转发策略,放行请求和响应的报文,但是每次这样转发效率就不是很高了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
示例三、NAT表的示例
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 -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并发请求
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
示例五、layer7模块的使用
一、打补丁工具介绍
二、向内核打补丁
#1、获取并编译内核
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
#2、给内核打补丁
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
#3、编译并安装内核
make
make
modules_install
make
install
# 4、重启系统,启用新内核
三、向iptables打补丁
# 1、获取iptables源码的rpm包
rpm -ivh
/root/iptables-1
.4.7-11.el6.src.rpm
tar
xf
/root/rpmbuild/SOURCES/iptables-1
.4.7.
tar
.bz2
# 2、向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/*
# 3、修改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
# 4、重新制作rpm包
rpmbuild -ba
/root/rpmbuild/SPECS/iptables
.spec
# 5、升级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
# 6、确认iptables打补丁成功,成功后会出现libxt_layer7.so的模块
rpm -ql iptables |
grep
"layer"
/lib64/xtables/libxt_layer7
.so
四、导入应用层协议特征码
tar
zxvf l7-protocols-2009-05-28.
tar
.gz
cd
l7-protocols-2009-05-28
make
install
五、加载模块启用iptables的layer7模块
# 1、加载内核模块
modprobe nf_conntrack
modprobe xt_layer7
# 2、修改内核参数,此参数需要装载nf_conntrack模块后方能生效。
net.netfilter.nf_conntrack_acct = 1
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
3、raw表
# vi /etc/sysctl.conf
net.ipv4.ip_conntrack_max = 393216
net.ipv4.netfilter.ip_conntrack_max = 393216
#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