iptables
Linux:网络防火墙
netfilter: Frame
iptables: 数据报文过滤,NAT、mangle等规则生成的工具;
网络:IP报文首部,TCP报文首部
防火墙:硬件,软件: 规则(匹配标准,处理办法)
Framework:
默认规则:
开放:堵 开放需要的,堵住所有不需要的请求
关闭:通 关闭所有只开放符合标标准的
规则:匹配标准 S(源),D(目标)
IP: SIP, DIP
TCP: SPORT, DPORT,
SYN=1,FIN=0,RST=0,ACK=0; 第一次握手
SYN=1,ACK=1,FIN=0,RST=0; 第二次握手
ACK=1,SYN=0,RST=0,FIN=0(ESTABLISHED) 第三次握手
UDP: SPORT, DPORT
ICMP(控制消息协议):icmp-type 根据报文类型区别
数据报文过滤:
早期:参考OpenBSD
用特定的app调用内核功能,把用户空间的命令加到内核的指定位置。
Linux2.4
iptables/netfilter //iptables工作在用户空间调用内核的功能的APP规则生成
器。
// netfilter是内核空间上的一个存放规则的位置
数据流向有三种:
1.外部请求本机的报文
2.本机请求外部的报文,并非是回应外部报文
3.转发出去的报文
根据路由表,所有报文都是先进到本地TCP/IP协议栈,然后路由决策
hook function: 五个钩子函数,每个函数可以存放多条函数过滤
prerouting //到本机来还没有进行路由
input //到本机内部来
output //本机出去的
forward //本机转发的
postrouting //由本机在路由之后转发出去的
规则链: //每个钩子函数可以有多条规则,对应一个链,称为规则链。
PREROUTING
INPUT
FORWARD
OUTPUT
POSTROUTING
filter(过滤):表,一般可以放到一下三个位置
INPUT
OUTPUT
FORWARD
nat(地址转换):表,下面三个位置
PREROUTING
OUTPUT
POSTROUTING
mangle(对报文:拆开、修改、封装):表
PREROUTING
INPUT
FORWARD
OUTPUT
POSTROUTING
raw(原始格式):表
PREROUTING
OUTPUT
优先级 row>mangle>nat>filter
iptables:四表五链组成,iptables在每个表上的链上生成规则
使用自定义链可以提高效率
可以使用自定链,但只在被调用时才能发挥作用,而且如果没有自定义链中的任何规则匹 配,还应该有返回机制,跳转到原来的链;
用户可以删除自定义的空链
默认链无法删除
每个规则都有两个内置的计数器:
被匹配的报文个数
被匹配的报文大小之和
规则:匹配标准,处理动作
iptables [-t TABLE] COMMAND CHAIN [num] 匹配标准 -j 处理办法
匹配标准:
通用匹配
-s, --src: 指定源地址
-d, --dst:指定目标地址
-p {tcp|udp|icmp}:指定协议
-i INTERFACE: 指定数据报文流入的接口
可用于定义标准的链:PREROUTING,INPUT,FORWARD
-o INTERFACE: 指定数据报文流出的接口
可用于标准定义的链:OUTPUT,POSTROUTING,FORWARD
扩展匹配
隐含扩展:不用特别指明由哪个模块进行的扩展,因为此时使用-p {tcp|udp|
icmp}
显式扩展:必须指明由哪个模块进行的扩展,在iptables中使用-m选项可完成此
iptables -t filter -A INPUT -s 172.16.0.0/16 -d 172.16.100.7 -j DROP
netfilter: Framework, 内核中TCP/IP,框架
iptables [-t TABLE] COMMAND CHAIN [num] 匹配条件 -j 处理动作
匹配条件
通用匹配
-s //指定源地址
-d //指定目标地址
-p {tcp|udp|icmp} //指定匹配协议
-i //指定进入接口lo eth0 eth1...
-o //指定出去的网卡接口
扩展匹配
隐含扩展
-p tcp
--sport PORT[-PORT]: 源端口
--dport PORT[-PORT]: 目标端口
--tcp-flags mask comp: 只检查mask指定的标志位,是逗号分隔的标志位列表;comp:此列表中出现的标记位必须为1,comp中没出 现,而mask中出现的,必须为0;
--tcp-flags SYN,FIN,ACK,RST SYN = --syn
--syn
-p icmp
--icmp-type
0: echo-reply //回应别人ping为8,别人回应自己为0。
8: echo-request //ping 别人为8,别人ping自己进来的是8。
-p udp
--sport 源端口
--dport 目标端口
-p tcp --dport
-m EXTESTION --spe-opt
state: 状态扩展
结合ip_conntrack追踪会话的状态
NEW: 新连接请求
ESTABLISHED:已建立的连接
INVALID:非法连接
RELATED:相关联的
-m state --state NEW,ESTABLISHED -j ACCEPT
开放ftp /etc/sysconfig/iptables-config 首先要装载ip_conntrack_ftp和ip_nat_ftp模块 RHEL6为nf_conntrack_ftp
iptables -A INPUT -d 172.16.100.7 -p tcp -m state --state ESTABLISHED,RELATED -j ACCEPT //追踪ESTABLISHED,RELATED状态.RELATED是和报文相关联的。
multiport: 离散的多端口匹配扩展
--source-ports
--destination-ports
--ports
-m multiport --destination-ports 21,22,80 -j ACCEPT
-m iprange
--src-range //源地址范围
--dst-range //目标地址范围
-s, -d
-s IP, NET
范围为172.16.0.0/16, 172.16.100.3-172.16.100.100的地址访问本机22端口,放行
iptables -A INPUT -p tcp -m iprange --src-range172.16.100.3-172.16.100.100 --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
-m connlimit: 连接数限制
! --connlimit-above n // 取反,表示连接数小于n
访问本机80端口的连接数不能大于2个,否则会被拒绝
iptables -A INPUT -d 172.16.100.7 -p tcp --dport 80 -m connlimit --connlimit-above 2 -j ACCEPT
-m limit
--limit RATE 速率 5/minute
--limit-burst 上限,一批放行多少,
-m string
--algo {bm|kmp} 使用算法
--string "STRING" 匹配过滤指定字符串,可以是正则
条件取反:!,-s ! 172.16.100.6
处理动作
-j 动作(target):
ACCEPT:放行
DROP:丢弃
REJECT:拒绝
DNAT:目标地址转换
--to-destination ip 将目标地址转换为指定IP:port可以加端口
将访问21.22.22.22地址80端口的目标地址更换为192.168..136.135:8080端口 iptables -t nat -A PREROUTNG -d 21.22.22.22 -p tcp --dport 80 -j DNAT --to- destination 192.168..136.135:8080
SNAT:源地址转换
--to-source ip 将源地址转为指定ip
将访问外网的源地址更换为21.22.22.22
iptables -t nat -A POSTROUTING -s 192.168.1136.135 -j SNAT --to-source 21.22.22.22
REDIRECT:端口重定向
MASQUERADE:地址伪装
LOG:日志
MARK:打标记
LOG
--log-prefix "STRING" 在日志加前缀
命令:
管理规则
-A:附加一条规则,添加在链的尾部
-I CHAIN [num]: 插入一条规则,插入为对应CHAIN上的第num条;
-D CHAIN [num]: 删除指定链中的第num条规则;
-R CHAIN [num]: 替换指定的规则;
-F [CHAIN]:flush,清空指定规则链,如果省略CHAIN,则可以实现删除对应表中的所有链
-P CHAIN: 设定指定链的默认策略;
iptables -P INPUT DROP 修改IPUT链默认为DROP
-N:自定义一个新的空链
-X: 删除一个自定义的空链
-Z:置零指定链中所有规则的计数器;
-E: 重命名自定义的链;
查看命令:
-L: 显示指定表中的规则;
-n: 以数字格式显示主机地址和端口号;
-v: 显示链及规则的详细信息
-vv:
-x: 显示计数器的精确值
--line-numbers: 显示规则号码
iptables不是服务,但有服务脚本;服务脚本的主要作用在于管理保存的规则 装载及移除iptables/netfilter相关的内核模块;
iptables_nat, iptables_filter, iptables_mangle, iptables_raw, ip_nat,
ip_conntrack 这个模块一般对于高并发服务器一般不启用,否则超过连接数时用户无法建立正常连接。
iptables -t nat -L 查看nat表会激活追踪工能,繁忙服务器会造成链接丢失。
RHEL5 /proc/net/ip_conntrack 保留其他主机和当前主机连接信息
RHEL6 /proc/net/nf_conntrack
/proc/sys/net/ipv4/ip_conntrack_max 最多的链接个数,超过这个数会被丢弃
cat /proc/slabinfo
iptstate //追踪nf_conntrack/ip_conntrack的状态
ip_conntrack_tcp_timeout_established默认情况下 timeout 是5天(432000秒)
RHEL5目录:/proc/sys/net/ipv4/netfilter/
RHRL6目录 /proc/sys/net/netfilter
RHEL6目录 /proc/sys/net/netfilter/nf_conntrack_max 最大追踪连接数
sysctl -w net.netfilter.nf_conntrack_max=1000000
保存规则:
# service iptables save
/etc/sysconfig/iptables
# iptables-save > /etc/sysconfig/iptables.2013041801 自定义保存
# iptables-restore < /etc/sysconfig/iptables.2013041801 输入重定向,读取规则
练习:
iptables -t filter -A INPUT -s 192.168.136.0/24 -j DROP 192.168.136.0/24,sshd:22/tcp 放行本机的22端口 iptables -t filter -A INPUT -s 192.168.136.0/24 -d 192.168.136.135 -p tcp --dport 22 -j ACCEPT iptables -t filter -A OUTPUT -s 192.168.136.135 -d 192.168.136.0/24 -p tcp --sport 22 -j ACCEPT 修改本机默认规则,注意:修改默认规则前先放行自己 iptables -P INPUT DROP iptables -P OUTPUT DROP iptables -P FORWARD DROP 放行本机80端口,一位web服务请求的多所以-I插入到22端口上面,第一位 iptables -I INPUT 1 -d 192.168.136.135 -p tcp --dport 80 -j ACCEPT iptables -I OUTPUT 1 -s 192.168.136.135 -p tcp --sport 80 -j ACCEPT 允许自己ping别人 iptables -A OUTPUT -s 192.168.136.135 -p icmp --icmp-type 8 -j ACCEPT iptables -A INPUT -d 192.168.136.135 -p icmp --icmp-type 0 -j ACCEPT 放行新请求链接和已建立的链接和所有响应链接 iptables -A INPUT -d 192.168.136.135 -p tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT iptables -A OUTPUT -d 192.168.136.135 -p tcp -state --state ESTABLISHED 删除INPUT链中的第二条规则 iptables -D INPUT 2 放行本地请求本地通过lo接口的请求和响应 iptables -A INPUT -i lo -j ACCEPT iptables -A OUTPUT -o lo -j ACCEPT 开放FTP服务,因为数据传输是被动连接 放行本机FTP发送给客户端的随机i端口 iptables -A OUTPUT -s 192.168.136.135 -p tcp -m state --state ESTABLISHED,RELATED -j ACCEPT 本地接受客户端的关联的报文请求 iptables -A INPUT -d 192.168.136.135 -p tcp --dport 21 -m state --state NEW,ESTABLISHED -j ACCEPT 多条规则合并成二条 iptables -A INPUT -d 192.168.136.135 -p tcp -m state --state ESTABLISHED,RELATED -j ACCEPT iptables -A INPUT -d 192.168.136.135 -p tcp -m state --state NEW -m multiport -- destination-port 21,22,80 -j ACCEPT
练习:判断下述规则的意义:
# iptables -N clean_in //自定义一个名字为clean_in的新链 # iptables -A clean_in -d 255.255.255.255 -p icmp -j DROP //拒绝向255.255.255.255的广播 # iptables -A clean_in -d 172.16.255.255 -p icmp -j DROP //拒绝向172.16的广播 # iptables -A clean_in -p tcp ! --syn -m state --state NEW -j DROP //只接受新的syn请求 # iptables -A clean_in -p tcp --tcp-flags ALL ALL -j DROP //拒绝tcp标志位全为1的请求 # iptables -A clean_in -p tcp --tcp-flags ALL NONE -j DROP //拒绝标志位全为0的请求 # iptables -A clean_in -d 172.16.100.7 -j RETURN //定义连中返回链,指向完自定义链接返回到主链上 # iptables -A INPUT -d 172.16.100.7 -j clean_in //调用自定义链 # iptables -A INPUT -i lo -j ACCEPT //本机自己访问自己 # iptables -A OUTPUT -o lo -j ACCEPT # iptables -A INPUT -i eth0 -m multiport -p tcp --dports 53,113,135,137,139,445 -j DROP # iptables -A INPUT -i eth0 -m multiport -p udp --dports 53,113,135,137,139,445 -j DROP # iptables -A INPUT -i eth0 -p udp --dport 1026 -j DROP # iptables -A INPUT -i eth0 -m multiport -p tcp --dports 1433,4899 -j DROP # iptables -A INPUT -p icmp -m limit --limit 10/second -j ACCEPT
利用iptables的recent模块来抵御DOS攻击
ssh: 远程连接, iptables -I INPUT -p tcp --dport 22 -m connlimit --connlimit-above 3 -j DROP iptables -I INPUT -p tcp --dport 22 -m state --state NEW -m recent --set --name SSH iptables -I INPUT -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 300 --hitcount 3 --name SSH -j DROP 1.利用connlimit模块将单IP的并发设置为3;会误杀使用NAT上网的用户,可以根据实际情况增大该值; 2.利用recent和state模块限制单IP在300s内只能与本机建立3个新连接。被限制五分钟后即可恢复访问。 下面对最后两句做一个说明: 1.第二句是记录访问tcp 22端口的新连接,记录名称为SSH--set 记录数据包的来源IP,如果IP已经存在将更新已经存在的条目 2.第三句是指SSH记录中的IP,300s内发起超过3次连接则拒绝此IP的连接。 --update 是指每次建立连接都更新列表; --seconds必须与--rcheck或者--update同时使用 --hitcount必须与--rcheck或者--update同时使用 3.iptables的记录:/proc/net/ipt_recent/SSH 也可以使用下面的这句记录日志: iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --update --name SSH --second 300 --hitcount 3 -j LOG --log-prefix "SSH Attack"
layer7 -- l7
应用:xunlei, qq, netfilter<--patch
-m layer7 --l7proto xunlei -j DROP
1、给内核打补丁,并重新编译内核
2、给iptables源码打补丁,并重新编译iptables
3、安装l7proto
kernel, patch
iptables, patch
Kernel Patch
# tar zxvf linux-2.6.28.10.tar.gz -C /usr/src
# tar zxvf netfilter-layer7-v2.22.tar.gz -C /usr/src
# cd /usr/src
# ln –s linux-2.6.28.10 linux
# cd /usr/src/linux/
# patch -p1 < ../netfilter-layer7-v2.22/kernel-2.6.25-2.6.28-layer7-2.22.patch
# cp /boot/config-2.6.18-164.el5 /usr/src/linux/.config
# make menuconfig
Networking support → Networking Options →Network packet filtering framework →Core
Netfilter Configuration
<M> Netfilter connection tracking support
<M> “layer7” match support
<M> “string” match support
<M> “time” match support
<M> “iprange” match support
<M> “connlimit” match support
<M> “state” match support
<M> “conntrack” connection match support
<M> “mac” address match support
<M> "multiport" Multiple port match support
Networking support → Networking Options →Network packet filtering framework → IP:
Netfilter Configuration
<M> IPv4 connection tracking support (required for NAT)
<M> Full NAT
<M> MASQUERADE target support
<M> NETMAP target support
<M> REDIRECT target support
# make
# make modules_install
# make install
Compiles iptables :
# cp /etc/init.d/iptables ~/iptables
# cp /etc/sysconfig/iptables-config ~/
# rpm -e iptables-ipv6 iptables iptstate --nodeps
# tar jxvf iptables-1.4.6.tar.bz2 –C /usr/src
# cd /usr/src/iptables-1.4.6
# cp ../netfilter-layer7-v2.22/iptables-1.4.3forward-for-kernel-
2.6.20forward/libxt_layer7.* ./extensions/
# ./configure --prefix=/usr --with-ksource=/usr/src/linux
# make
# make install
# tar zxvf l7-protocols-2009-05-28.tar.gz
# cd l7-protocols-2009-05-28
# make install
# mv ~/iptables /etc/rc.d/init.d/
# service iptables start
l7-filter uses the standard iptables extension syntax
# iptables [specify table & chain] -m layer7 --l7proto [protocol name] -j [action]
-m time
--timestart --timestop
iptables -A FORWARD -s 192.168.136.0/24 -m time --timestart 08:30:00 --
timestop 12:00:00 -j DROP
iptables -A FORWARD -s 192.168.136.0/24 -m time --timestart 13:00:00 --
timestop 18:00:00 -j DROP
自定义iptables脚本,开机启动可以放到/etc/rc.d/rc.local里面执行。
#!/bin/bash
ipt=/usr/sbin/iptables
einterface=eth1
iinterface=eth0
eip=192.168.136.135
iip=192.168.136.135
$ipt -t nat -F
$ipt -t filter -F
$ipt -t mangle -F
$ipt -N clean_up